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 (128 lines) | stat: -rw-r--r-- 3,928 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
/*
	Fish
	Author: Zapper
*/

#include Fish

// Default additional scaling for the mesh.
local BaseScale = +200;
// Damage per bite.
local BiteStrength = 10;

local hunger;

func Construction()
{
	hunger = 0;
	AddTimer("MoreHunger", 80);
	// Set base transform (can be overwritten by e.g. Place()).
	SetYZScale(1000);
	_inherited(...);
}

func MoreHunger()
{
	++hunger;
	if (hunger > 100) hunger = 100;
}

func InitFuzzyRules()
{
	brain = FuzzyLogic->Init();
	
	// ACTION SETS
	brain->AddSet("swim", "sharp_left", [[-2 * SwimMaxAngle, 1], [-SwimMaxAngle, 0], [SwimMaxAngle, 0]]);
	brain->AddSet("swim", "left", [[-SwimMaxAngle, 1], [-SwimMaxAngle/2, 0], [SwimMaxAngle, 0]]);
	brain->AddSet("swim", "straight", [[-5, 0], [0, 1], [5, 0]]);
	brain->AddSet("swim", "right", [[-SwimMaxAngle, 0], [SwimMaxAngle/2, 0], [SwimMaxAngle, 1]]);
	brain->AddSet("swim", "sharp_right", [[-SwimMaxAngle, 0], [SwimMaxAngle, 0], [2 * SwimMaxAngle, 1]]);
	
	brain->AddSet("speed", "slow", [[0, 1], [SwimMaxSpeed/2, 0], [SwimMaxSpeed, 0]]);
	brain->AddSet("speed", "fast", [[0, 0],  [SwimMaxSpeed/2, 0], [SwimMaxSpeed, 1]]);
	
	// RULE SETS
	var directional_sets = ["food"];
	
	for (var set in directional_sets)
	{
		brain->AddSet(set, "left", [[-VisionMaxAngle, 1], [0, 0], [VisionMaxAngle, 0]]);
		brain->AddSet(set, "straight", [[-5, 0], [0, 1], [5, 0]]);
		brain->AddSet(set, "right", [[-VisionMaxAngle, 0], [0, 0], [VisionMaxAngle, 1]]);
	}
	
	var proximity_sets = ["food_range"];
	var middle = VisionMaxRange / 2;
	
	for (var set in proximity_sets)
	{
		brain->AddSet(set, "far", [[middle, 0], [VisionMaxRange, 1], [VisionMaxRange, 1]]);
		brain->AddSet(set, "medium", [[0, 0], [middle, 1], [VisionMaxRange, 0]]);
		brain->AddSet(set, "close", [[0, 1], [0, 1], [middle, 0]]);
	}
	
	brain->AddSet("left_wall", "close", [[0, 1], [0, 1], [wall_vision_range/2, 0]]);
	brain->AddSet("right_wall", "close", [[0, 1], [0, 1], [wall_vision_range/2, 0]]);
	brain->AddSet("wall_range", "close", [[0, 1], [0, 1], [wall_vision_range, 0]]);
	
	brain->AddSet("hunger", "low", [[0, 1], [0, 1], [75, 0]]);
	brain->AddSet("hunger", "high", [[25, 0], [100, 1], [100, 1]]);
	
	// RULES
	brain->AddRule(brain->And("hunger=high", "food=right"), "swim=right");
	brain->AddRule(brain->And("hunger=high", "food=left"), "swim=left");
	brain->AddRule("hunger=high", "speed=fast");
	brain->AddRule(brain->Or("wall_range=close", "hunger=low"), "speed=slow");
	brain->AddRule(brain->And("left_wall=close", brain->Not("right_wall=close")), "swim=sharp_right");
	brain->AddRule("right_wall=close", "swim=sharp_left");
}


func UpdateVision()
{
	brain->Fuzzify("hunger", hunger);
	UpdateVisionFor("food", "food_range", FindObjects(Find_Distance(VisionMaxRange), Find_OCF(OCF_Alive), Find_Func("IsPrey"), Find_NoContainer(), Sort_Distance()), true);
	UpdateWallVision();
}

func DoEat(object obj)
{
	BiteEffect();
	var len = GetAnimationLength("Bite");
	PlayAnimation("Bite", 5,  Anim_Linear(0, 0, len, 36, ANIM_Remove), Anim_Const(1000)); // temp overrides Swim animation in same slot
	if (obj->GetAlive())
		obj->DoEnergy(-BiteStrength);
	hunger -= 20;
	if (hunger < 0) hunger = 0;
	DoEnergy(BiteStrength);
}

private func BiteEffect()
{
	Sound("Animals::Fish::Munch*");
}

// Make this piranha a little larger than the mesh.
func SetYZScale(int new_scale)
{
	base_transform = Trans_Scale(1000 + BaseScale, new_scale + BaseScale, new_scale + BaseScale);
	return true;
}

local Name = "$Name$";
local Description = "$Description$";
local MaxEnergy = 50000;
local Placement = 1;
local NoBurnDecay = true;
local BreatheWater = 1;
local BorderBound = C4D_Border_Sides | C4D_Border_Top | C4D_Border_Bottom;
local ContactCalls = true;

func IsPrey() { return false; }
func IsPredator() { return true; }

func Definition(proplist def)
{
	def.PictureTransformation = Trans_Mul(Trans_Translate(2000, 0, 0), Trans_Scale(1500), Trans_Rotate(20, 1, 0, 0), Trans_Rotate(70, 0, 1, 0));
}