Ejemplo n.º 1
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);
	}
}
Ejemplo n.º 2
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);
	}
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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);
    }
}
Ejemplo n.º 5
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);
    }
}
Ejemplo n.º 6
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;
		}
	}
}
Ejemplo 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;

	// 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);
	}
}