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);
}
|