Exemplo n.º 1
0
void SV_MoveToOrigin( edict_t *ent, const vec3_t pflGoal, float dist, int iMoveType )
{
	vec3_t	vecDist;

	VectorCopy( pflGoal, vecDist );

	if( ent->v.flags & ( FL_FLY|FL_SWIM|FL_ONGROUND ))
	{
		if( iMoveType == MOVE_NORMAL )
		{
			if( SV_StepDirection( ent, ent->v.ideal_yaw, dist ) == 0 )
			{
				SV_NewChaseDir( ent, vecDist, dist );
			}
		}
		else
		{
			vecDist[0] -= ent->v.origin[0];
			vecDist[1] -= ent->v.origin[1];

			if( ent->v.flags & ( FL_FLY|FL_SWIM ))
				vecDist[2] -= ent->v.origin[2];
			else vecDist[2] = 0.0f;

			VectorNormalize( vecDist );
			VectorScale( vecDist, dist, vecDist );
			SV_FlyDirection( ent, vecDist );
		}
	}
}
Exemplo n.º 2
0
/*
======================
SV_MoveToGoal

======================
*/
void SV_MoveToGoal (void)
{
	edict_t		*ent, *goal;
	float		dist;
#ifdef QUAKE2
	edict_t		*enemy;
#endif

	ent = PROG_TO_EDICT(pr_global_struct->self);
	goal = PROG_TO_EDICT(ent->v.goalentity);
	dist = G_FLOAT(OFS_PARM0);

	if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
	{
		G_FLOAT(OFS_RETURN) = 0;
		return;
	}

// if the next step hits the enemy, return immediately
#ifdef QUAKE2
	enemy = PROG_TO_EDICT(ent->v.enemy);
	if (enemy != sv.edicts &&  SV_CloseEnough (ent, enemy, dist) )
#else
	if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts &&  SV_CloseEnough (ent, goal, dist) )
#endif
		return;

// bump around...
	if ( (rand()&3)==1 ||
	!SV_StepDirection (ent, ent->v.ideal_yaw, dist))
	{
		SV_NewChaseDir (ent, goal, dist);
	}
}
Exemplo n.º 3
0
void SV_NewChaseDir1 (edict_t *self, edict_t *goal, float dist)
{
	int		i, bestyaw, minyaw, maxyaw;	
	vec3_t	v;

	if (!goal)
		return;

	VectorSubtract(goal->s.origin, self->s.origin, v);
	bestyaw = vectoyaw(v);

	minyaw = bestyaw - 90;
	maxyaw = bestyaw + 90;

	if (minyaw < 0)
		minyaw += 360;
	if (maxyaw > 360)
		maxyaw -= 360;

	for (i=minyaw; i<maxyaw; i+=30) {
		if (SV_StepDirection(self, i, dist, false))
			return;
	}

	//gi.dprintf("couldnt find a better direction!\n");
	SV_NewChaseDir(self, goal, dist);
}
Exemplo n.º 4
0
void SV_NewChaseDir2 (edict_t *self, vec3_t dest, float dist)
{
	float	minyaw, maxyaw, bestyaw, temp;
	vec3_t	v;

	if (!dest)
		return;

	VectorSubtract(dest, self->s.origin, v);
	bestyaw = vectoyaw(v);

	minyaw = bestyaw - 90;
	maxyaw = bestyaw + 90;

	// try a step forward +/- 90 degrees from ideal yaw
	if (CheckYawStep(self, minyaw, maxyaw, dist))
	{
		//gi.dprintf("took a step +/- 90 degrees from ideal yaw\n");
		return;
	}

	// that didn't work, so flip the search pattern and
	// try going in the opposite direction
	temp = minyaw;
	minyaw = maxyaw;
	maxyaw = temp;
	if (CheckYawStep(self, minyaw, maxyaw, dist))
	{
		//gi.dprintf("took a step 180 degrees from ideal yaw\n");
		return;
	}
	
	//gi.dprintf("couldnt find a better direction!\n");
	SV_NewChaseDir(self, self->goalentity, dist);
}
Exemplo n.º 5
0
/*
======================
SV_MoveToGoal

======================
*/
void SV_MoveToGoal (void)
{
	edict_t		*ent, *goal;
	float		dist;

	ent = PROG_TO_EDICT(PR_GLOBAL_STRUCT(self));	// Entity moving
	goal = PROG_TO_EDICT(ent->v.goalentity);	// its goalentity
	dist = G_FLOAT(OFS_PARM0);			// how far to move

// Reset trace_plane_normal
	VectorCopy(vec3_origin, PR_GLOBAL_STRUCT(trace_plane_normal));

// If not onground, flying, or swimming, return 0
	if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) )
	{
		G_FLOAT(OFS_RETURN) = 0;
		return;
	}

// if the next step hits the enemy, return immediately
	if ( PROG_TO_EDICT(ent->v.enemy) != sv.edicts &&  SV_CloseEnough (ent, goal, dist) )
	{
		G_FLOAT(OFS_RETURN) = 0;
		return;
	}

// bump around...
	if (!SV_StepDirection (ent, ent->v.ideal_yaw, dist))//If can't go in a direction (including step check) or 30% chance...
	{
		SV_NewChaseDir (ent, goal, dist);//Find a new direction to go in instead
		G_FLOAT(OFS_RETURN) = 0;
	}
	else
	{
		if ((rand()&3)==1)
		{
			SV_NewChaseDir (ent, goal, dist);//Find a new direction to go in instead
		}
		G_FLOAT(OFS_RETURN) = 1;
	}
	return;
}
Exemplo n.º 6
0
/*
====================
M_MoveAwayFromFlare
====================
*/
qboolean M_MoveAwayFromFlare(edict_t *self, float dist)
{
	edict_t *e = NULL;
	edict_t *goal = NULL;
	vec3_t delta;
	vec3_t forward;

	// find the closest flare
	while(1)
	{
		e = findradius(e, self->s.origin, 256);
		if (e == NULL)
			break;

		if (Q_stricmp(e->classname, "flare") == 0)
			break;
	}
	
	goal = G_Spawn();
	self->goalentity = goal;
	if (e == NULL)
	{
		// just move forward
		AngleVectors(self->s.angles, forward, NULL, NULL);
		VectorMA(self->s.origin, 128, forward, goal->s.origin);
	}
	else
	{
		VectorSubtract(self->s.origin, e->s.origin, delta);
		VectorNormalize(delta);
		VectorMA(self->s.origin, 128, delta, goal->s.origin);
	}

	if (rand() & (7 == 1))
	{
		// set the ideal_yaw
		VectorSubtract(goal->s.origin, self->s.origin, delta);
		self->ideal_yaw = vectoyaw(delta);
	}

	if ( (rand()&3)==1 || !SV_StepDirection (self, self->ideal_yaw, dist))
	{
		SV_NewChaseDir (self, goal, dist);
	}

	self->goalentity = NULL;
	G_FreeEdict(goal);

	return true;
}
Exemplo n.º 7
0
/*
======================
M_MoveToGoal
======================
*/
void M_MoveToGoal(edict_t *ent, float dist){
	edict_t	*goal;
	
	goal = ent->goalentity;
	
	if(!ent->groundentity && !(ent->flags &(FL_FLY | FL_SWIM)))
		return;
		
	// if the next step hits the enemy, return immediately
	if(ent->enemy && SV_CloseEnough(ent, ent->enemy, dist))
		return;
		
	// bump around...
	if((rand()&3) == 1 || !SV_StepDirection(ent, ent->ideal_yaw, dist)){
		if(ent->inuse)
			SV_NewChaseDir(ent, goal, dist);
	}
}
Exemplo n.º 8
0
/*
======================
M_MoveToGoal
======================
*/
void M_MoveToGoal (edict_t *ent, float dist)
{
    edict_t		*goal;

    goal = ent->goalentity;

    if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)))
        return;

// if the next step hits the enemy, return immediately
    if (ent->enemy &&  SV_CloseEnough (ent, ent->enemy, dist) )
        return;

// bump around...
//	if ( (rand()&3)==1 || !SV_StepDirection (ent, ent->ideal_yaw, dist))
// PMM - charging monsters (AI_CHARGING) don't deflect unless they have to
    if ( (((rand()&3)==1) && !(ent->monsterinfo.aiflags & AI_CHARGING)) || !SV_StepDirection (ent, ent->ideal_yaw, dist))
    {
        if (ent->inuse)
            SV_NewChaseDir (ent, goal, dist);
    }
}
Exemplo n.º 9
0
/*
======================
M_MoveToGoal
======================
*/
void M_MoveToGoal (edict_t *ent, float dist)
{
    edict_t		*goal;

    goal = ent->goalentity;

    if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)))
        return;

    // if the next step hits the enemy, return immediately
    if (ent->enemy &&  SV_CloseEnough (ent, ent->enemy, dist) )
        return;

    if ( (((rand()&3)==1) && !(ent->monsterinfo.aiflags & AI_CHARGING)) || !SV_StepDirection (ent, ent->ideal_yaw, dist))
    {
        if (ent->monsterinfo.aiflags & AI_BLOCKED)
        {
            ent->monsterinfo.aiflags &= ~AI_BLOCKED;
            return;
        }
        if (ent->inuse)
            SV_NewChaseDir (ent, goal, dist);
    }
}
Exemplo n.º 10
0
/*
======================
M_MoveToGoal
======================
*/
void M_MoveToGoal (edict_t *ent, float dist)
{
	edict_t		*goal;

	goal = ent->goalentity;

	if (ent->holdtime > level.time) // stay in-place for medic healing
		return;

	if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)) && !ent->waterlevel)
	{
		//gi.dprintf("not touching ground\n");
		return;
	}

// if the next step hits the enemy, return immediately
	if (ent->enemy && (ent->enemy->solid == SOLID_BBOX) 
		&& SV_CloseEnough (ent, ent->enemy, dist) )
//GHz START
	{
		vec3_t v;

		// we need to keep turning to avoid getting stuck doing nothing
		if (ent->goalentity && ent->goalentity->inuse) // 3.89 make sure the monster still has a goal!
		{
			VectorSubtract(ent->goalentity->s.origin, ent->s.origin, v);
			VectorNormalize(v);
			ent->ideal_yaw = vectoyaw(v);
			M_ChangeYaw(ent);
		}
		return;
	}
//GHz END

	// dont move so fast in the water
	if (!(ent->flags & (FL_FLY|FL_SWIM)) && (ent->waterlevel > 1))
		dist *= 0.5;

// bump around...
	// if we can't take a step, try moving in another direction
	if (!SV_StepDirection (ent, ent->ideal_yaw, dist, true))
	{
		//gi.dprintf("couldnt step\n");
		// if the monster hasn't moved much, then increment
		// the number of frames it has been stuck
		if (distance(ent->s.origin, ent->monsterinfo.stuck_org) < 64)
			ent->monsterinfo.stuck_frames++;
		else
			ent->monsterinfo.stuck_frames = 0;

		// record current position for comparison
		VectorCopy(ent->s.origin, ent->monsterinfo.stuck_org);

		// attempt a course-correction
		if (ent->inuse && (level.time > ent->monsterinfo.bump_delay))
		{
			//gi.dprintf("tried course correction %s\n", ent->goalentity?"true":"false");
			SV_NewChaseDir (ent, goal, dist);
			ent->monsterinfo.bump_delay = level.time + FRAMETIME*GetRandom(2, 5);
			return;
		}
	}
}
Exemplo n.º 11
0
/*
======================
M_MoveToGoal
======================
*/
void M_MoveToGoal (edict_t *ent, float dist)
{
	edict_t		*goal;
	
	goal = ent->goalentity;

	if (!ent->groundentity && !(ent->flags & (FL_FLY|FL_SWIM)))
		return;

	// Lazarus range checks
	if (!(ent->monsterinfo.aiflags & (AI_CHASE_THING | AI_CHICKEN)))
	{
		if (ent->enemy && (ent->monsterinfo.min_range > 0) && ((goal==ent->enemy) || !goal) ) {
			float dist;
			dist = realrange(ent,ent->enemy);
			if(dist < ent->monsterinfo.min_range)
			{
				ent->monsterinfo.aiflags |= (AI_STAND_GROUND | AI_RANGE_PAUSE);
				ent->monsterinfo.rangetime = level.time + 0.5;
				ent->monsterinfo.stand(ent);
				return;
			}
		}
		if ((ent->enemy) && (level.time > ent->monsterinfo.rangetime + 0.5) && ((goal==ent->enemy) || !goal) )
		{
			float dist;
			dist = realrange(ent,ent->enemy);
			if((dist < ent->monsterinfo.ideal_range[0]) && (rand() & 3))
			{
				ent->monsterinfo.aiflags |= (AI_STAND_GROUND | AI_RANGE_PAUSE);
				ent->monsterinfo.rangetime = level.time + 1.0;
				ent->monsterinfo.stand(ent);
				return;
			}
			if((dist < ent->monsterinfo.ideal_range[1]) && (dist > ent->monsterinfo.ideal_range[0]) && (rand() & 1))
			{
				ent->monsterinfo.aiflags |= (AI_STAND_GROUND | AI_RANGE_PAUSE);
				ent->monsterinfo.rangetime = level.time + 0.2;
				ent->monsterinfo.stand(ent);
				return;
			}
		}
	}

	if( (ent->monsterinfo.aiflags & AI_FOLLOW_LEADER) &&
		(ent->movetarget) &&
		(ent->movetarget->inuse) &&
		(ent->movetarget->health > 0) ) {

		if(ent->enemy)
			ent->monsterinfo.currentmove = &actor_move_run;
		else
		{
			float	R;

			R = realrange(ent,ent->movetarget);
			if(R > ACTOR_FOLLOW_RUN_RANGE)
				ent->monsterinfo.currentmove = &actor_move_run;
			else if(R < ACTOR_FOLLOW_STAND_RANGE && ent->movetarget->client) {
				ent->monsterinfo.pausetime = level.time + 0.5;
				ent->monsterinfo.currentmove = &actor_move_stand;
				return;
			}
			else
				ent->monsterinfo.currentmove = &actor_move_walk;
		}
	}

//	If the next step hits the enemy, return immediately. Don't do this for
//	AI_CHASE_THING, since we want monster to actually touch or pass through
//	"thing"
	if (ent->enemy && !(ent->monsterinfo.aiflags & AI_CHASE_THING) && SV_CloseEnough (ent, ent->enemy, dist) )
		return;

// bump around...
	if ( (rand()&3)==1 || !SV_StepDirection (ent, ent->ideal_yaw, dist))
	{
		if (ent->inuse)
			SV_NewChaseDir (ent, goal, dist);
	}
}