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 (139 lines) | stat: -rw-r--r-- 3,858 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
/**
	AI Melee Weapons
	Functionality that helps the AI use melee weapons. Handles:
	 * Sword
	 * Club
	 * Axe
	
	@author Sven2, Maikel
*/


/*-- General Melee Weapon --*/

private func ExecuteMelee(effect fx)
{
	// Still carrying the melee weapon?
	if (fx.weapon->Contained() != fx.Target)
	{
		fx.weapon = nil;
		return false;
	}
	// Are we in range?
	var x = fx.Target->GetX(), y = fx.Target->GetY(), tx = fx.target->GetX(), ty = fx.target->GetY();
	var dx = tx - x, dy = ty - y;
	if (Abs(dx) <= 10 && PathFree(x, y, tx, ty))
	{
		if (dy >= -15)
		{
			// Target is under us - sword slash downwards!
			if (!this->CheckHandsAction(fx))
				return true;
			// Stop here.
			fx.Target->SetCommand("None");
			fx.Target->SetComDir(COMD_None);
			// Cooldown?
			if (!fx.weapon->CanStrikeWithWeapon(fx.Target))
			{
				// While waiting for the cooldown, we try to evade...
				this->ExecuteEvade(fx, dx, dy);
				return true;
			}
			// OK, do a strike.
			this->SelectItem(fx, fx.weapon);
			// First try to do a single control use call.
			if (!fx.weapon->~HoldingEnabled() && fx.weapon->~ControlUse(fx.Target, tx, ty))
				return true;
			// Assume the weapon must be held longer for a strike.
			if (fx.weapon->~ControlUseStart(fx.Target, tx, ty))
			{
				fx.weapon->~ControlUseHolding(fx.Target, tx, ty);
				fx.weapon->~ControlUseStop(fx.Target, tx, ty);
			}
		}
		// Clonk is above us - jump there, but only if not commanded.
		if (!fx.commander)
		{
			this->ExecuteJump(fx);
			if (dx < -5)
				fx.Target->SetComDir(COMD_Left);
			else if (dx > 5)
				fx.Target->SetComDir(COMD_Right);
			else
				fx.Target->SetComDir(COMD_None);
		}
	}
	// Not in range. Walk there, but only if not being commanded.
	if (!fx.commander && (!fx.Target->GetCommand() || !Random(10)))
		fx.Target->SetCommand("MoveTo", fx.target);
	return true;
}

private func ExecuteClub(effect fx)
{
	// Still carrying the melee weapon?
	if (fx.weapon->Contained() != fx.Target)
	{
		fx.weapon = nil;
		return false;
	}
	// Are we in range?
	var x=fx.Target->GetX(), y=fx.Target->GetY(), tx=fx.target->GetX(), ty=fx.target->GetY();
	var dx = tx-x, dy = ty-y;
	if (Abs(dx) <= 10 && PathFree(x,y,tx,ty))
	{
		if (Abs(dy) >= 15)
		{
			// Clonk is above or below us - wait
			if (dx<-5) fx.Target->SetComDir(COMD_Left); else if (dx>5) fx.Target->SetComDir(COMD_Right); else fx.Target->SetComDir(COMD_None);
			return true;
		}
		if (!this->CheckHandsAction(fx)) return true;
		// Stop here
		fx.Target->SetCommand("None"); fx.Target->SetComDir(COMD_None);
		// cooldown?
		if (!fx.weapon->CanStrikeWithWeapon(fx.Target))
		{
			//Message("MeleeWAIT %s @ %s!!!", fx.weapon->GetName(), fx.target->GetName());
			// While waiting for the cooldown, we try to evade...
			this->ExecuteEvade(fx,dx,dy);
			return true;
		}
		// OK, attack! Prefer upwards strike
		dy -= 16;
		fx.weapon->ControlUseStart(fx.Target, dx,dy);
		fx.weapon->ControlUseHolding(fx.Target, dx,dy);
		fx.weapon->ControlUseStop(fx.Target, dx,dy);
		return true;
	}
	// Not in range. Walk there.
	if (!fx.Target->GetCommand() || !Random(10)) fx.Target->SetCommand("MoveTo", fx.target);
	//Message("Melee %s @ %s!!!", fx.weapon->GetName(), fx.target->GetName());
	return true;
}

private func ExecuteBomber(effect fx)
{
	// Still carrying the bomb?
	if (fx.weapon->Contained() != fx.Target)
	{
		fx.weapon=nil;
		return false;
	}
	// Are we in range?
	if (fx.Target->ObjectDistance(fx.target) < 20 && !fx.weapon->OnFire())
	{
		// make sure it kills the AI clonk, because it would be useless after the explosion
		fx.Target->DoEnergy(5 - fx.Target->GetEnergy());
		// Boom!
		fx.weapon.TimeToExplode = 10;
		fx.weapon->Incinerate(100, fx.Target->GetController());
	}
	else
	{
		// Not in range. Walk there.
		if (!fx.Target->GetCommand() || !Random(10))
			fx.Target->SetCommand("MoveTo", fx.target);
	}
	return true;
}