File: Script.c

package info (click to toggle)
openclonk 8.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 169,500 kB
  • sloc: cpp: 180,478; ansic: 108,988; xml: 31,371; python: 1,223; php: 767; makefile: 139; sh: 101; javascript: 34
file content (154 lines) | stat: -rw-r--r-- 4,713 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
/**
	Animal Library
	Handles reproduction and growth for animals. If included the Construction()
	call must return _inherited(...) for this library to work.
	
	@author Maikel
*/


// This object is an animal.
public func IsAnimal() { return true; }

protected func Construction(...)
{
	// Add a reproduction timer.
	AddReproductionEffect();
	// Add a growth effect.
	StartGrowth(GrowthSpeed());
	_inherited(...);
}

private func AddReproductionEffect()
{
	if (!GetEffect("IntReproduction", this))
		return AddEffect("IntReproduction", this, 100, 72, this);
}

private func RemoveReproductionEffect()
{
	return RemoveEffect("IntReproduction", this);
}


/*-- Growth --*/

// Speed of the growth of an animal.
private func GrowthSpeed() { return 5; }


/*-- Reproduction --*/

local animal_reproduction_area_size = 800;
local animal_reproduction_rate = 67;
local animal_max_count = 10;

// Population control is handled through these variables.
// The area, in which new animals of this kind can appear.
public func ReproductionAreaSize() { return animal_reproduction_area_size; }
public func SetReproductionAreaSize(int v) { animal_reproduction_area_size = v; return true; }
// The chance that reproduction takes place in one timer interval. From 0 to 10000.
// The higher this value the more likely it is to reproduce. Special: If it is zero, reproduction is off.
public func ReproductionRate() { return animal_reproduction_rate; }
public func SetReproductionRate(int v)
{
	animal_reproduction_rate = v;
	if (v) AddReproductionEffect(); else RemoveReproductionEffect();
	return true;
}
// The maximal animal count in the area.
public func MaxAnimalCount() { return animal_max_count; }
public func SetMaxAnimalCount(int v) { animal_max_count = v; return true; }

// Special reproduction method (e.g. with egg).
private func SpecialReproduction()
{
	// You can have a special kind of reproduction implemented here.
	// If you do so return true in this function.
	return false;
}

// Standard conditions for reproduction.
private func ReproductionCondition()
{
	return GetAlive() && GetCon() >= 100;
}

// Special conditions which needs to be fulfilled (e.g. a fish should have the swim action).
private func SpecialReproductionCondition()
{
	// You can implement a special condition for reproduction here.
	// Return false if this condition is not satisfied.
	return true;
}

// Count animals in the reproduction area.
private func CountAnimalsInArea()
{
	var reprod_size = ReproductionAreaSize();
	var reprod_size_half = reprod_size / 2;
	return ObjectCount(Find_ID(GetID()), Find_InRect(-reprod_size_half, -reprod_size_half, reprod_size , reprod_size), Find_OCF(OCF_Alive));
}

public func FxIntReproductionTimer(object target, proplist effect, int time)
{
	// Already dead or not full grown? Don't do anything.
	if (!ReproductionCondition()) 
		return FX_OK;
	// Apply the reproduction rate.
	if (Random(10000) >= ReproductionRate())
		return FX_OK;
	// Special conditions not fulfilled? Don't do anything either.
	if (!SpecialReproductionCondition()) 
		return FX_OK;
	// Check whether there are already enough animals of this kind.
	if (CountAnimalsInArea() >= MaxAnimalCount())
		return FX_OK;
	// Reproduction: first try special reproduction, otherwise normal.
	if (!SpecialReproduction())
	{
		// Normal reproduction.
		var child = CreateConstruction(GetID(), 0, 0, NO_OWNER, 40);
		child->~Birth(this);
	}
	return FX_OK;
}

// Callback in the animal on its birth.
public func Birth(object parent)
{
	SetAction("Walk");
	if (Random(2)) 
		SetComDir(COMD_Left);
	else
		SetComDir(COMD_Right);
	return;
}


/*-- Collection --*/

protected func RejectEntrance(object container)
{
	// From one container to another is not blocked by this library.
	if (Contained()) 
		return _inherited(container, ...);
	// Neither are dead animals.
	if (!GetAlive()) 
		return _inherited(container, ...);
	// For all other cases the entrance is blocked.
	return true;
}



/* Editor */

public func Definition(def, ...)
{
	if (!def.EditorProps) def.EditorProps = {};
	def.EditorProps.animal_reproduction_area_size = { Name="$ReproductionAreaSize$", EditorHelp="$ReproductionAreaSizeHelp$", Type="int", Min=0, AsyncGet="ReproductionAreaSize", Set="SetReproductionAreaSize", Save="Reproduction" };
	def.EditorProps.animal_reproduction_rate = { Name="$ReproductionRate$", EditorHelp="$ReproductionRateHelp$", Type="int", Min=0, Max=10000, AsyncGet="ReproductionRate", Set="SetReproductionRate", Save="Reproduction" };
	def.EditorProps.animal_max_count = { Name="$MaxCount$", EditorHelp="$MaxCountHelp$", Type="int", Min=1, AsyncGet="MaxAnimalCount", Set="SetMaxAnimalCount", Save="Reproduction" };
	return _inherited(def, ...);
}