tracelines and solids

Discuss programming in the QuakeC language.
Post Reply
Nahuel
Posts: 495
Joined: Wed Jan 12, 2011 8:42 pm
Location: mar del plata

tracelines and solids

Post by Nahuel »

hello forum. I'm trying to get that the player send tracelines to impact on some functions with solid_trigger and send me information about the function. but apparently tracelines can not collide with solid_trigger brushes. there is any way that traceline impacts a solid_trigger entity?
what alternatives can I use? I am using darkplaces engine :)
hi, I am nahuel, I love quake and qc.
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: tracelines and solids

Post by Spike »

DP/FTE:
trigger.solid = SOLID_BSP;
traceline(start, end, 0, self);
trigger.solid = SOLID_TRIGGER;
(can still hit other solids. trigger must be known in advance)

FTE1:
traceline(start, end, 16, self);
(hits *only* triggers)

FTE2:
traceline(start, end, 32, self);
(hits anything including triggers)

FTE3:
traceline(start, end, 256, trigger);
(hits only the specified entity, regardless of trigger/etc)

Any Engine:
trigger.solid = SOLID_BSP;
setorigin(trigger, trigger.origin);
traceline(start, end, 0, self);
trigger.solid = SOLID_TRIGGER;
setorigin(trigger, trigger.origin);
(can still hit other solids. trigger must be known in advance)
Cobalt
Posts: 445
Joined: Wed Jun 10, 2009 2:58 am
Location: New England, USA
Contact:

Re: tracelines and solids

Post by Cobalt »

Theres some code in original src doors.qc that might do this for you with triggers....not tracelines. Not sure if it helps... as follows:

Code: Select all

float (entity e1, entity e2) EntitiesTouching =
{
	if ((e1.mins_x > e2.maxs_x))
	{
		return (FALSE);
	}
	if ((e1.mins_y > e2.maxs_y))
	{
		return (FALSE);
	}
	if ((e1.mins_z > e2.maxs_z))
	{
		return (FALSE);
	}
	if ((e1.maxs_x < e2.mins_x))
	{
		return (FALSE);
	}
	if ((e1.maxs_y < e2.mins_y))
	{
		return (FALSE);
	}
	if ((e1.maxs_z < e2.mins_z))
	{
		return (FALSE);
	}
	return (TRUE);
};

Theres also this utility written a long time ago which Seven supplied to me revently, that probably wont hurt including in any mod as a utility to do some basic checks. Though alot of them are obsolete with the introduction of DP_tracebox you can still learn alot from them if you are doing tricky stuff:

Code: Select all

//==========================================================================
//  check.qc -- by Patrick Martin               Last updated:  9-8-1997
//--------------------------------------------------------------------------
//  This file contains code that determines whether an entity or a
//  location is inside the various contents found in Quake.
//==========================================================================

//-------------------------------------------------------- New Code --------
//  This checks for obstacles such as solid entities or walls inside
//  the bbox and along its borders.  If an obstacle is met, FALSE is
//  returned.
//--------------------------------------------------------------------------
float(entity head, vector spot) PM_TraceCheck =
{
        local   vector  p1, p2;

// Check for obstacles inside the bbox.
// Order:  1)--- to +++    2)+-- to -++    3)++- to --+    4)-+- to +-+
        p1 = spot + self.mins;
        p2 = spot + self.maxs;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1_x = spot_x + self.maxs_x;
        p2_x = spot_x + self.mins_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1_y = spot_y + self.maxs_y;
        p2_y = spot_y + self.mins_y;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1_x = spot_x + self.mins_x;
        p2_x = spot_x + self.maxs_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

// Check for obstacles along the bbox boundaries.
// Order:  1)+++ to ++-    2)+-+ to +--    3)--+ to ---    4)-++ to -+-
//         5)--- to +--    6)+-- to ++-    7)++- to -+-    8)-+- to ---
//         9)+++ to -++   10)-++ to --+   11)--+ to -+-   12)-+- to +++
        p1 = p2 = spot + self.maxs;
        p2_z = spot_z + self.mins_z;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1_x = p2_x = spot_x + self.mins_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1_y = p2_y = spot_y + self.mins_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1_x = p2_x = spot_x + self.maxs_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1 = p2 = spot + self.mins;
        p2_x = spot_x + self.maxs_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1 = p2;
        p2_y = spot_y + self.maxs_y;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1 = p2;
        p2_x = spot_x + self.mins_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1 = p2;
        p2_y = spot_y + self.mins_y;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1 = p2 = spot + self.maxs;
        p2_x = spot_x + self.mins_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1 = p2;
        p2_y = spot_y + self.mins_y;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1 = p2;
        p2_x = spot_x + self.maxs_x;
        traceline (p1, p2, FALSE, head);
        if (trace_fraction < 1)  return FALSE;

        p1 = p2;
        p2_y = spot_y + self.maxs_y;
        traceline (p1, p2, FALSE, head);
        return (trace_fraction == 1);
};

//-------------------------------------------------------- New Code --------
//  This checks if a bbox is inside a wall or sky.  The bbox's origin
//  and corners are checked.  If any one points is within a solid or sky,
//  TRUE is returned.
//--------------------------------------------------------------------------
float(entity head, vector spot) PM_InWall =
{
        local   vector  p;

// Check origin.
        p = spot;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

// Check bbox faces.
// Order:  1)-00  2)+00  3)0-0  4)0+0  5)00-  6)00+
        p_x = spot_x + head.mins_x;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_x = spot_x + head.maxs_x;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p = spot;
        p_y = spot_y + head.mins_y;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_y = spot_y + head.maxs_y;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p = spot;
        p_z = spot_z + head.mins_z;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_z = spot_z + head.maxs_z;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

// Check bbox corners.
// Order:  1)+++  2)-++  3)+-+  4)--+  5)++-  6)-+-  7)+--  8)---
        p_x = spot_x + head.maxs_x;
        p_y = spot_y + head.maxs_y;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_x = spot_x + head.mins_x;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_x = spot_x + head.maxs_x;
        p_y = spot_y + head.mins_y;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_x = spot_x + head.mins_x;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_x = spot_x + head.maxs_x;
        p_y = spot_y + head.maxs_y;
        p_z = spot_z + head.mins_z;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_x = spot_x + head.mins_x;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_x = spot_x + head.maxs_x;
        p_y = spot_y + head.mins_y;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        if (pointcontents(p) == CONTENT_SKY)    return TRUE;

        p_x = spot_x + head.mins_x;
        if (pointcontents(p) == CONTENT_SOLID)  return TRUE;
        return (pointcontents(p) == CONTENT_SKY);
};

//-------------------------------------------------------- New Code --------
//  This is a variation of InWall.  The bbox is checked if it is a
//  empty air; that is not inside solid, water, or anything else.
//  If any one point is within a brush, FALSE is returned.
//--------------------------------------------------------------------------
float(entity head, vector spot) PM_InEmpty =
{
        local   vector  p;

// Check origin.
        p = spot;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

// Check bbox faces.
// Order:  1)-00  2)+00  3)0-0  4)0+0  5)00-  6)00+
        p_x = spot_x + head.mins_x;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_x = spot_x + head.maxs_x;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p = spot;
        p_y = spot_y + head.mins_y;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_y = spot_y + head.maxs_y;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p = spot;
        p_z = spot_z + head.mins_z;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_z = spot_z + head.maxs_z;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

// Check bbox corners.
// Order:  1)+++  2)-++  3)+-+  4)--+  5)++-  6)-+-  7)+--  8)---
        p_x = spot_x + head.maxs_x;
        p_y = spot_y + head.maxs_y;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_x = spot_x + head.mins_x;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_x = spot_x + head.maxs_x;
        p_y = spot_y + head.mins_y;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_x = spot_x + head.mins_x;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_x = spot_x + head.maxs_x;
        p_y = spot_y + head.maxs_y;
        p_z = spot_z + head.mins_z;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_x = spot_x + head.mins_x;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_x = spot_x + head.maxs_x;
        p_y = spot_y + head.mins_y;
        if (pointcontents(p) != CONTENT_EMPTY)  return FALSE;

        p_x = spot_x + head.mins_x;
        return (pointcontents(p) == CONTENT_EMPTY);
};

//-------------------------------------------------------- New Code --------
//  This checks if the entity is in a body of liquid.
//--------------------------------------------------------------------------
float(entity head) PM_InLiquid =
{
        if (head.classname == "player") // Cobalt added
	 head.origin_z = head.origin_z - 20; // right at players feet - take care because I am not sure if this actually changes the origin of the player?
        if (pointcontents(head.origin) == CONTENT_WATER)  return TRUE;
        if (pointcontents(head.origin) == CONTENT_SLIME)  return TRUE;
        if (pointcontents(head.origin) == CONTENT_LAVA)   return TRUE;

        return FALSE;    // Entity is not in liquid.
};

//--------------------------------------------------------------------------
//  END OF LINE.
//--------------------------------------------------------------------------
Post Reply