Example #1
0
void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist)
{
	float		deltax,deltay;
	float			d[3];
	float		tdir, olddir, turnaround;

	olddir = anglemod( (int)(actor->v.ideal_yaw/45)*45 );
	turnaround = anglemod(olddir - 180);

	deltax = enemy->v.origin[0] - actor->v.origin[0];
	deltay = enemy->v.origin[1] - actor->v.origin[1];
	if (deltax>10)
		d[1]= 0;
	else if (deltax<-10)
		d[1]= 180;
	else
		d[1]= DI_NODIR;
	if (deltay<-10)
		d[2]= 270;
	else if (deltay>10)
		d[2]= 90;
	else
		d[2]= DI_NODIR;

// try direct route
	if (d[1] != DI_NODIR && d[2] != DI_NODIR)
	{
		if (d[1] == 0)
			tdir = d[2] == 90 ? 45 : 315;
		else
			tdir = d[2] == 90 ? 135 : 215;
			
		if (tdir != turnaround && SV_StepDirection(actor, tdir, dist))
			return;
	}

// try other directions
	if ( ((rand()&3) & 1) ||  abs(deltay)>abs(deltax))
	{
		tdir=d[1];
		d[1]=d[2];
		d[2]=tdir;
	}

	if (d[1]!=DI_NODIR && d[1]!=turnaround 
	&& SV_StepDirection(actor, d[1], dist))
			return;

	if (d[2]!=DI_NODIR && d[2]!=turnaround
	&& SV_StepDirection(actor, d[2], dist))
			return;

/* there is no direct path to the player, so pick another direction */

	if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist))
			return;

	if (rand()&1) 	/*randomly determine direction of search*/
	{
		for (tdir=0 ; tdir<=315 ; tdir += 45)
			if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) )
					return;
	}
	else
	{
		for (tdir=315 ; tdir >=0 ; tdir -= 45)
			if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) )
					return;
	}

	if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) )
			return;

	actor->v.ideal_yaw = olddir;		// can't move

// if a bridge was pulled out from underneath a monster, it may not have
// a valid standing position at all

	if (!SV_CheckBottom (actor))
		SV_FixCheckBottom (actor);

}
Example #2
0
void SV_Physics_Step (edict_t *ent)
{
	qboolean	wasonground;
	qboolean	inwater;
	qboolean	hitsound = false;
	float		*vel;
	float		speed, newspeed, control;
	float		friction;
	edict_t		*groundentity;

	groundentity = PROG_TO_EDICT(ent->v.groundentity);
	if ((int)groundentity->v.flags & FL_CONVEYOR)
		VectorScale(groundentity->v.movedir, groundentity->v.speed, ent->v.basevelocity);
	else
		VectorCopy(vec_origin, ent->v.basevelocity);
//@@
	pr_global_struct->time = sv.time;
	pr_global_struct->self = EDICT_TO_PROG(ent);
	PF_WaterMove();

	SV_CheckVelocity (ent);

	wasonground = (int)ent->v.flags & FL_ONGROUND;
//	ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;

	// add gravity except:
	//   flying monsters
	//   swimming monsters who are in the water
	inwater = SV_CheckWater(ent);
	if (! wasonground)
		if (!((int)ent->v.flags & FL_FLY))
			if (!(((int)ent->v.flags & FL_SWIM) && (ent->v.waterlevel > 0)))
			{
				if (ent->v.velocity[2] < sv_gravity.value*-0.1)
					hitsound = true;
				if (!inwater)
					SV_AddGravity (ent);
			}

	if (!VectorCompare(ent->v.velocity, vec_origin) || !VectorCompare(ent->v.basevelocity, vec_origin))
	{
		ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
		// apply friction
		// let dead monsters who aren't completely onground slide
		if (wasonground)
			if (!(ent->v.health <= 0.0 && !SV_CheckBottom(ent)))
			{
				vel = ent->v.velocity;
				speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]);
				if (speed)
				{
					friction = sv_friction.value;

					control = speed < sv_stopspeed.value ? sv_stopspeed.value : speed;
					newspeed = speed - host_frametime*control*friction;

					if (newspeed < 0)
						newspeed = 0;
					newspeed /= speed;

					vel[0] = vel[0] * newspeed;
					vel[1] = vel[1] * newspeed;
				}
			}

		VectorAdd (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);
		SV_FlyMove (ent, host_frametime, NULL);
		VectorSubtract (ent->v.velocity, ent->v.basevelocity, ent->v.velocity);

		// determine if it's on solid ground at all
		{
			vec3_t	mins, maxs, point;
			int		x, y;
		
			VectorAdd (ent->v.origin, ent->v.mins, mins);
			VectorAdd (ent->v.origin, ent->v.maxs, maxs);

			point[2] = mins[2] - 1;
			for	(x=0 ; x<=1 ; x++)
				for	(y=0 ; y<=1 ; y++)
				{
					point[0] = x ? maxs[0] : mins[0];
					point[1] = y ? maxs[1] : mins[1];
					if (SV_PointContents (point) == CONTENTS_SOLID)
					{
						ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
						break;
					}
				}

		}

		SV_LinkEdict (ent, true);

		if ((int)ent->v.flags & FL_ONGROUND)
			if (!wasonground)
				if (hitsound)
					SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
	}

// regular thinking
	SV_RunThink (ent);
	SV_CheckWaterTransition (ent);
}
Example #3
0
void SV_NewChaseDir( edict_t *actor, vec3_t destination, float dist )
{
	float	deltax, deltay;
	float	tempdir, olddir, turnaround;
	vec3_t	d;

	olddir = anglemod(((int)( actor->v.ideal_yaw / 45.0f )) * 45.0f );
	turnaround = anglemod( olddir - 180 );

	deltax = destination[0] - actor->v.origin[0];
	deltay = destination[1] - actor->v.origin[1];

	if( deltax > 10 )
		d[1] = 0.0f;
	else if( deltax < -10 )
		d[1] = 180.0f;
	else d[1] = -1;

	if( deltay < -10 )
		d[2] = 270.0f;
	else if( deltay > 10 )
		d[2] = 90.0f;
	else d[2] = -1;

	// try direct route
	if( d[1] != -1 && d[2] != -1 )
	{
		if( d[1] == 0.0f )
			tempdir = ( d[2] == 90.0f ) ? 45.0f : 315.0f;
		else tempdir = ( d[2] == 90.0f ) ? 135.0f : 215.0f;

		if( tempdir != turnaround && SV_StepDirection( actor, tempdir, dist ))
			return;
	}

	// try other directions
	if( Com_RandomLong( 0, 1 ) != 0 || fabs( deltay ) > fabs( deltax ))
	{
		tempdir = d[1];
		d[1] = d[2];
		d[2] = tempdir;
	}

	if( d[1] != -1 && d[1] != turnaround && SV_StepDirection( actor, d[1], dist ))
		return;

	if( d[2] != -1 && d[2] != turnaround && SV_StepDirection( actor, d[2], dist ))
		return;

	// there is no direct path to the player, so pick another direction
	if( olddir != -1 && SV_StepDirection( actor, olddir, dist ))
		return;

	// fine, just run somewhere.
	if( Com_RandomLong( 0, 1 ) != 1 )
	{
		for( tempdir = 0; tempdir <= 315; tempdir += 45 )
		{
			if( tempdir != turnaround && SV_StepDirection( actor, tempdir, dist ))
				return;
		}
	}
	else
	{
		for( tempdir = 315; tempdir >= 0; tempdir -= 45 )
		{
			if( tempdir != turnaround && SV_StepDirection( actor, tempdir, dist ))
				return;
		}
	}

	// we tried. run backwards. that ought to work...
	if( turnaround != -1 && SV_StepDirection( actor, turnaround, dist ))
		return;

	// well, we're stuck somehow.
	actor->v.ideal_yaw = olddir;

	// if a bridge was pulled out from underneath a monster, it may not have
	// a valid standing position at all.
	if( !SV_CheckBottom( actor, MOVE_NORMAL ))
	{
		actor->v.flags |= FL_PARTIALGROUND;
	}
}
Example #4
0
/*
=============
SV_movestep

Called by monster program code.
The move will be adjusted for slopes and stairs, but if the move isn't
possible, no move is done, FALSE is returned, and
pr_global_struct->trace_normal is set to the normal of the blocking wall
=============
*/
qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink)
{
	float		dz;
	vec3_t		oldorg, neworg, end;
	trace_t		trace;
	int			i;
	edict_t		*enemy;

// try the move	
	VectorCopy (ent->v.origin, oldorg);
	VectorAdd (ent->v.origin, move, neworg);

// flying monsters don't step up
	if ( (int)ent->v.flags & (FL_SWIM | FL_FLY) )
	{
	// try one move with vertical motion, then one without
		for (i=0 ; i<2 ; i++)
		{
			VectorAdd (ent->v.origin, move, neworg);
			enemy = PROG_TO_EDICT(ent->v.enemy);
			if (i == 0 && enemy != sv.edicts)
			{
				dz = ent->v.origin[2] - PROG_TO_EDICT(ent->v.enemy)->v.origin[2];
				if (dz > 40)
					neworg[2] -= 8;
				if (dz < 30)
					neworg[2] += 8;
			}
			trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, neworg, FALSE, ent);
	
			if (trace.fraction == 1)
			{
				if ( ((int)ent->v.flags & FL_SWIM) && SV_PointContents(trace.endpos) == CONTENTS_EMPTY )
					return FALSE;	// swim monster left water
	
				VectorCopy (trace.endpos, ent->v.origin);
				if (relink)
					SV_LinkEdict (ent, TRUE);
				return TRUE;
			}
			
			if (enemy == sv.edicts)
				break;
		}
		
		return FALSE;
	}

// push down from a step height above the wished position
	neworg[2] += STEPSIZE;
	VectorCopy (neworg, end);
	end[2] -= STEPSIZE*2;

	trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, FALSE, ent);

	if (trace.allsolid)
		return FALSE;

	if (trace.startsolid)
	{
		neworg[2] -= STEPSIZE;
		trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, FALSE, ent);
		if (trace.allsolid || trace.startsolid)
			return FALSE;
	}
	if (trace.fraction == 1)
	{
	// if monster had the ground pulled out, go ahead and fall
		if ( (int)ent->v.flags & FL_PARTIALGROUND )
		{
			VectorAdd (ent->v.origin, move, ent->v.origin);
			if (relink)
				SV_LinkEdict (ent, TRUE);
			ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
//	Con_Printf ("fall down\n"); 
			return TRUE;
		}
	
		return FALSE;		// walked off an edge
	}

// check point traces down for dangling corners
	VectorCopy (trace.endpos, ent->v.origin);
	
	if (!SV_CheckBottom (ent))
	{
		if ( (int)ent->v.flags & FL_PARTIALGROUND )
		{	// entity had floor mostly pulled out from underneath it
			// and is trying to correct
			if (relink)
				SV_LinkEdict (ent, TRUE);
			return TRUE;
		}
		VectorCopy (oldorg, ent->v.origin);
		return FALSE;
	}

	if ( (int)ent->v.flags & FL_PARTIALGROUND )
	{
//		Con_Printf ("back on ground\n"); 
		ent->v.flags = (int)ent->v.flags & ~FL_PARTIALGROUND;
	}
	ent->v.groundentity = EDICT_TO_PROG(trace.ent);

// the move is ok
	if (relink)
		SV_LinkEdict (ent, TRUE);
	return TRUE;
}
Example #5
0
qboolean SV_MoveStep( edict_t *ent, vec3_t move, qboolean relink )
{
	int	i;
	trace_t	trace;
	vec3_t	oldorg, neworg, end;
	edict_t	*enemy;
	float	dz;

	VectorCopy( ent->v.origin, oldorg );
	VectorAdd( ent->v.origin, move, neworg );

	// well, try it.  Flying and swimming monsters are easiest.
	if( ent->v.flags & ( FL_SWIM|FL_FLY ))
	{
		// try one move with vertical motion, then one without
		for( i = 0; i < 2; i++ )
		{
			VectorAdd( ent->v.origin, move, neworg );

			enemy = ent->v.enemy;
			if( i == 0 && enemy != NULL )
			{
				dz = ent->v.origin[2] - enemy->v.origin[2];

				if( dz > 40 ) neworg[2] -= 8;
				else if( dz < 30 ) neworg[2] += 8;
			}

			trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, neworg, MOVE_NORMAL, ent );

			if( trace.fraction == 1.0f )
			{
				svs.groupmask = ent->v.groupinfo;

				// that move takes us out of the water.
				// apparently though, it's okay to travel into solids, lava, sky, etc :)
				if(( ent->v.flags & FL_SWIM ) && SV_PointContents( trace.endpos ) == CONTENTS_EMPTY )
					return 0;

				VectorCopy( trace.endpos, ent->v.origin );
				if( relink ) SV_LinkEdict( ent, true );

				return 1;
			}
			else
			{
				if( !SV_IsValidEdict( enemy ))
					break;
			}
		}
		return 0;
	}
	else
	{

		dz = svgame.movevars.stepsize;
		neworg[2] += dz;
		VectorCopy( neworg, end );
		end[2] -= dz * 2.0f;

		trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent );
		if( trace.allsolid )
			return 0;

		if( trace.startsolid != 0 )
		{
			neworg[2] -= dz;
			trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent );

			if( trace.allsolid != 0 || trace.startsolid != 0 )
				return 0;
		}

		if( trace.fraction == 1.0f )
		{
			if( ent->v.flags & FL_PARTIALGROUND )
			{
				VectorAdd( ent->v.origin, move, ent->v.origin );
				if( relink ) SV_LinkEdict( ent, true );
				ent->v.flags &= ~FL_ONGROUND;
				return 1;
			}
			return 0;
		}
		else
		{
			VectorCopy( trace.endpos, ent->v.origin );

			if( SV_CheckBottom( ent, MOVE_NORMAL ) == 0 )
			{
				if( ent->v.flags & FL_PARTIALGROUND )
				{
					if( relink ) SV_LinkEdict( ent, true );
					return 1;
				}

				VectorCopy( oldorg, ent->v.origin );
				return 0;
			}
			else
			{
				ent->v.flags &= ~FL_PARTIALGROUND;
				ent->v.groundentity = trace.ent;
				if( relink ) SV_LinkEdict( ent, true );

				return 1;
			}
		}
	}
}
Example #6
0
qboolean SV_MoveTest( edict_t *ent, vec3_t move, qboolean relink )
{
	float	temp;
	vec3_t	oldorg, neworg, end;
	trace_t	trace;

	VectorCopy( ent->v.origin, oldorg );
	VectorAdd( ent->v.origin, move, neworg );

	temp = svgame.movevars.stepsize;

	neworg[2] += temp;
	VectorCopy( neworg, end );
	end[2] -= temp * 2.0f;

	trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_WORLDONLY, ent );

	if( trace.allsolid != 0 )
		return 0;

	if( trace.startsolid != 0 )
	{
		neworg[2] -= temp;
		trace = SV_Move( neworg, ent->v.mins, ent->v.maxs, end, MOVE_WORLDONLY, ent );

		if( trace.allsolid != 0 || trace.startsolid != 0 )
			return 0;
	}

	if( trace.fraction == 1.0f )
	{
		if( ent->v.flags & FL_PARTIALGROUND )
		{
			VectorAdd( ent->v.origin, move, ent->v.origin );
			if( relink ) SV_LinkEdict( ent, true );
			ent->v.flags &= ~FL_ONGROUND;
			return 1;
		}
		return 0;
	}
	else
	{
		VectorCopy( trace.endpos, ent->v.origin );

		if( SV_CheckBottom( ent, MOVE_WORLDONLY ) == 0 )
		{
			if( ent->v.flags & FL_PARTIALGROUND )
			{
				if( relink ) SV_LinkEdict( ent, true );
				return 1;
			}

			VectorCopy( oldorg, ent->v.origin );
			return 0;
		}
		else
		{
			ent->v.flags &= ~FL_PARTIALGROUND;
			ent->v.groundentity = trace.ent;
			if( relink ) SV_LinkEdict( ent, true );

			return 1;
		}
	}
}
Example #7
0
/*
=============
SV_Physics_Step

Monsters freefall when they don't have a ground entity, otherwise
all movement is done with discrete steps.

This is also used for objects that have become still on the ground, but
will fall if the floor is pulled out from under them.
=============
*/
void SV_Physics_Step( edict_t *ent )
{
	qboolean	inwater;
	qboolean	wasonground;
	qboolean	wasonmover;
	vec3_t	mins, maxs;
	vec3_t	point;
	trace_t	trace;
	int	x, y;

	SV_WaterMove( ent );
	SV_CheckVelocity( ent );

	wasonground = (ent->v.flags & FL_ONGROUND);
	wasonmover = SV_CheckMover( ent );
	inwater = SV_CheckWater( ent );

	if( ent->v.flags & FL_FLOAT && ent->v.waterlevel > 0 )
	{
		float buoyancy = SV_Submerged( ent ) * ent->v.skin * host.frametime;

		SV_AddGravity( ent );
		ent->v.velocity[2] += buoyancy;
	}

	if( !wasonground && !( ent->v.flags & FL_FLY ) && (!( ent->v.flags & FL_SWIM ) || ent->v.waterlevel <= 0 ))
	{
		if( !inwater )
			SV_AddGravity( ent );
	}

	if( !VectorIsNull( ent->v.velocity ) || !VectorIsNull( ent->v.basevelocity ))
	{
		ent->v.flags &= ~FL_ONGROUND;

		if(( wasonground || wasonmover ) && ( ent->v.health > 0 || SV_CheckBottom( ent, MOVE_NORMAL )))
		{
			float	*vel = ent->v.velocity;
			float	control, speed, newspeed;
			float	friction;

			speed = sqrt(( vel[0] * vel[0] ) + ( vel[1] * vel[1] ));	// DotProduct2D

			if( speed )
			{
				friction = sv_friction->value * ent->v.friction;	// factor
				ent->v.friction = 1.0f; // g-cont. ???
				if( wasonmover ) friction *= 0.5f; // add a little friction

				control = (speed < sv_stopspeed->value) ? sv_stopspeed->value : speed;
				newspeed = speed - (host.frametime * control * friction);
				if( newspeed < 0 ) newspeed = 0;
				newspeed /= speed;

				vel[0] = vel[0] * newspeed;
				vel[1] = vel[1] * newspeed;
			}
		}

		VectorAdd( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );
		SV_CheckVelocity( ent );

		SV_FlyMove( ent, host.frametime, NULL );
		if( ent->free ) return;

		SV_CheckVelocity( ent );
		VectorSubtract( ent->v.velocity, ent->v.basevelocity, ent->v.velocity );

		SV_CheckVelocity( ent );

		VectorAdd( ent->v.origin, ent->v.mins, mins );
		VectorAdd( ent->v.origin, ent->v.maxs, maxs );

		point[2] = mins[2] - 1.0f;

		for( x = 0; x <= 1; x++ )
		{
			if( ent->v.flags & FL_ONGROUND )
				break;

			for( y = 0; y <= 1; y++ )
			{
				point[0] = x ? maxs[0] : mins[0];
				point[1] = y ? maxs[1] : mins[1];

				trace = SV_Move( point, vec3_origin, vec3_origin, point, MOVE_NORMAL, ent );

				if( trace.startsolid )
				{
					ent->v.flags |= FL_ONGROUND;
					ent->v.groundentity = trace.ent;
					ent->v.friction = 1.0f;
					break;
				}
			}
		}

		SV_LinkEdict( ent, true );
	}
	else
	{
		if( svgame.globals->force_retouch != 0 )
		{
			trace = SV_Move( ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_NORMAL, ent );

			// hentacle impact code
			if(( trace.fraction < 1.0f || trace.startsolid ) && SV_IsValidEdict( trace.ent ))
			{
				SV_Impact( ent, trace.ent, &trace );
				if( ent->free ) return;
			}
		}
	}

	if( !SV_RunThink( ent )) return;
	SV_CheckWaterTransition( ent );

}
Example #8
0
void SV_NewChaseDir2(edict_t *actor, vec3_t destination, float dist) {

   float deltax, deltay;
   float tempdir, olddir, turnaround;
   vec3_t d;

   olddir = anglemod(((int)(actor->v.ideal_yaw / 45.0)) * 45.0); //So, we're shaving down some of the precision.  Ohkay.
   turnaround = anglemod(olddir - 180);

   deltax = destination[0] - actor->v.origin[0];
   deltay = destination[1] - actor->v.origin[1];

   if(deltax > 10) { d[1]= 0; }
   else if(deltax < -10) { d[1]= 180; }
   else { d[1] = -1; } //DI_NODIR, so in this function, -1 is a reserved 'null' like value.

   if(deltay < -10) { d[2] = 270; }
   else if(deltay > 10) { d[2] = 90; }
   else { d[2] = -1; }

   // try direct route
   if(d[1] != -1 && d[2] != -1) {

      if(d[1] == 0) {
         if(d[2] == 90) { tempdir = 45; }
         else { tempdir = 315; }
      }
      else {
         if(d[2] == 90) { tempdir = 135; }
         else { tempdir = 215; }
      }

      if(tempdir != turnaround && SV_StepDirection(actor, tempdir, dist) != 0) {
         return;
      }
   }

   // try other directions
   if(RandomLong(0, 1) != 0 || fabs(deltay) > fabs(deltax)) { //These were originally cast as int before compared.  I cannot think of any compelling reason to do so.

      tempdir = d[1];
      d[1] = d[2];
      d[2] = tempdir;
   }

   if(d[1] != -1 && d[1] != turnaround && SV_StepDirection(actor, d[1], dist) != 0) {
      return;
   }
   if(d[2] != -1 && d[2] != turnaround && SV_StepDirection(actor, d[2], dist) != 0) {
      return;
   }

   /* there is no direct path to the player, so pick another direction */
   if(olddir != -1 && SV_StepDirection(actor, olddir, dist) != 0) {
      return;
   }

   //Fine, just run somewhere.
   if(RandomLong(0, 1) != 0) {
      for(tempdir = 0; tempdir <= 315; tempdir += 45) {
         if(tempdir != turnaround && SV_StepDirection(actor, tempdir, dist) != 0) {
            return;
         }
      }
   }
   else {
      for(tempdir = 315; tempdir >= 0; tempdir -= 45) {
         if(tempdir != turnaround && SV_StepDirection(actor, tempdir, dist) != 0) {
            return;
         }
      }
   }

   //We tried.  Run backwards.  THAT ought to work...
   if(turnaround != -1 && SV_StepDirection(actor, turnaround, dist) != 0) {
      return;
   }

   //Well, we're stuck somehow.
   actor->v.ideal_yaw = olddir;

   // if a bridge was pulled out from underneath a monster, it may not have
   // a valid standing position at all.

   if(SV_CheckBottom(actor) == 0) {
      SV_FixCheckBottom(actor);
   }
}
Example #9
0
qboolean SV_movetest(edict_t *ent, vec3_t move, qboolean relink) {

   float temp;
   vec3_t oldorg, neworg, end;
   trace_t trace;


   oldorg[0] = ent->v.origin[0];
   oldorg[1] = ent->v.origin[1];
   oldorg[2] = ent->v.origin[2];

   neworg[0] = ent->v.origin[0] + move[0];
   neworg[1] = ent->v.origin[1] + move[1];
   neworg[2] = ent->v.origin[2] + move[2];

   temp = cvar_sv_stepsize.value;

   neworg[2] += temp;
   end[0] = neworg[0];
   end[1] = neworg[1];
   end[2] = neworg[2];
   end[2] -= temp*2;

   trace = SV_MoveNoEnts(neworg, ent->v.mins, ent->v.maxs, end, 0, ent);

   if(trace.allsolid != 0) { return(0); }
   if(trace.startsolid != 0) {

      neworg[2] -= temp;

      trace = SV_MoveNoEnts(neworg, ent->v.mins, ent->v.maxs, end, 0, ent);

      if(trace.allsolid != 0 || trace.startsolid != 0) { return(0); }
   }

   if(trace.fraction == 1) {
      if(ent->v.flags & FL_PARTIALGROUND) {
         ent->v.origin[0] += move[0];
         ent->v.origin[1] += move[1];
         ent->v.origin[2] += move[2];

         if(relink != 0) {
            SV_LinkEdict(ent, 1);
         }
         ent->v.flags &= ~FL_ONGROUND;
         return(1);
      }

      return(0);
   }
   else {

      ent->v.origin[0] = trace.endpos[0];
      ent->v.origin[1] = trace.endpos[1];
      ent->v.origin[2] = trace.endpos[2];

      if(SV_CheckBottom(ent) == 0) {
         if(ent->v.flags & FL_PARTIALGROUND) {

            if(relink != 0) {
               SV_LinkEdict(ent, 1);
            }
            return(1);
         }

         ent->v.origin[0] = oldorg[0];
         ent->v.origin[1] = oldorg[1];
         ent->v.origin[2] = oldorg[2];

         return(0);
      }
      else {

         if(ent->v.flags & FL_PARTIALGROUND) {
            ent->v.flags &= ~FL_PARTIALGROUND;
         }

         ent->v.groundentity = trace.pHit;

         if(relink != 0) {
            SV_LinkEdict(ent, 1);
         }
         return(1);
      }
   }
}
Example #10
0
/* DESCRIPTION: SV_movestep/movetest
// LOCATION: sv_move.c
// PATH: PF_walkmove_I
//
// (from QW): Called by monster program code.
// The move will be adjusted for slopes and stairs, but if the move isn't
// possible, no move is done, false is returned, and
// pr_global_struct->trace_normal is set to the normal of the blocking wall
*/
qboolean SV_movestep(edict_t *ent, vec3_t move, qboolean relink) {

   int i, var_6C_hullnum;
   float dz;
   trace_t trace;
   vec3_t oldorg, neworg, end;
   edict_t * enemy;


   if(ent->v.flags & FL_MONSTERCLIP) { //Don't know what one has to do with the other.
      var_6C_hullnum = 1;
   }
   else {
      var_6C_hullnum = 0;
   }

   oldorg[0] = ent->v.origin[0];
   oldorg[1] = ent->v.origin[1];
   oldorg[2] = ent->v.origin[2];

   neworg[0] = ent->v.origin[0] + move[0];
   neworg[1] = ent->v.origin[1] + move[1];
   neworg[2] = ent->v.origin[2] + move[2];


   //well, try it.  Flying and swimming monsters are easiest.
   if(ent->v.flags & (FL_SWIM | FL_FLY)) {

      // try one move with vertical motion, then one without
      for(i = 0; i < 2; i++) {

         neworg[0] = ent->v.origin[0] + move[0];
         neworg[1] = ent->v.origin[1] + move[1];
         neworg[2] = ent->v.origin[2] + move[2];

         enemy = ent->v.enemy;
         if(i == 0 && enemy != NULL) {

            dz = ent->v.origin[2] - enemy->v.origin[2];

            if(dz > 40) { neworg[2] -= 8; }
            else if(dz < 30) { neworg[2] += 8; }
         }

         trace = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, neworg, 0, ent, var_6C_hullnum);

         if(trace.fraction == 1) { //yaay

            global_g_groupmask = ent->v.groupinfo;

            if((ent->v.flags & FL_SWIM) && SV_PointContents(trace.endpos) == Q1CONTENTS_EMPTY) {
               return(0); //That move takes us out of the water.  Apparently though, it's okay to travel into solids, lava, sky, etc :)
            }

            ent->v.origin[0] = trace.endpos[0];
            ent->v.origin[1] = trace.endpos[1];
            ent->v.origin[2] = trace.endpos[2];

            if(relink != 0) {
               SV_LinkEdict(ent, 1);
            }
            return(1);
         }
         else {

            if(enemy == NULL) { break; }
         }
      }

      return(0);
   }
   else {

      dz = cvar_sv_stepsize.value;
      neworg[2] += dz;
      end[0] = neworg[0];
      end[1] = neworg[1];
      end[2] = neworg[2];
      end[2] -= dz*2;

      trace = SV_Move(neworg, ent->v.mins, ent->v.maxs, end, 0, ent, var_6C_hullnum);
      if(trace.allsolid != 0) { return(0); }

      if(trace.startsolid != 0) {

         neworg[2] -= dz;

         trace = SV_Move(neworg, ent->v.mins, ent->v.maxs, end, 0, ent, var_6C_hullnum);

         if(trace.allsolid != 0 || trace.startsolid != 0) { return(0); }
      }

      if(trace.fraction == 1) {
         if(ent->v.flags & FL_PARTIALGROUND) { //Whoa, where'd the ground go?

            ent->v.origin[0] += move[0];
            ent->v.origin[1] += move[1];
            ent->v.origin[2] += move[2];

            if(relink != 0) {
               SV_LinkEdict(ent, 1);
            }
            ent->v.flags &= ~FL_ONGROUND;
            return(1);
         }

         return(0); //Fell off like a green koopa.
      }
      else {

         ent->v.origin[0] = trace.endpos[0];
         ent->v.origin[1] = trace.endpos[1];
         ent->v.origin[2] = trace.endpos[2];

         if(SV_CheckBottom(ent) == 0) {
            if(ent->v.flags & FL_PARTIALGROUND) {

               if(relink != 0) {
                  SV_LinkEdict(ent, 1);
               }
               return(1);
            }

            ent->v.origin[0] = oldorg[0];
            ent->v.origin[1] = oldorg[1];
            ent->v.origin[2] = oldorg[2];

            return(0);
         }
         else {

            if(ent->v.flags & FL_PARTIALGROUND) {
               ent->v.flags &= ~FL_PARTIALGROUND;
            }

            ent->v.groundentity = trace.pHit;

            if(relink != 0) {
               SV_LinkEdict(ent, 1);
            }
            return(1);
         }
      }
   }
}
Example #11
0
/*
=============
SV_movestep

Called by monster program code.
The move will be adjusted for slopes and stairs, but if the move isn't
possible, no move is done, false is returned, and
pr_global_struct->trace_normal is set to the normal of the blocking wall
=============
*/
qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy,
					  qboolean set_trace)
{
	float		dz;
	vec3_t		oldorg, neworg, end;
	trace_t		trace;
	int			i;
	edict_t		*enemy;

// try the move	
	VectorCopy (ent->v.origin, oldorg);
	VectorAdd (ent->v.origin, move, neworg);

// flying monsters don't step up, unless no_z turned on
	if ( ((int)ent->v.flags&(FL_SWIM|FL_FLY)) && !((int)ent->v.flags&FL_NOZ) && !((int)ent->v.flags&FL_HUNTFACE))
	{
	// try one move with vertical motion, then one without
		for (i=0 ; i<2 ; i++)
		{
			VectorAdd (ent->v.origin, move, neworg);
			if (!noenemy)
			{
				enemy = PROG_TO_EDICT(ent->v.enemy);
				if (i == 0 && enemy != sv.edicts)
				{
					if((int)ent->v.flags&FL_HUNTFACE)//Go for face
						dz = ent->v.origin[2] - PROG_TO_EDICT(ent->v.enemy)->v.origin[2] + PROG_TO_EDICT(ent->v.enemy)->v.view_ofs[2];
					else
						dz = ent->v.origin[2] - PROG_TO_EDICT(ent->v.enemy)->v.origin[2];

					if (dz > 40)
						neworg[2] -= 8;
					else if (dz < 30)
						neworg[2] += 8;
				}
			}

			if ( ((int)ent->v.flags & FL_SWIM) && SV_PointContents(neworg) == CONTENTS_EMPTY )
			{//Would end up out of water, don't do z move
				neworg[2]=ent->v.origin[2];
				trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, neworg, false, ent);
				if (set_trace)
					set_move_trace(&trace);
				if(trace.fraction < 1||SV_PointContents(trace.endpos) == CONTENTS_EMPTY )
					return false;	// swim monster left water
			}
			else
			{
				trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, neworg, false, ent);
				if (set_trace)
					set_move_trace(&trace);
			}
	
			if (trace.fraction == 1)
			{
				VectorCopy (trace.endpos, ent->v.origin);
				if (relink)
					SV_LinkEdict (ent, true);

				return true;
			}
			
			if (noenemy || enemy == sv.edicts)
				break;
		}
		
		return false;
	}

// push down from a step height above the wished position
	neworg[2] += STEPSIZE;
	VectorCopy (neworg, end);
	end[2] -= STEPSIZE*2;

	trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, false, ent);

	if (set_trace)
		set_move_trace(&trace);

	if (trace.allsolid)
	{
		return false;
	}

	if (trace.startsolid)
	{
		neworg[2] -= STEPSIZE;
		trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, false, ent);
		if (set_trace)
			set_move_trace(&trace);
		if (trace.allsolid || trace.startsolid)
		{
			return false;
		}
	}
	if (trace.fraction == 1)
	{
	// if monster had the ground pulled out, go ahead and fall
		if ( (int)ent->v.flags & FL_PARTIALGROUND )
		{
			VectorAdd (ent->v.origin, move, ent->v.origin);
			if (relink)
				SV_LinkEdict (ent, true);
			ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
//	Con_Printf ("fall down\n"); 
			return true;
		}
	
		return false;		// walked off an edge
	}

// check point traces down for dangling corners
	VectorCopy (trace.endpos, ent->v.origin);
	
	if (!SV_CheckBottom (ent))
	{
		if ( (int)ent->v.flags & FL_PARTIALGROUND )
		{	// entity had floor mostly pulled out from underneath it
			// and is trying to correct
			if (relink)
				SV_LinkEdict (ent, true);
			return true;
		}
		VectorCopy (oldorg, ent->v.origin);

		return false;
	}

	if ( (int)ent->v.flags & FL_PARTIALGROUND )
	{
//		Con_Printf ("back on ground\n"); 
		ent->v.flags = (int)ent->v.flags & ~FL_PARTIALGROUND;
	}
	ent->v.groundentity = EDICT_TO_PROG(trace.ent);

// the move is ok
	if (relink)
		SV_LinkEdict (ent, true);
	return true;
}