File: Vertices.c

package info (click to toggle)
openclonk 8.1-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 169,656 kB
  • sloc: cpp: 180,484; ansic: 108,988; xml: 31,371; python: 1,223; php: 767; makefile: 148; sh: 101; javascript: 34
file content (136 lines) | stat: -rw-r--r-- 3,721 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
/**
	Vertices.c
	Vertex related functions.
	
	@author Clonkonaut, flgr
*/

// Sets both the X and Y-coordinate of one vertex.
// documented in /docs/sdk/script/fn
global func SetVertexXY(int index, int x, int y)
{
	// Set vertices.
	SetVertex(index, VTX_X, x);
	SetVertex(index, VTX_Y, y);
	return;
}

// Returns the number of stuck vertices. (of this)
// documented in /docs/sdk/script/fn
global func VerticesStuck()
{
	var vertices = 0;
	// Loop through vertices.
	for (var i = -1; i < GetVertexNum(); i++)
		// Solid?
		if (GBackSolid(GetVertex(i, VTX_X), GetVertex(i, VTX_Y)))
			// Count vertices.
			vertices++;
	return vertices;
}

// Automatically move an object up to <range> pixels in each direction if it is stuck
// documented in /docs/sdk/script/fn
global func Unstick(int range)
{
	if (Stuck())
	{
		for (var i = 1; i <= (range ?? 7); ++i)
		{
			for (var d in [[0,-i], [0,i], [-i,0], [i,0]])
			{
				if (!Stuck(d[0], d[1]))
				{
					if (Inside(GetX()+d[0], 0, LandscapeWidth()-1) && GetY()+d[1] < LandscapeHeight()) // But do not push outside landscape!
					{
						return SetPosition(GetX() + d[0], GetY() + d[1]);
					}
				}
			}
		}
	}
	// Unsticking failed (or not stuck).
	return false;
}

// Returns whether the object has a vertex with the given CNAT value
global func HasCNAT(int cnat)
{
	for (var i = -1; i < GetVertexNum(); i++)
		if (GetVertex(i, VTX_CNAT) == cnat)
			return true;
	return false;
}

// e.g. clonk->SetVertexCNAT(k, CNAT_CollideHalfVehicle, true); for k != 2 makes the clonk behave correctly wrt. to HalfVehicle
global func SetVertexCNAT(int vtx, int val, bool set)
{
	if (val == nil || set == nil)
		return FatalError("this function requires its second and third parameter to be non-nil");
	if (!this)
		return FatalError("this function requires object context");
	if (vtx == nil)
		for (var i = GetVertexNum(); i-->0;)
			SetVertexCNAT(i, val, set);
	else
		SetVertex(vtx, VTX_CNAT, GetVertex(vtx, VTX_CNAT) & ~val | (set && val), 2);
}

// Allow falling down throughg a HalfVehicle platform
global func HalfVehicleFadeJumpStart()
{
	if (!this)
		return FatalError("this function requires object context");
	if (GetEffect("IntHalfVehicleFadeJump", this))
		return;
	AddEffect("IntHalfVehicleFadeJump", this, 1);
}


global func HalfVehicleFadeJumpStop()
{
	if (!this)
		return FatalError("this function requires object context");
	var fx;
	if (fx = GetEffect("IntHalfVehicleFadeJump", this))
		fx.Interval = 1;
}

global func FxIntHalfVehicleFadeJumpStart(object target, effect fx, int temp)
{
	if (temp)
		return FX_OK;
	if (!target) {
		return FX_Start_Deny;
	}
	fx.collideverts = CreateArray();
	for (var i = target->GetVertexNum(); i-->0;)
		if(!(target->GetVertex(i, VTX_CNAT) & CNAT_PhaseHalfVehicle)) {
			PushBack(fx.collideverts, i);
			target->SetVertexCNAT(i, CNAT_PhaseHalfVehicle, true);
		}
	fx.origpos = target->GetPosition();
	return FX_OK;
}

global func FxIntHalfVehicleFadeJumpTimer(object target, effect fx, int time)
{
	if (DeepEqual(target->GetPosition(), fx.origpos))
		return FX_OK;
	for (var i = GetLength(fx.collideverts); i-- > 0;)
	{
		if (target->GetMaterial(target->GetVertex(fx.collideverts[i], VTX_X),
		                        target->GetVertex(fx.collideverts[i], VTX_Y)) == Material("HalfVehicle"))
			return FX_OK;
	}
	return FX_Execute_Kill;
	// The way this is implemented, it may ignore smaller cracks beteween half-solid masks at high speeds. Fix if necessary.
}

global func FxIntHalfVehicleFadeJumpStop(object target, effect fx, int reason, bool temp)
{
	if (reason == FX_Call_RemoveClear)
		return;
	for (var i = GetLength(fx.collideverts); i-- > 0;)
		target->SetVertexCNAT(fx.collideverts[i], CNAT_PhaseHalfVehicle, false);
}