LineTrace

From ZDoom Wiki
Jump to navigation Jump to search
Note: This page is about a ZScript function. This should not be confused with the LineTracer class that can be used for similar purposes.

Actor

native bool LineTrace(double angle, double distance, double pitch, int flags = 0, double offsetz = 0., double offsetforward = 0., double offsetside = 0., out FLineTraceData data = null)

Usage

Draws a hitscan line from an actor, at the specified angle, pitch and range (distance). The line originates from the calling actor's exact position, which means that offsetz must be used if this is intended to represent an attack like a gunshot.

Parameters

  • double angle
The absolute angle of the direction to fire the line.
  • double distance
The maximum range the line is allowed to travel.
  • double pitch
The absolute pitch of the direction to fire the line.
  • int flags
Flags passed to the function. Multiple flags can be combined with |:
  • TRF_ABSPOSITION — makes offsets absolute coordinates.
  • TRF_ABSOFFSET — makes the x (forward) and y (side) offsets independent from actor rotation.
  • TRF_THRUSPECIES — passes through all actors sharing the caller's species.
  • TRF_THRUACTORS — passes through all actors in general. Useful for when you only need map geometry.
  • TRF_THRUBLOCK — passes through all lines set to "block everything".
  • TRF_THRUHITSCAN — passes through all lines set to "block hitscan".
  • TRF_NOSKY — treats hitting a sky texture as not hitting anything at all.
  • TRF_ALLACTORS — may stop at any actor, even if it's not shootable or solid (this still excludes actors not in the blockmap e.g. projectiles).
  • TRF_SOLIDACTORS — will also stop at actors that aren't shootable but still solid.
  • TRF_BLOCKUSE — stops at lines set to "block use".
  • TRF_BLOCKSELF — stops at lines that would normally block the calling actor (e.g. if called from a player, stop at impassable or "block players" lines).
  • double offsetz
The amount to offset the height of the line's origin from the caller's position. Default is 0, meaning the trace will originate at the bottom of the actor.
Note: if you're calling the function from the player (either on a PlayerPawn directly, or from a weapon state), if you want the height of the origin point of the trace to exactly match the attack height of the player, use the following expression for this argument: player.mo.height * 0.5 - player.mo.floorclip + player.mo.AttackZOffset*player.crouchFactor. This expression takes all relevant values into the account, including floorclip, the crouch factor defined in the PlayerInfo struct, and the value of the AttackZOffset property.
If you want this to match the center of the player's screen, use player.viewz - player.mo.pos.z instead.
  • double offsetforward
Default is 0. The amount to offset the line's origin in the direction the caller is facing.
  • double offsetside
Default is 0. The amount to offset the line's origin to the sides of the caller.
  • FLineTraceData data
Stores information about the hitscan after the check is performed. Default is null.

Return value

The function's actual return is true or false, indicating whether the line hit anything.

Much more significantly, this function lets you write information to an FLineTraceData pointer that can be accessed for detailed information about what the line hit and where.

Note: Some of these values are only relevant if the return result of the function was true. If the function returns false, some of them may still be set to the last thing the line hit, even if that thing was ignored. Always check the trace actually hit something before using these values. Furthermore, the HitType value should be checked first, as pointers might contain bogus data that won't match what was truly hit.

The struct contains the following pointers:

  • Actor HitActor
The actor that got hit, if any.
  • Line HitLine
The line that got hit, if any.
  • Sector HitSector
The sector in which the impact occurred or the trace terminated.
  • F3DFloor Hit3DFloor
The 3D floor that got hit, if any.
  • TextureID HitTexture
The Id of the texture of the surface that got hit, if any.
  • Vector3 HitLocation
The absolute position in the map in which the impact occurred or the trace terminated.
  • Vector3 HitDir
A unit vector representing the direction in which the trace was traveling when it terminated.
  • double Distance
The total distance traveled by the trace, whether it hit anything or not.
  • int NumPortals
The number of portals the trace crossed while traveling.
  • int LineSide
Which side of the line the trace hit, if any. Can be one of the following constants:
  • Line.front
  • Line.back
  • int LinePart
Which part of the line the trace hit, if any. Can be one of the following constants:
  • Side.top
  • Side.mid (always if a 3D floor was hit)
  • Side.bottom
  • int SectorPlane
Whether the trace hit the ceiling or floor, if either. Can be one of the following constants:
  • Sector.floor
  • Sector.ceiling
  • int HitType
What the trace hit, if anything. Can be one of the following constants:
  • TRACE_HitNone - nothing was hit
  • TRACE_HitFloor - hit a floor plane or the top of a 3D floor
  • TRACE_HitCeiling - hit a ceiling plane or the bottom of a 3D floor
  • TRACE_HitWall - hit a line (including sides of a 3D floor)
  • TRACE_HitActor - hit an actor
  • TRACE_CrossingPortal
  • TRACE_HasHitSky (unused)

Examples

This item when used will hit any switch in front of the player within about 2048 units, provided nothing is between the player and the line.

class RemoteSwitcher : Inventory
{
	Default
	{
		+Inventory.Invbar
		inventory.icon "CELLA0"; //substitute your own graphic
	}
	
	override bool Use (bool pickup)
	{
		if (owner && owner.player)
		{
			console.printf ("firing linetrace");
			FLineTraceData RemoteRay;
			double pz = owner.height * 0.5 - owner.floorclip + owner.player.mo.AttackZOffset*owner.player.crouchFactor;
			bool hit = owner.LineTrace(
				owner.angle,
				2048,
				owner.pitch,
				offsetz: pz,
				data: RemoteRay
			);

			if (hit && RemoteRay.HitType == TRACE_HitWall)
			{
				RemoteRay.HitLine.Activate(owner, 0, SPAC_Use);
			}
		}
		return false;
	}
}

See also