File: Script.c

package info (click to toggle)
openclonk 8.1-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 169,516 kB
  • sloc: cpp: 180,479; ansic: 108,988; xml: 31,371; python: 1,223; php: 767; makefile: 145; sh: 101; javascript: 34
file content (160 lines) | stat: -rw-r--r-- 4,250 bytes parent folder | download | duplicates (5)
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;
}