示例#1
0
// Get the sighted location
//
void
GetSightedLocation (edict_t * self, char *buf)
{
  vec3_t start, forward, right, end, up, offset;
  int xo, yo, zo;
  trace_t tr;

  AngleVectors (self->client->v_angle, forward, right, up);

  VectorSet (offset, 24, 8, self->viewheight);
  P_ProjectSource (self->client, self->s.origin, offset, forward, right,
		   start);
  VectorMA (start, 8192, forward, end);

  PRETRACE ();
  tr =
    gi.trace (start, NULL, NULL, end, self,
	      CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_DEADMONSTER);
  POSTTRACE ();

  xo = tr.endpos[0];
  yo = tr.endpos[1];
  zo = tr.endpos[2];

  GetLocation (xo, yo, zo, 10, buf);
}
示例#2
0
qboolean loc_CanSee(edict_t * targ, edict_t * inflictor)
{
    trace_t trace;
    vec3_t targpoints[8];
    int i;
    vec3_t viewpoint;

// bmodels need special checking because their origin is 0,0,0
    if (targ->movetype == MOVETYPE_PUSH)
        return false;	// bmodels not supported

    loc_buildboxpoints(targpoints, targ->s.origin, targ->mins, targ->maxs);

    VectorCopy(inflictor->s.origin, viewpoint);
    viewpoint[2] += inflictor->viewheight;

    for (i = 0; i < 8; i++) {
        PRETRACE();
        trace = gi.trace(viewpoint, vec3_origin, vec3_origin, targpoints[i], inflictor, MASK_SOLID);
        POSTTRACE();
        if (trace.fraction == 1.0)
            return true;
    }

    return false;
}
示例#3
0
//updated
void LaserLinkThink (edict_t *laser)
{
	edict_t *node = NULL;
	vec3_t  start;
	vec3_t  end;
	trace_t tr;

	if (!laser->enemy)
	{
		node = FindEdictByClassnumAndMass("LaserTrailLink", laser->classnum-1, laser->mass);
		if (node)
			laser->enemy = node;
		else
			laser->enemy = laser;
	}

	VectorCopy (laser->s.origin, start);
	VectorMA (start, 0, laser->movedir, end);

	PRETRACE();
	tr = gi.trace (start, NULL, NULL, laser->enemy->s.origin, NULL /*ignore*/ , /*MASK_SOLID);//*/ MASK_PLAYERSOLID);
	POSTTRACE();

	//HERE FOR TRAIL FLASHES
	if (tr.ent->client)
	{
		tr.ent->client->resp.intblend = laser->s.skinnum;
		tr.ent->client->resp.trailtouch = laser->mass;
	}

	VectorCopy (tr.endpos, laser->s.old_origin);

	laser->nextthink = level.time + FRAMETIME;
}
示例#4
0
edict_t *GetIDView(edict_t *ent)
{
	vec3_t		forward,	dir;
	trace_t		tr;
	edict_t		*who,		*best;
	float		bd = 0.9,	d;
	int			i;

	if ((ent->client->chase_mode) && (ent->client->chase_target))
		return ent->client->chase_target;
	
	AngleVectors(ent->client->v_angle, forward, NULL, NULL);
	VectorScale(forward, 8192, forward);
	VectorAdd(ent->s.origin, forward, forward);
	PRETRACE();
	tr = gi.trace(ent->s.origin, NULL, NULL, forward, ent, MASK_PLAYERSOLID);
	POSTTRACE();

	AngleVectors(ent->client->v_angle, forward, NULL, NULL);
	best = NULL;
	for (i = 1; i <= maxclients->value; i++) {

		who = g_edicts + i;
		if (!who->inuse)
			continue;

		//check for player
		VectorSubtract(who->s.origin, ent->s.origin, dir);
		VectorNormalize(dir);
		d = DotProduct(forward, dir);

		if (d > bd && loc_CanSee(ent, who))// && 
		{
			//FIREBLADE
			bd = d;
			best = who;
		}

		//check for puppet
		if (ent->client->puppet)
		{
			VectorSubtract(ent->client->puppet->s.origin, ent->s.origin, dir);
			VectorNormalize(dir);
			d = DotProduct(forward, dir);

			if (d > bd && loc_CanSee(ent, ent->client->puppet))
			{
				//FIREBLADE
				bd = d;
				best = ent->client->puppet;
			}
		}
	}

	if ((best != NULL) && (bd > 0.90))
		return best;
	else
		return NULL;
}
示例#5
0
// DetermineViewedTeammate: determine the current player you're viewing (only looks for live teammates)
// Modified from SetIDView (which was used from Zoid's CTF)
edict_t *DetermineViewedTeammate (edict_t * ent)
{
	vec3_t forward, dir;
	trace_t tr;
	edict_t *who, *best;
	//FIREBLADE, suggested by hal[9k]  3/11/1999
	float bd = 0.9f;
	//FIREBLADE
	float d;
	int i;

	AngleVectors (ent->client->v_angle, forward, NULL, NULL);
	VectorScale (forward, 8192, forward);
	VectorAdd (ent->s.origin, forward, forward);
	PRETRACE ();
	tr = gi.trace (ent->s.origin, NULL, NULL, forward, ent, MASK_SOLID);
	POSTTRACE ();
	if (tr.fraction < 1 && tr.ent && tr.ent->client)
	{
		return NULL;
	}

	AngleVectors (ent->client->v_angle, forward, NULL, NULL);
	best = NULL;
	for (i = 1; i <= maxclients->value; i++)
	{
		who = g_edicts + i;
		if (!who->inuse)
			continue;
		VectorSubtract (who->s.origin, ent->s.origin, dir);
		VectorNormalize (dir);
		d = DotProduct (forward, dir);
		if (d > bd && loc_CanSee (ent, who) && who->solid != SOLID_NOT &&
			who->deadflag != DEAD_DEAD && OnSameTeam (who, ent))
		{
			bd = d;
			best = who;
		}
	}

	if (bd > 0.90)
	{
		return best;
	}

	return NULL;
}
示例#6
0
/*
============
SV_PushEntity

Does not change the entities velocity at all
============
*/
trace_t
SV_PushEntity (edict_t * ent, vec3_t push)
{
  trace_t trace;
  vec3_t start;
  vec3_t end;
  int mask;

  VectorCopy (ent->s.origin, start);
  VectorAdd (start, push, end);

retry:
  if (ent->clipmask)
    mask = ent->clipmask;
  else
    mask = MASK_SOLID;

  PRETRACE ();
  trace = gi.trace (start, ent->mins, ent->maxs, end, ent, mask);
  POSTTRACE ();

  VectorCopy (trace.endpos, ent->s.origin);
  gi.linkentity (ent);

  if (trace.fraction != 1.0)
    {
      SV_Impact (ent, &trace);

      // if the pushed entity went away and the pusher is still there
      if (!trace.ent->inuse && ent->inuse)
	{
	  // move the pusher back and try again
	  VectorCopy (start, ent->s.origin);
	  gi.linkentity (ent);
	  goto retry;
	}
    }

  if (ent->inuse)
    G_TouchTriggers (ent);

  return trace;
}
示例#7
0
/*
============
SV_TestEntityPosition

============
*/
edict_t *
SV_TestEntityPosition (edict_t * ent)
{
  trace_t trace;
  int mask;

  if (ent->clipmask)
    mask = ent->clipmask;
  else
    mask = MASK_SOLID;
  PRETRACE ();
  trace =
    gi.trace (ent->s.origin, ent->mins, ent->maxs, ent->s.origin, ent, mask);
  POSTTRACE ();

  if (trace.startsolid)
    return g_edicts;

  return NULL;
}
示例#8
0
void LaserSightThink(edict_t * self)
{
    vec3_t start, end, endp, offset;
    vec3_t forward, right, up, angles;
    trace_t tr;
    int height = 0;

    // zucc compensate for weapon ride up
    VectorAdd(self->owner->client->v_angle, self->owner->client->kick_angles, angles);
    AngleVectors(angles, forward, right, up);

    if (self->owner->lasersight != self) {
        self->think = G_FreeEdict;
    }

    if (self->owner->client->pers.firing_style == ACTION_FIRING_CLASSIC)
        height = 8;

    VectorSet(offset, 24, 8, self->owner->viewheight - height);
    P_ProjectSource(self->owner->client, self->owner->s.origin, offset, forward, right, start);
    VectorMA(start, 8192, forward, end);

    PRETRACE();
    tr = gi.trace(start, NULL, NULL, end, self->owner, CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_DEADMONSTER);
    POSTTRACE();

    if (tr.fraction != 1) {
        VectorMA(tr.endpos, -4, forward, endp);
        VectorCopy(endp, tr.endpos);
    }

    vectoangles(tr.plane.normal, self->s.angles);
    VectorCopy(tr.endpos, self->s.origin);
    gi.linkentity(self);
    self->nextthink = level.time + 0.1;
}
示例#9
0
void UpdateChaseCam( edict_t * ent )
{
	vec3_t o, ownerv, goal;
	edict_t *targ;
	vec3_t forward, right, angles;
	trace_t trace;
	int i;
	gclient_t *client;
	short oldStats[MAX_STATS];

	if (ChaseTargetGone( ent ))
		return;

	client = ent->client;

	targ = client->resp.last_chase_target = client->chase_target;

	memcpy(oldStats, client->ps.stats, sizeof(oldStats));

	if (client->chase_mode == 1)
	{
		VectorCopy( targ->s.origin, ownerv );

		ownerv[2] += targ->viewheight;

		VectorCopy(client->resp.cmd_angles, angles);
		for (i = 0; i < 3; i++)
			 angles[i] += SHORT2ANGLE(client->ps.pmove.delta_angles[i]);

		AngleVectors( angles, forward, right, NULL );
		VectorNormalize( forward );
		VectorMA( ownerv, -150, forward, o );

		// jump animation lifts
		if (!targ->groundentity)
			o[2] += 16;

		PRETRACE();
		trace = gi.trace( ownerv, vec3_origin, vec3_origin, o, targ, MASK_SOLID );

		VectorCopy( trace.endpos, goal );

		VectorMA( goal, 2, forward, goal );

		// pad for floors and ceilings
		VectorCopy( goal, o );
		o[2] += 6;
		trace = gi.trace( goal, vec3_origin, vec3_origin, o, targ, MASK_SOLID );
		if (trace.fraction < 1) {
			VectorCopy( trace.endpos, goal );
			goal[2] -= 6;
		}

		VectorCopy( goal, o );
		o[2] -= 6;
		trace = gi.trace( goal, vec3_origin, vec3_origin, o, targ, MASK_SOLID );
		POSTTRACE();
		if (trace.fraction < 1) {
			VectorCopy( trace.endpos, goal );
			goal[2] += 6;
		}

		if (targ->deadflag)
			client->ps.pmove.pm_type = PM_DEAD;
		else
			client->ps.pmove.pm_type = PM_FREEZE;

		VectorCopy(goal, ent->s.origin);
		VectorScale(goal, 8, client->ps.pmove.origin);

		for (i = 0; i < 3; i++) {
			client->ps.pmove.delta_angles[i] = ANGLE2SHORT(angles[i] - client->resp.cmd_angles[i]);
		}
		VectorCopy(angles, client->ps.viewangles);
		VectorCopy(angles, client->v_angle);

		client->clientNum = ent - g_edicts - 1;
		client->ps.gunindex = client->ps.gunframe = 0;
		client->desired_fov = 90;
		client->ps.fov = 90;

		ent->viewheight = 0;
		memcpy(client->ps.stats, targ->client->ps.stats, sizeof(client->ps.stats));
		client->ps.stats[STAT_SNIPER_ICON] = 0; // only show sniper lens when in chase mode 2
		if( client->ps.stats[STAT_HELPICON] != level.pic_health ) // Keep bandaging icon.
			client->ps.stats[STAT_HELPICON] = 0; // No weapon icon in 3rd person chase.
	}
	else             // chase_mode == 2
	{

		VectorCopy( targ->client->v_angle, angles );

		if (!(game.serverfeatures & GMF_CLIENTNUM))
		{
			VectorCopy( targ->s.origin, ownerv );
			ownerv[2] += targ->viewheight;

			AngleVectors( angles, forward, right, NULL );
			VectorNormalize( forward );
			VectorMA( ownerv, 11, forward, o );

			VectorCopy(o, ent->s.origin);
			VectorScale(o, 8, client->ps.pmove.origin);

			if (targ->deadflag)
			{
				client->ps.viewangles[ROLL] = 40;
				client->ps.viewangles[PITCH] = -15;
				client->ps.viewangles[YAW] = targ->client->killer_yaw;
				client->ps.pmove.pm_type = PM_DEAD;
			}
			else
			{
				VectorCopy(targ->client->ps.kick_angles, client->ps.kick_angles);
				for (i = 0; i < 3; i++) {
					ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(angles[i] - client->resp.cmd_angles[i]);
				}
				VectorCopy(angles, client->ps.viewangles);
				VectorCopy(angles, client->v_angle);
				client->ps.pmove.pm_type = PM_FREEZE;
			}

			ent->viewheight = 0;
			memcpy(client->ps.stats, targ->client->ps.stats, sizeof(client->ps.stats));
		}
		else
		{
			i = client->ps.pmove.pm_flags & PMF_JUMP_HELD;
			client->ps = targ->client->ps;

			VectorCopy(client->ps.viewangles, ent->s.angles);
			VectorCopy(client->ps.viewangles, client->v_angle);
			VectorScale(client->ps.pmove.origin, 0.125f, ent->s.origin);
			ent->viewheight = targ->viewheight;

			client->ps.pmove.pm_flags &= ~PMF_JUMP_HELD;
			client->ps.pmove.pm_flags |= i;
			client->ps.pmove.pm_type = PM_FREEZE;
		}

		ent->client->clientNum = targ - g_edicts - 1;
		ent->client->ps.fov = targ->client->ps.fov;
		ent->client->desired_fov = targ->client->ps.fov;

		// Keep bandaging icon from stats, but weapon icon is based on observer's hand and fov.
		if( client->ps.stats[STAT_HELPICON] == level.pic_health )
			;
		else if( (client->pers.hand == CENTER_HANDED || client->ps.fov > 91) && targ->client->weapon )
			client->ps.stats[STAT_HELPICON] = level.pic_items[targ->client->weapon->typeNum];
		else
			client->ps.stats[STAT_HELPICON] = 0;
	}

	//protect these
	for (i = STAT_TEAM_HEADER; i <= STAT_TEAM2_SCORE; i++) {
		client->ps.stats[i] = oldStats[i];
	}
	client->ps.stats[STAT_TEAM3_PIC] = oldStats[STAT_TEAM3_PIC];
	client->ps.stats[STAT_TEAM3_SCORE] = oldStats[STAT_TEAM3_SCORE];
	client->ps.stats[STAT_LAYOUTS] = oldStats[STAT_LAYOUTS];
	client->ps.stats[STAT_ID_VIEW] = oldStats[STAT_ID_VIEW];
	client->ps.stats[STAT_FRAGS] = oldStats[STAT_FRAGS];

	client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
	gi.linkentity( ent );
}
示例#10
0
文件: g_combat.c 项目: andrijan/ajaq
/*
  ============
  CanDamage
  
  Returns true if the inflictor can directly damage the target.  Used for
  explosions and melee attacks.
  ============
*/
qboolean CanDamage (edict_t * targ, edict_t * inflictor)
{
	vec3_t dest;
	trace_t trace;

	// bmodels need special checking because their origin is 0,0,0
	//GLASS FX
	if ((targ->movetype == MOVETYPE_PUSH) ||
	((targ->movetype == MOVETYPE_FLYMISSILE)
	&& (0 == Q_stricmp ("func_explosive", targ->classname))))
	//GLASS FX
	{
		VectorAdd (targ->absmin, targ->absmax, dest);
		VectorScale (dest, 0.5, dest);
		PRETRACE ();
		trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest,
			inflictor, MASK_SOLID);
		POSTTRACE ();
		if (trace.fraction == 1.0)
			return true;
		if (trace.ent == targ)
			return true;
		return false;
	}

	PRETRACE ();
	trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, targ->s.origin,
		inflictor, MASK_SOLID);
	POSTTRACE ();
	if (trace.fraction == 1.0)
		return true;

	VectorCopy (targ->s.origin, dest);
	dest[0] += 15.0;
	dest[1] += 15.0;
	PRETRACE ();
	trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor,
		MASK_SOLID);
	POSTTRACE ();
	if (trace.fraction == 1.0)
		return true;

	VectorCopy (targ->s.origin, dest);
	dest[0] += 15.0;
	dest[1] -= 15.0;
	PRETRACE ();
	trace =	gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor,
		MASK_SOLID);
	POSTTRACE ();
	if (trace.fraction == 1.0)
		return true;

	VectorCopy (targ->s.origin, dest);
	dest[0] -= 15.0;
	dest[1] += 15.0;
	PRETRACE ();
	trace = gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor,
		MASK_SOLID);
	POSTTRACE ();
	if (trace.fraction == 1.0)
		return true;

	VectorCopy (targ->s.origin, dest);
	dest[0] -= 15.0;
	dest[1] -= 15.0;
	PRETRACE ();
	trace =	gi.trace (inflictor->s.origin, vec3_origin, vec3_origin, dest, inflictor,
		MASK_SOLID);
	POSTTRACE ();
	if (trace.fraction == 1.0)
		return true;

	return false;
}
示例#11
0
// originally from Zoid's CTF
void SetIDView(edict_t * ent)
{
    vec3_t forward, dir;
    trace_t tr;
    edict_t *who, *best;
//FIREBLADE, suggested by hal[9k]  3/11/1999
    float bd = 0.9f;
    float d;
    int i;

    ent->client->ps.stats[STAT_ID_VIEW] = 0;

//FIREBLADE
    if (ent->solid != SOLID_NOT && !teamplay->value) {
        if (!((int) (dmflags->value) & (DF_MODELTEAMS | DF_SKINTEAMS)))
            return;	// won't ever work in non-teams so don't run the code...

    }

    if (ent->client->chase_mode) {
        if (ent->client->chase_target && ent->client->chase_target->inuse) {
            ent->client->ps.stats[STAT_ID_VIEW] =
                CS_PLAYERSKINS + (ent->client->chase_target - g_edicts - 1);
        }
        return;
    }
//FIREBLADE

    if (ent->client->resp.id == 1)
        return;

    AngleVectors(ent->client->v_angle, forward, NULL, NULL);
    VectorScale(forward, 8192, forward);
    VectorAdd(ent->s.origin, forward, forward);
    PRETRACE();
    tr = gi.trace(ent->s.origin, NULL, NULL, forward, ent, MASK_SOLID);
    POSTTRACE();
    if (tr.fraction < 1 && tr.ent && tr.ent->client) {
        ent->client->ps.stats[STAT_ID_VIEW] = CS_PLAYERSKINS + (ent - g_edicts - 1);
        return;
    }

    AngleVectors(ent->client->v_angle, forward, NULL, NULL);
    best = NULL;
    for (i = 1; i <= maxclients->value; i++) {
        who = g_edicts + i;
        if (!who->inuse)
            continue;
        VectorSubtract(who->s.origin, ent->s.origin, dir);
        VectorNormalize(dir);
        d = DotProduct(forward, dir);
        if (d > bd && loc_CanSee(ent, who) &&
//FIREBLADE
                (who->solid != SOLID_NOT || who->deadflag == DEAD_DEAD) &&
                (ent->solid == SOLID_NOT || OnSameTeam(ent, who))) {
//FIREBLADE
            bd = d;
            best = who;
        }
    }
    if (best != NULL && bd > 0.90) {
        ent->client->ps.stats[STAT_ID_VIEW] = CS_PLAYERSKINS + (best - g_edicts - 1);
    }
}
示例#12
0
文件: g_chase.c 项目: basecq/q2dos
void UpdateChaseCam(edict_t *ent)
{
        vec3_t o, ownerv, goal;
        edict_t *targ;
        vec3_t forward, right;
        trace_t trace;
        int i;
        vec3_t angles;

        if (ChaseTargetGone(ent))
                return;

        targ = ent->client->resp.last_chase_target = ent->client->chase_target;

        if (ent->client->chase_mode == 1)
        {
                ent->client->desired_fov = 90;
                ent->client->ps.fov = 90;

                if (ent->client->resp.cmd_angles[PITCH] > 89)
                        ent->client->resp.cmd_angles[PITCH] = 89;
                if (ent->client->resp.cmd_angles[PITCH] < -89)
                        ent->client->resp.cmd_angles[PITCH] = -89;

                VectorCopy(targ->s.origin, ownerv);

                ownerv[2] += targ->viewheight;

                VectorCopy(ent->client->ps.viewangles, angles);
                AngleVectors (angles, forward, right, NULL);
                VectorNormalize(forward);
                VectorMA(ownerv, -150, forward, o);

// not sure if this should be left in... -FB
//              if (o[2] < targ->s.origin[2] + 20)  
//                      o[2] = targ->s.origin[2] + 20;

                // jump animation lifts
                if (!targ->groundentity)
                        o[2] += 16;

                PRETRACE();
                trace = gi.trace(ownerv, vec3_origin, vec3_origin, o, targ, MASK_SOLID);        
                POSTTRACE();
 
                VectorCopy(trace.endpos, goal);

                VectorMA(goal, 2, forward, goal);

                // pad for floors and ceilings
                VectorCopy(goal, o);
                o[2] += 6;
                PRETRACE();
                trace = gi.trace(goal, vec3_origin, vec3_origin, o, targ, MASK_SOLID);
                POSTTRACE();
                if (trace.fraction < 1) {
                        VectorCopy(trace.endpos, goal);
                        goal[2] -= 6;
                }

                VectorCopy(goal, o);
                o[2] -= 6;
                PRETRACE();
                trace = gi.trace(goal, vec3_origin, vec3_origin, o, targ, MASK_SOLID);
                POSTTRACE();
                if (trace.fraction < 1) {
                        VectorCopy(trace.endpos, goal);
                        goal[2] += 6;
                }

                if (targ->deadflag)
                        ent->client->ps.pmove.pm_type = PM_DEAD;
                else
                        ent->client->ps.pmove.pm_type = PM_FREEZE;              
 
                VectorCopy(goal, ent->s.origin);

                for (i=0 ; i<3 ; i++)
                        ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(ent->client->v_angle[i] - ent->client->resp.cmd_angles[i]);

                VectorCopy(ent->client->resp.cmd_angles, ent->client->ps.viewangles);
        }
                else // chase_mode == 2
        {
                VectorCopy(targ->s.origin, ownerv);
                VectorCopy(targ->client->v_angle, angles);

                AngleVectors (angles, forward, right, NULL);
                VectorNormalize(forward);
                VectorMA(ownerv, 16, forward, o);

                o[2] += targ->viewheight;

                VectorCopy(o, ent->s.origin);

                ent->client->ps.fov = targ->client->ps.fov;
                ent->client->desired_fov = targ->client->ps.fov;

                for (i=0 ; i<3 ; i++)
                        ent->client->ps.pmove.delta_angles[i] = ANGLE2SHORT(targ->client->v_angle[i] - ent->client->resp.cmd_angles[i]);

                if (targ->deadflag)
                {
                        ent->client->ps.viewangles[ROLL] = 40;
                        ent->client->ps.viewangles[PITCH] = -15;
                        ent->client->ps.viewangles[YAW] = targ->client->killer_yaw;
                }
                        else 
                {
                        VectorAdd(targ->client->v_angle,
                                targ->client->ps.kick_angles,
                                angles);
                        VectorCopy(angles, ent->client->ps.viewangles);
                        VectorCopy(angles, ent->client->v_angle);
                }
        }       

        ent->viewheight = 0;
        ent->client->ps.pmove.pm_flags |= PMF_NO_PREDICTION;
        gi.linkentity(ent);
}
示例#13
0
文件: a_doorkick.c 项目: basecq/q2dos
int KickDoor( trace_t *tr_old, edict_t *ent, vec3_t forward )
{
  trace_t tr;
  
  vec3_t d_forward, right, end;
  float d;
  if ( !Q_strcasecmp( tr_old->ent->classname, "func_door_rotating" ) )
  {
    // Make that the door is closed
    
    tr = *tr_old;
#if 1
    if ( (!(tr.ent->spawnflags & DOOR_START_OPEN) &&
          !(tr.ent->moveinfo.state == STATE_TOP)) ||
          ( (tr.ent->spawnflags & DOOR_START_OPEN) &&
           !(tr.ent->moveinfo.state == STATE_BOTTOM)) )
#else
    if ( (!(tr.ent->spawnflags & DOOR_START_OPEN) &&
      ((tr.ent->moveinfo.state == STATE_BOTTOM) ||
      (tr.ent->moveinfo.state == STATE_DOWN))) ||
      ((tr.ent->spawnflags & DOOR_START_OPEN) &&
      ((tr.ent->moveinfo.state == STATE_TOP) ||
      (tr.ent->moveinfo.state == STATE_UP))) )
#endif
    {
      //gi.dprintf( "Kicking a closed door\n" );
      
      // Find out if we are on the "outside"
      
#if 0
      gi.WriteByte (svc_temp_entity);
      gi.WriteByte (TE_RAILTRAIL);
      gi.WritePosition (tr.ent->s.origin);
      gi.WritePosition (tr.endpos);
      gi.multicast (tr.ent->s.origin, MULTICAST_PHS);
#endif
      VectorSubtract( tr.endpos, tr.ent->s.origin, d_forward );
      
      forward[2] = 0;
      d_forward[2] = 0;
      VectorNormalize( forward );
      VectorNormalize( d_forward );
      VectorSet( right, 0, 90, 0 );
      VectorRotate( d_forward, right, d_forward );
      
      d = DotProduct( forward, d_forward );
      if ( tr.ent->spawnflags & DOOR_REVERSE )
        d = -d;
      // d = sin( acos( d ) );
      if ( d > 0.0 )
      {
        // gi.dprintf( "we think we are on the outside\n" );
        //if ( tr.ent->spawnflags & DOOR_REVERSE )
        //  gi.dprintf( "but DOOR_REVERSE is set\n" );
        // Only use the door if it's not already opening
        if ( (!( tr.ent->spawnflags & DOOR_START_OPEN ) &&  
               !( tr.ent->moveinfo.state == STATE_UP )) ||
               ((tr.ent->spawnflags & DOOR_START_OPEN ) &&
                (tr.ent->moveinfo.state == STATE_DOWN) ) )
          door_use( tr.ent, ent, ent );
        // Find out if someone else is on the other side
        VectorMA( tr.endpos, 25, forward, end );
	PRETRACE();
        tr = gi.trace (tr.endpos, NULL, NULL, end, tr.ent, MASK_SHOT);
	POSTTRACE();
        if (!((tr.surface) && (tr.surface->flags & SURF_SKY)))    
        {
          if (tr.fraction < 1.0)        
          {            
            if (tr.ent->client)            
            {
              //gi.dprintf(DEVELOPER_MSG_GAME, "we found a client on the other side\n");
              *tr_old = tr;
              return( 1 );
            }
          }
        }
      }
      
    }
  }

  return( 0 );
}
示例#14
0
int
SV_FlyMove (edict_t * ent, float time, int mask)
{
  edict_t *hit;
  int bumpcount, numbumps;
  vec3_t dir;
  float d;
  int numplanes;
  vec3_t planes[MAX_CLIP_PLANES];
  vec3_t primal_velocity, original_velocity, new_velocity;
  int i, j;
  trace_t trace;
  vec3_t end;
  float time_left;
  int blocked;

  numbumps = 4;

  blocked = 0;
  VectorCopy (ent->velocity, original_velocity);
  VectorCopy (ent->velocity, primal_velocity);
  numplanes = 0;

  time_left = time;

  ent->groundentity = NULL;
  for (bumpcount = 0; bumpcount < numbumps; bumpcount++)
    {
      for (i = 0; i < 3; i++)
	end[i] = ent->s.origin[i] + time_left * ent->velocity[i];

      PRETRACE ();
      trace = gi.trace (ent->s.origin, ent->mins, ent->maxs, end, ent, mask);
      POSTTRACE ();

      if (trace.allsolid)
	{			// entity is trapped in another solid
	  VectorCopy (vec3_origin, ent->velocity);
	  return 3;
	}

      if (trace.fraction > 0)
	{			// actually covered some distance
	  VectorCopy (trace.endpos, ent->s.origin);
	  VectorCopy (ent->velocity, original_velocity);
	  numplanes = 0;
	}

      if (trace.fraction == 1)
	break;			// moved the entire distance

      hit = trace.ent;

      if (trace.plane.normal[2] > 0.7)
	{
	  blocked |= 1;		// floor
	  if (hit->solid == SOLID_BSP)
	    {
	      ent->groundentity = hit;
	      ent->groundentity_linkcount = hit->linkcount;
	    }
	}
      if (!trace.plane.normal[2])
	{
	  blocked |= 2;		// step
	}

//
// run the impact function
//
      SV_Impact (ent, &trace);
      if (!ent->inuse)
	break;			// removed by the impact function


      time_left -= time_left * trace.fraction;

      // cliped to another plane
      if (numplanes >= MAX_CLIP_PLANES)
	{			// this shouldn't really happen
	  VectorCopy (vec3_origin, ent->velocity);
	  return 3;
	}

      VectorCopy (trace.plane.normal, planes[numplanes]);
      numplanes++;

//
// modify original_velocity so it parallels all of the clip planes
//
      for (i = 0; i < numplanes; i++)
	{
	  ClipVelocity (original_velocity, planes[i], new_velocity, 1);
	  for (j = 0; j < numplanes; j++)
// The following VectorCompare was added in 3.20, adding it.  -FB
	    if ((j != i) && !VectorCompare (planes[i], planes[j]))
	      {
		if (DotProduct (new_velocity, planes[j]) < 0)
		  break;	// not ok
	      }
	  if (j == numplanes)
	    break;
	}

      if (i != numplanes)
	{			// go along this plane
	  VectorCopy (new_velocity, ent->velocity);
	}
      else
	{			// go along the crease
	  if (numplanes != 2)
	    {
//                              gi.dprintf ("clip velocity, numplanes == %i\n",numplanes);
	      VectorCopy (vec3_origin, ent->velocity);
	      return 7;
	    }
	  CrossProduct (planes[0], planes[1], dir);
	  d = DotProduct (dir, ent->velocity);
	  VectorScale (dir, d, ent->velocity);
	}

//
// if original velocity is against the original velocity, stop dead
// to avoid tiny occilations in sloping corners
//
      if (DotProduct (ent->velocity, primal_velocity) <= 0)
	{
	  VectorCopy (vec3_origin, ent->velocity);
	  return blocked;
	}
    }

  return blocked;
}
示例#15
0
/*
8===============>
FL_think
Moving the flashlight
<===============8
*/
void FL_think (edict_t * self)
{

	vec3_t start, end, endp, offset;
	vec3_t forward, right, up;
	vec3_t angles;
	trace_t tr;
	int height = 0;

  /*vec3_t start,end,endp,offset;
     vec3_t forward,right,up;
     trace_t tr; */

  //AngleVectors (self->owner->client->v_angle, forward, right, up);
  VectorAdd (self->owner->client->v_angle, self->owner->client->kick_angles,
	     angles);
  AngleVectors ( /*self->owner->client->v_angle */ angles, forward, right,
		up);

/*	VectorSet(offset,24 , 6, self->owner->viewheight-7);
	G_ProjectSource (self->owner->s.origin, offset, forward, right, start);
	VectorMA(start,8192,forward,end);

	tr = gi.trace (start,NULL,NULL, end,self->owner,CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER);

	if (tr.fraction != 1)
	{
		VectorMA(tr.endpos,-4,forward,endp);
		VectorCopy(endp,tr.endpos);
	}

	if ((tr.ent->svflags & SVF_MONSTER) || (tr.ent->client))
	{
		if ((tr.ent->takedamage) && (tr.ent != self->owner))
		{
			self->s.skinnum = 1;
		}
	}
	else
		self->s.skinnum = 0;

	vectoangles(tr.plane.normal,self->s.angles);
	VectorCopy(tr.endpos,self->s.origin);

	gi.linkentity (self);
	self->nextthink = level.framenum + FRAMEDIV; */

	if (self->owner->client->pers.firing_style == ACTION_FIRING_CLASSIC)
		height = 8;

	VectorSet (offset, 24, 8, self->owner->viewheight - height);

	P_ProjectSource (self->owner->client, self->owner->s.origin, offset,
		forward, right, start);
	VectorMA (start, 8192, forward, end);

	PRETRACE ();
	tr = gi.trace (start, NULL, NULL, end, self->owner,
		CONTENTS_SOLID | CONTENTS_MONSTER | CONTENTS_DEADMONSTER);
	POSTTRACE ();

	if (tr.fraction != 1)
	{
		VectorMA (tr.endpos, -4, forward, endp);
		VectorCopy (endp, tr.endpos);
	}

	vectoangles (tr.plane.normal, self->s.angles);
	VectorCopy (tr.endpos, self->s.origin);

	gi.linkentity (self);
	self->nextthink = level.framenum + FRAMEDIV;

}
示例#16
0
void target_laser_think (edict_t *self)
{
        edict_t *ignore;
        vec3_t  start;
        vec3_t  end;
        trace_t tr;
        vec3_t  point;
        vec3_t  last_movedir;
        int             count;

        if (self->spawnflags & 0x80000000)
                count = 8;
        else
                count = 4;

        if (self->enemy)
        {
                VectorCopy (self->movedir, last_movedir);
                VectorMA (self->enemy->absmin, 0.5, self->enemy->size, point);
                VectorSubtract (point, self->s.origin, self->movedir);
                VectorNormalize (self->movedir);
                if (!VectorCompare(self->movedir, last_movedir))
                        self->spawnflags |= 0x80000000;
        }

        ignore = self;
        VectorCopy (self->s.origin, start);
        VectorMA (start, 2048, self->movedir, end);
        while(1)
        {
                PRETRACE();
                tr = gi.trace (start, NULL, NULL, end, ignore, CONTENTS_SOLID|CONTENTS_MONSTER|CONTENTS_DEADMONSTER);
                POSTTRACE();

                if (!tr.ent)
                        break;

                // hurt it if we can
                if ((tr.ent->takedamage) && !(tr.ent->flags & FL_IMMUNE_LASER))
                        T_Damage (tr.ent, self, self->activator, self->movedir, tr.endpos, vec3_origin, self->dmg, 1, DAMAGE_ENERGY, MOD_TARGET_LASER);

                // if we hit something that's not a monster or player or is immune to lasers, we're done
                if (!(tr.ent->svflags & SVF_MONSTER) && (!tr.ent->client))
                {
                        if (self->spawnflags & 0x80000000)
                        {
                                self->spawnflags &= ~0x80000000;
                                gi.WriteByte (svc_temp_entity);
                                gi.WriteByte (TE_LASER_SPARKS);
                                gi.WriteByte (count);
                                gi.WritePosition (tr.endpos);
                                gi.WriteDir (tr.plane.normal);
                                gi.WriteByte (self->s.skinnum);
                                gi.multicast (tr.endpos, MULTICAST_PVS);
                        }
                        break;
                }

                ignore = tr.ent;
                VectorCopy (tr.endpos, start);
        }

        VectorCopy (tr.endpos, self->s.old_origin);

        self->nextthink = level.time + FRAMETIME;
}