GetZAt
native double 'GetZAt(double px = 0, double py = 0, double angle = 0, int flags = 0, int pick_pointer = AAPTR_DEFAULT)
Usage
Gets the Z of the floor or ceiling at coordinates x and y based on flags. This allows for more flexible checks than the floorz and ceilingz Actor properties.
This function is capable of succeeding where A_CheckFloor and A_CheckCeiling have their shortcomings -- over ledges and at the edges of a hitbox. With a proper loop, an actor can detect if any part of the pointed actor is truly on the ground or touching the ceiling in its entirety or not.
Note that this function is to be used where an expression is expected. It is mostly useful when combined with A_JumpIf or Anonymous Functions.
Parameters
- double px
- The x coordinates based on relativity to the pointer. Positive numbers move the check forward, negative moves it behind.
- double py
- Similar to X but for side-to-side. Positive numbers move the check to the right of the actor, negative moves it to the left.
- double angle
- The offset amount added to the actor's current angle. Positive amounts rotate the check to the left, negative to the right.
- int flags
- Multiple flags can be combined with
|
. The following flags are available:- GZF_ABSOLUTEPOS: Relativity is disabled and the x/y coordinates are absolute.
- GZF_ABSOLUTEANG: angle is not added to the actor's current angle.
- GZF_CEILING: The function checks for the ceiling's z instead of the floor's.
- GZF_3DRESTRICT: Ignores Z on top of midtextures and 3D floors that are above the pointer's position.
- GZF_NOPORTALS: Ignores the existence of portals and does not traverse into other sectors.
- GZF_NO3DFLOOR: Ignores all 3D floors above or below the pointer between it and the true floor/ceiling.
- int pick_pointer
- The pointer to examine. Default is AAPTR_DEFAULT. See actor pointers.
Return value
double — Returns the floorz or ceilingz based on the flags above as a double.
Examples
This custom version of Blood enters a Death state upon hitting the floor and then leaves a pool on the floor (which is a flat sprite). However, in order to make sure that the flat sprite doesn't stick out into the air when it falls near a ledge or on a narrow stair, four GetZAt checks are introduced. Unless the floor height of four points 24 units away in 4 directions from the center of the BetterBlood actor is equal to the floor height under the actor's center, the pool doesn't appear.
ZScript code
In this example the sprites SPLTA-SPLTD are meant to be represent a pool of blood (viewed from above).
class BetterBlood : Blood replaces Blood
{
Default
{
-ALLOWPARTICLES
+MISSILE
}
States
{
Spawn:
BLUD CBA 8;
wait;
Death:
TNT1 A 0
{
// if any if these checks fail, destroy the actor by moving
// to the "Null" state sequence:
if (GetZAt(24,0) != floorz || GetZAt(-24,0) != floorz || GetZAt(0,24) != floorz || GetZAt(0,-24) != floorz)
{
return FindState("Null");
}
// otherwise make it a flat sprite and continue:
bFLATSPRITE = true;
return State(null);
}
SPLT A -1
{
// set the sprite frame randomly to A, B, C or D:
frame = random(0,3);
}
stop;
}
}
Another option in ZScript is to use a for loop and utilize the angle argument of GetZAt() to rotate the check. This will run the check every 30 degrees:
class BetterBlood : Blood replaces Blood
{
Default
{
-ALLOWPARTICLES
+MISSILE
}
States
{
Spawn:
BLUD CBA 8;
wait;
Death:
TNT1 A 0
{
// Check 24 units away from the actor, rotating
// the check by 30 degrees with every iteration:
for (int i = 0; i < 360; i += 30)
{
// As soon as this check fails destroy the
// actor by moving to the "Null" sequence:
if (GetZAt(24, 0, i) != floorz)
{
return FindState("Null");
}
}
// otherwise make it a flat sprite and continue:
bFLATSPRITE = true;
return State(null);
}
SPLT A -1
{
// set the sprite frame randomly to A, B, C or D:
frame = random(0,3);
}
stop;
}
}
DECORATE code
Actor BetterBlood : Blood replaces Blood { -ALLOWPARTICLES +MISSILE States { Spawn: BLUD CBA 8 wait Death: // go to the "Pool" state sequence only if all of these checks pass: TNT1 A 0 A_JumpIf(GetZAt(24,0) == floorz && GetZAt(-24,0) == floorz && GetZAt(0,24) == floorz && GetZAt(0,-24) == floorz, "Pool") stop Pool: // make it a flat sprite and set one of the frames randomly: TNT1 A 0 A_ChangeFlag("FLATSPRITE",1) TNT1 A 0 A_Jump(256,1,2,3,4) SPLT A -1 stop SPLT B -1 stop SPLT C -1 stop SPLT D -1 stop } }