Beispiel #1
0
/*
=============
SV_PointContents
=============
*/
int SV_PointContents (vec3_t p)
{
	edict_t		*touch[MAX_EDICTS], *hit;
	int			i, num;
	int			contents, c2;
	int			headnode;
	float		*angles;

	// get base contents from world
	contents = CM_PointContents (p, sv.models[1]->headnode);

	// or in contents from all the other entities
	num = SV_AreaEdicts (p, p, touch, MAX_EDICTS, AREA_SOLID);

	for (i=0 ; i<num ; i++)
	{
		hit = touch[i];

		// might intersect, so do an exact clip
		headnode = SV_HullForEntity (hit);
		angles = hit->s.angles;
		if (hit->solid != SOLID_BSP)
			angles = vec3_origin;	// boxes don't rotate

		c2 = CM_TransformedPointContents (p, headnode, hit->s.origin, hit->s.angles);

		contents |= c2;
	}

	return contents;
}
Beispiel #2
0
int SV_PointContents(const CVec3 &p)
{
	guard(SV_PointContents);

	// get base contents from world
	unsigned contents = CM_PointContents(p, 0);
	contents |= CM_PointModelContents(p);

	edict_t	*list[MAX_EDICTS];
	int num = SV_AreaEdicts(p, p, ARRAY_ARG(list), AREA_SOLID);

	for (int i = 0; i < num; i++)
	{
		edict_t *edict = list[i];
		entityHull_t &ent = ents[NUM_FOR_EDICT(edict)];

		if (ent.model)
			contents |= CM_TransformedPointContents(p, ent.model->headnode, edict->s.origin, ent.axis);
		else
			contents |= CM_TransformedPointContents(p, CM_HeadnodeForBox(ent.bounds), edict->s.origin, nullVec3);
	}
	return contents;

	unguard;
}
Beispiel #3
0
/*
====================
SV_TouchLinks
====================
*/
void SV_TouchLinks ( edict_t *ent, areanode_t *node )
{
	int			i, numtouch;
	edict_t		*touchlist[MAX_EDICTS], *touch;
	int			old_self, old_other;

	numtouch = SV_AreaEdicts (ent->v.absmin, ent->v.absmax, touchlist, MAX_EDICTS, AREA_TRIGGERS);

// touch linked edicts
	for (i = 0; i < numtouch; i++)
	{
		touch = touchlist[i];
		if (touch == ent)
			continue;
		if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER)
			continue;

		old_self = pr_global_struct->self;
		old_other = pr_global_struct->other;

		pr_global_struct->self = EDICT_TO_PROG(touch);
		pr_global_struct->other = EDICT_TO_PROG(ent);
		pr_global_struct->time = sv.time;
		PR_ExecuteProgram (touch->v.touch);

		pr_global_struct->self = old_self;
		pr_global_struct->other = old_other;
	}
}
Beispiel #4
0
/*
 * Call after linking a new trigger
 * in during gameplay to force all
 * entities it covers to immediately
 * touch it
 */
void G_TouchSolids(edict_t *ent)
{
  int i, num;
  edict_t *touch[MAX_EDICTS], *hit;

  if (!ent) {
    return;
  }

  num = SV_AreaEdicts(ent->absmin, ent->absmax, touch, MAX_EDICTS, AREA_SOLID);

  /* be careful, it is possible to have an entity in this
     list removed before we get to it (killtriggered) */
  for (i = 0; i < num; i++) {
    hit = touch[i];

    if (!hit->inuse) {
      continue;
    }

    if (ent->touch) {
      ent->touch(hit, ent, NULL, NULL);
    }

    if (!ent->inuse) {
      break;
    }
  }
}
Beispiel #5
0
void G_TouchTriggers(edict_t *ent)
{
  int i, num;
  edict_t *touch[MAX_EDICTS], *hit;

  if (!ent) {
    return;
  }

  /* dead things don't activate triggers! */
  if ((ent->client || (ent->svflags & SVF_MONSTER)) && (ent->health <= 0)) {
    return;
  }

  num = SV_AreaEdicts(ent->absmin, ent->absmax, touch, MAX_EDICTS, AREA_TRIGGERS);

  /* be careful, it is possible to have an entity in this
     list removed before we get to it (killtriggered) */
  for (i = 0; i < num; i++) {
    hit = touch[i];

    if (!hit->inuse) {
      continue;
    }

    if (!hit->touch) {
      continue;
    }

    hit->touch(hit, ent, NULL, NULL);
  }
}
Beispiel #6
0
/*
=============
SV_PointContents
=============
*/
int SV_PointContents(vec3_t p)
{
    edict_t     *touch[MAX_EDICTS], *hit;
    int         i, num;
    int         contents;

    if (!sv.cm.cache) {
        Com_Error(ERR_DROP, "%s: no map loaded", __func__);
    }

    // get base contents from world
    contents = CM_PointContents(p, sv.cm.cache->nodes);

    // or in contents from all the other entities
    num = SV_AreaEdicts(p, p, touch, MAX_EDICTS, AREA_SOLID);

    for (i = 0; i < num; i++) {
        hit = touch[i];

        // might intersect, so do an exact clip
        contents |= CM_TransformedPointContents(p, SV_HullForEntity(hit),
                                                hit->s.origin, hit->s.angles);
    }

    return contents;
}
Beispiel #7
0
/*
 * ==================== SV_ClipMoveToEntities
 *
 * ====================
 */
void
SV_ClipMoveToEntities(moveclip_t * clip)
{
	int		i, num;
	edict_t        *touchlist[MAX_EDICTS], *touch;
	trace_t		trace;
	int		headnode;
	float          *angles;

	num = SV_AreaEdicts(clip->boxmins, clip->boxmaxs, touchlist
	    ,MAX_EDICTS, AREA_SOLID);

	/* be careful, it is possible to have an entity in this */
	/* list removed before we get to it (killtriggered) */
	for (i = 0; i < num; i++) {
		touch = touchlist[i];
		if (touch->solid == SOLID_NOT)
			continue;
		if (touch == clip->passedict)
			continue;
		if (clip->trace.allsolid)
			return;
		if (clip->passedict) {
			if (touch->owner == clip->passedict)
				continue;	/* don't clip against own
						 * missiles */
			if (clip->passedict->owner == touch)
				continue;	/* don't clip against owner */
		}
		if (!(clip->contentmask & CONTENTS_DEADMONSTER)
		    && (touch->svflags & SVF_DEADMONSTER))
			continue;

		/* might intersect, so do an exact clip */
		headnode = SV_HullForEntity(touch);
		angles = touch->s.angles;
		if (touch->solid != SOLID_BSP)
			angles = vec3_origin;	/* boxes don't rotate */

		if (touch->svflags & SVF_MONSTER)
			trace = CM_TransformedBoxTrace(clip->start, clip->end,
			    clip->mins2, clip->maxs2, headnode, clip->contentmask,
			    touch->s.origin, angles);
		else
			trace = CM_TransformedBoxTrace(clip->start, clip->end,
			    clip->mins, clip->maxs, headnode, clip->contentmask,
			    touch->s.origin, angles);

		if (trace.allsolid || trace.startsolid ||
		    trace.fraction < clip->trace.fraction) {
			trace.ent = touch;
			if (clip->trace.startsolid) {
				clip->trace = trace;
				clip->trace.startsolid = true;
			} else
				clip->trace = trace;
		} else if (trace.startsolid)
			clip->trace.startsolid = true;
	}
}
Beispiel #8
0
/*
====================
SV_ClipToLinks

Mins and maxs enclose the entire area swept by the move
====================
*/
void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
{
	int			i, numtouch;
	edict_t		*touchlist[MAX_EDICTS], *touch;
	trace_t		trace;

	numtouch = SV_AreaEdicts (clip->boxmins, clip->boxmaxs, touchlist, MAX_EDICTS, AREA_SOLID);

// touch linked edicts
	for (i = 0; i < numtouch; i++)
	{
		touch = touchlist[i];
		if (touch == clip->passedict)
			continue;
		if (touch->v.solid == SOLID_TRIGGER)
			Host_Error ("Trigger in clipping list");

		if (clip->type == MOVE_NOMONSTERS && touch->v.solid != SOLID_BSP)
			continue;

		if (clip->passedict && clip->passedict->v.size[0] && !touch->v.size[0])
			continue;	// points never interact

	// might intersect, so do an exact clip
		if (clip->trace.allsolid)
			return;
		if (clip->passedict)
		{
		 	if (PROG_TO_EDICT(touch->v.owner) == clip->passedict)
				continue;	// don't clip against own missiles
			if (PROG_TO_EDICT(clip->passedict->v.owner) == touch)
				continue;	// don't clip against owner
		}

		if ((int)touch->v.flags & FL_MONSTER)
			trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);
		else
			trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end);
		if (trace.allsolid || trace.startsolid ||
		trace.fraction < clip->trace.fraction)
		{
			trace.e.ent = touch;
		 	if (clip->trace.startsolid)
			{
				clip->trace = trace;
				clip->trace.startsolid = true;
			}
			else
				clip->trace = trace;
		}
		else if (trace.startsolid)
			clip->trace.startsolid = true;
	}
}
Beispiel #9
0
/*
====================
SV_ClipMoveToEntities

====================
*/
static void SV_ClipMoveToEntities(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end,
                                  edict_t *passedict, int contentmask, trace_t *tr)
{
    vec3_t      boxmins, boxmaxs;
    int         i, num;
    edict_t     *touchlist[MAX_EDICTS], *touch;
    trace_t     trace;

    // create the bounding box of the entire move
    for (i = 0; i < 3; i++) {
        if (end[i] > start[i]) {
            boxmins[i] = start[i] + mins[i] - 1;
            boxmaxs[i] = end[i] + maxs[i] + 1;
        } else {
            boxmins[i] = end[i] + mins[i] - 1;
            boxmaxs[i] = start[i] + maxs[i] + 1;
        }
    }

    num = SV_AreaEdicts(boxmins, boxmaxs, touchlist, MAX_EDICTS, AREA_SOLID);

    // be careful, it is possible to have an entity in this
    // list removed before we get to it (killtriggered)
    for (i = 0; i < num; i++) {
        touch = touchlist[i];
        if (touch->solid == SOLID_NOT)
            continue;
        if (touch == passedict)
            continue;
        if (tr->allsolid)
            return;
        if (passedict) {
            if (touch->owner == passedict)
                continue;    // don't clip against own missiles
            if (passedict->owner == touch)
                continue;    // don't clip against owner
        }

        if (!(contentmask & CONTENTS_DEADMONSTER)
            && (touch->svflags & SVF_DEADMONSTER))
            continue;

        // might intersect, so do an exact clip
        CM_TransformedBoxTrace(&trace, start, end, mins, maxs,
                               SV_HullForEntity(touch), contentmask,
                               touch->s.origin, touch->s.angles);

        CM_ClipEntity(tr, &trace, touch);
    }
}
Beispiel #10
0
static void SV_ClipMoveToEntities(trace_t &trace, const CVec3 &start, const CVec3 &end, const CBox &bounds, edict_t *passedict, int contentmask)
{
	guard(SV_ClipMoveToEntities);

	if (trace.allsolid) return;

	int		i;

	CVec3 amins, amaxs;
	for (i = 0; i < 3; i++)
	{
		if (start[i] < end[i])
		{
			amins[i] = bounds.mins[i] + start[i];
			amaxs[i] = bounds.maxs[i] + end[i];
		}
		else
		{
			amins[i] = bounds.mins[i] + end[i];
			amaxs[i] = bounds.maxs[i] + start[i];
		}
	}
	edict_t	*list[MAX_EDICTS];
	int num = SV_AreaEdicts(amins, amaxs, ARRAY_ARG(list), AREA_SOLID);
	if (!num) return;

	float b1 = dot(bounds.mins, bounds.mins);
	float b2 = dot(bounds.maxs, bounds.maxs);
	float t = max(b1, b2);
	float traceWidth = SQRTFAST(t);
	CVec3 traceDir;
	VectorSubtract(end, start, traceDir);
	float traceLen = traceDir.Normalize() + traceWidth;

	for (i = 0; i < num; i++)
	{
		edict_t *edict = list[i];
		entityHull_t &ent = ents[NUM_FOR_EDICT(edict)];
//		if (!ent->linked) continue;

		if (edict->solid == SOLID_NOT || edict == passedict) continue;
		if (passedict)
		{
		 	if (edict->owner == passedict)
				continue;	// don't clip against own missiles
			if (passedict->owner == edict)
				continue;	// don't clip against owner
		}
		if (!(contentmask & CONTENTS_DEADMONSTER) && (edict->svflags & SVF_DEADMONSTER))
			continue;

		CVec3 eCenter;
		VectorSubtract(ent.center, start, eCenter);
		// check position of point projection on line
		float entPos = dot(eCenter, traceDir);
		if (entPos < -traceWidth - ent.radius || entPos > traceLen + ent.radius)
			continue;		// too near / too far

		// check distance between point and line
		CVec3 tmp;
		VectorMA(eCenter, -entPos, traceDir, tmp);
		float dist2 = dot(tmp, tmp);
		float dist0 = ent.radius + traceWidth;
		if (dist2 >= dist0 * dist0) continue;

		trace_t	tr;
		if (ent.model)
			CM_TransformedBoxTrace(tr, start, end, bounds, ent.model->headnode, contentmask, edict->s.origin, ent.axis);
		else
			CM_TransformedBoxTrace(tr, start, end, bounds, CM_HeadnodeForBox(ent.bounds), contentmask, edict->s.origin, nullVec3);
		if (CM_CombineTrace(trace, tr))
			trace.ent = edict;
		if (trace.allsolid) return;
	}

	unguard;
}