File: Script.c

package info (click to toggle)
openclonk 8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 169,484 kB
  • sloc: cpp: 180,478; ansic: 108,988; xml: 31,371; python: 1,223; php: 767; makefile: 139; sh: 101
file content (216 lines) | stat: -rw-r--r-- 5,147 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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
/**
	Windmill
	Crushes seeds into flour using power. It can either use its own power
	generated by the mill or drain power from the network if the wind does
	not supply enough.
	
	@authors Ringwaul, Clonkonaut, Maikel
*/

#include Library_Structure
#include Library_Ownable
#include Library_Producer

local last_power;
local wheel;

func TurnAnimation() { return "Spin"; }
func MinRevolutionTime() { return 18000; } // in frames

protected func Construction()
{
	SetProperty("MeshTransformation", Trans_Rotate(-30, 0, 1, 0));
	SetAction("Default");
	return _inherited(...);
}

public func IsHammerBuildable() { return true; }

protected func Initialize()
{
	// Create a helper object for the wheel.
	wheel = CreateObject(WindGenerator_Wheel, 0, 0, NO_OWNER);
	wheel->SetParent(this, 150);
	// Start the animation for the wheel.
	PlayAnimation(TurnAnimation(), 5, wheel->Anim_R(GetAnimationLength(TurnAnimation()), 0));
	// Initialize a regular check of the wheel's position and speed, also handles power updates.
	last_power = 0;
	AddTimer("Wind2Turn", 4);
	Wind2Turn();
	// Another timer for the collection zone.
	AddTimer("CollectionZone", 1);
	return _inherited(...);
}

// Timer, check for objects to collect in the designated collection zone.
public func CollectionZone()
{
	if (GetCon() < 100) 
		return;
	for (var object in FindObjects(Find_InRect(-18 + 21 * GetDir(), 35, 15, 15), Find_OCF(OCF_Collectible), Find_NoContainer(), Find_Layer(GetObjectLayer())))
		Collect(object);
	return;
}

protected func Collection()
{
	Sound("Objects::Clonk");
	return;
}

/*-- Power Production --*/

// Returns the wind weighted over several points.
private func GetWeightedWind()
{
	return (
		(10 * GetWind(-150, -30)) + 
		(25 * GetWind( -75, -30)) + 
		(30 * GetWind(   0, -30)) + 
		(25 * GetWind( +75, -30)) + 
		(10 * GetWind(+150, -30))
		) / 100;
}

// Turns wind into power and adjusts the power production accordingly.
public func Wind2Turn()
{	
	// Only produce power if fully constructed.
	if (GetCon() < 100) 
		return;
	var current_wind = GetWeightedWind();
	// Determine the current power production.	
	var power = 0;
	if (!wheel->Stuck() && !wheel->HasStopped())
	{
		// Produced power ranges from 0 to 80 in steps of 10.
		power = Abs(wheel->GetRDir(MinRevolutionTime() / 90));
		power = BoundBy((10 * power + 60) / 125 * 10, 0, 80);	

		// Make some sounds.
		if (Random(10 + Abs(current_wind)) < 5 && !Random(5))
			Sound(["Hits::Materials::Wood::WoodCreak?","Structures::HingeCreak?"][Random(2)], false, nil, nil, nil, 75);
	}
	// Update the power consumption if the produced power has changed.
	if (last_power != power)
	{
		last_power = power;
		// If in production update the power consumption.
		if (GetEffect("InProduction", this))
			RegisterPowerRequest(this->PowerNeed());
	}
	// Adjust the wheel speed.
	wheel->SetRDir(current_wind * 90, MinRevolutionTime());
	return;
}

// Power need for the production library.
public func PowerNeed() 
{
	return Max(0, 30 - last_power); 
}


/*-- Production --*/

private func IgnoreKnowledge() { return true; }

private func IsProduct(id product_id)
{
	return product_id->~IsWindmillProduct();
}

private func ProductionTime(id product) { return _inherited(product, ...) ?? 290; }

public func OnProductionStart(id product)
{
	AddEffect("InProduction", this, 100, 10, this);
	AddEffect("Crushing", this, 100, 10, this);
	return;
}

public func OnProductionContinued(id product)
{
	AddEffect("Crushing", this, 100, 10, this);
	return;
}

public func OnProductionHold(id product)
{
	RemoveEffect("Crushing", this);
	return;
}

public func OnProductionFinish(id product)
{
	RemoveEffect("InProduction", this);
	RemoveEffect("Crushing", this);
	return;
}	

public func FxInProductionTimer(object target, proplist effect, int time)
{
	return 1;
}

public func FxCrushingTimer(object target, proplist effect, int time)
{
	var dir = GetCalcDir();
	var particles =
	{
		Prototype = Particles_WoodChip(),
		R = 255,
		G = 200,
		B = 100
	};
	CreateParticle("Dust", PV_Random(11 * dir, 13 * dir), 40, PV_Random(-5, 5), PV_Random(-13, -6), PV_Random(36 * 3, 36 * 10), particles, 3);
	
	return 1;
}

public func OnProductEjection(object product)
{
	product->SetPosition(GetX() - 25 * GetCalcDir(), GetY() + 40);
	product->SetSpeed(0, -17);
	product->SetR(30 - Random(59));
	Sound("Structures::EjectionPop");
	return;
}

protected func RejectCollect(id item, object collect)
{
	if (collect->~IsMillIngredient()) 
		return false;
	return true;
}


/*-- Properties --*/

local ActMap = {
	Default = {
		Prototype = Action,
		Name = "Default",
		Procedure = DFA_NONE,
		Directions = 2,
		//FlipDir = 1,
		Length = 1,
		Delay = 0,
		FacetBase = 1,
		NextAction = "Default",
	},
};

protected func Definition(def) 
{
	SetProperty("PictureTransformation", Trans_Mul(Trans_Translate(2000, 0, 7000), Trans_Rotate(-20, 1, 0, 0), Trans_Rotate(30, 0, 1, 0)), def);
	return _inherited(def, ...);
}

local ContainBlast = true;
local BlastIncinerate = 100;
local FireproofContainer = true;
local HitPoints = 70;
local Name = "$Name$";
local Description = "$Description$";
local Components = {Rock = 6, Wood = 2};