1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
/**
Liquid Container
Basic interface for anything that can contain liquids.
@author Marky
*/
public func IsLiquidContainer() { return true; }
public func GetLiquidContainerMaxFillLevel(liquid_name)
{
return 0;
}
public func IsLiquidContainerForMaterial(string liquid_name)
{
return true;
}
public func GetLiquidAmount(liquid_name)
{
var amount = 0;
var type = nil;
// In case that a value was supplied, try finding the type for that.
if (liquid_name != nil)
{
type = GetLiquidDef(liquid_name);
if (type == nil)
FatalError(Format("GetLiquidAmount(%s): No such liquid.", liquid_name));
}
// Return everything if 'nil' was passed, or a specific amount if a value was passed.
for (var liquid in GetLiquidContents())
{
if (liquid_name == nil || liquid->GetLiquidType() == type->GetLiquidType())
amount += liquid->~GetLiquidAmount();
}
return amount;
}
public func GetLiquidAmountRemaining(liquid_name)
{
return GetLiquidContainerMaxFillLevel(liquid_name) - GetLiquidAmount(liquid_name);
}
public func GetLiquidContents()
{
return FindObjects(Find_Container(this), Find_Func("IsLiquid"));
}
/*-- Interaction --*/
// Returns whether this container has any of the requested liquid and returns that liquid.
// If liquids == nil it returns the first liquid found.
public func HasLiquid(array liquids)
{
for (var liquid in GetLiquidContents())
{
if (liquids != nil)
{
if (IsValueInArray(liquids, liquid->GetID()))
return liquid;
}
else
return liquid;
}
return nil;
}
/**
Extracts liquid from the container.
@param liquid_name: Material to extract; Wildcardsupport
Defaults to the current liquid if 'nil' is passed.
@param amount: Max Amount of liquid being extracted;
Defaults to all contained liquid if 'nil' is passed.
@param destination: Object that extracts the liquid
@return [returned_liquid, returned_amount]
- returned_liquid: Material being extracted
- returned_amount: Amount being extracted
*/
public func RemoveLiquid(liquid_name, int amount, object destination)
{
if (amount < 0)
{
FatalError(Format("You can remove positive amounts of liquid only, got %d", amount));
}
amount = amount ?? GetLiquidAmount();
var removed = 0;
for (var liquid in GetLiquidContents())
{
if (removed >= amount) break;
if (!liquid_name) liquid_name = liquid->GetLiquidType();
removed += liquid->RemoveLiquid(liquid_name, amount - removed, destination)[1];
}
return [liquid_name, removed];
}
/**
Inserts liquid into the container.
@param liquid_name: Material to insert
@param amount: Max amount of material being inserted.
Passing a nil parameter will fill the
container to its maximum.
@param source: Object which inserts the liquid [optional]
@return returned_amount: The inserted amount
*/
public func PutLiquid(liquid_name, int amount, object source)
{
amount = amount ?? this->GetLiquidAmountRemaining();
if (amount < 0)
{
FatalError(Format("You can insert positive amounts of liquid only, got %d", amount));
}
var type = GetLiquidDef(liquid_name);
var max = this->GetLiquidContainerMaxFillLevel(liquid_name);
var before = GetLiquidAmount(liquid_name);
if (max > 0 && before >= max) return 0;
if (type)
{
var liquid = type->~CreateLiquid(amount);
if (liquid) Collect(liquid, true);
// the check is necessary here, because the liquid may get removed if the barrel already
// has a stack inside
if (liquid && !(liquid->Contained())) liquid->RemoveObject();
}
var after = GetLiquidAmount(liquid_name);
return after - before;
}
public func AcceptsLiquid(liquid_name, int amount)
{
// Container must accept material and not be full.
var liquid_type = GetLiquidDef(liquid_name)->GetLiquidType();
return IsLiquidContainerForMaterial(liquid_type) && amount <= this->GetLiquidContainerMaxFillLevel(liquid_name) - GetLiquidAmount(liquid_name);
}
private func GetLiquidDef(liquid_name)
{
if (GetType(liquid_name) == C4V_String)
return GetDefinition(liquid_name);
else if (GetType(liquid_name) == C4V_Def)
return liquid_name;
FatalError(Format("The first parameter of GetLiquidDef() must either be a string or definition. You passed %v.", liquid_name));
return nil;
}
|