Exemplo n.º 1
0
qboolean NearestNodeLocation (vec3_t start, vec3_t node_loc, float range, qboolean vis)
{
	int		i=0, bestNodeNum=-1;
	float	dist, best=9999;
	vec3_t	v;

	if (!numnodes)
		return false;

	// get the nodenum for the closest node
	for ( ; i < numnodes; i++)
	{
		VectorCopy(pathnode[i], v);
		// ignore nodes we can't see
		if (vis && !G_IsClearPath(NULL, MASK_SOLID, v, start))
			continue;
		dist = distance(v, start);
		if (range && dist > range)
			continue;
		if (dist < best)
		{
			best = dist;
			bestNodeNum = i;
		}
	}
	
	if (bestNodeNum == -1)
		return false;

	VectorCopy(pathnode[bestNodeNum], node_loc);
	return true;

}
Exemplo n.º 2
0
// returns node index of node closest to start
int NearestNodeNumber (vec3_t start, float range, qboolean vis)
{
	int		i=0, bestNodeNum=-1;
	float	dist, best=9999;
	vec3_t	v;

	if (!numnodes)
		return -1;

	// get the nodenum for the closest node
	for ( ; i < numnodes; i++)
	{
		VectorCopy(pathnode[i], v);
		// ignore nodes we can't see
		if (vis && !G_IsClearPath(NULL, MASK_SOLID, v, start))
			continue;
		dist = distance(v, start);
		if (range && dist > range)
			continue;
		if (dist < best)
		{
			best = dist;
			bestNodeNum = i;
		}
	}

	return bestNodeNum;
}
Exemplo n.º 3
0
qboolean LandCloserToGoal (edict_t *self, vec3_t goal_pos, vec3_t landing_pos)
{
	// goal position path is obstructed by a wall
	if (!G_IsClearPath(self, MASK_SOLID, landing_pos, goal_pos))
		return false;
	// landing position places us farther from our goal
	if (distance(landing_pos, goal_pos) > distance(self->s.origin, goal_pos))
		return false;
	return true;
}
Exemplo n.º 4
0
void mybrain_continue (edict_t *self)
{
	float	dist, chance;
	vec3_t	start, forward;

	if (!G_ValidTarget(self, self->enemy, true))
		return;

	// higher chance to continue attack if our enemy is close
	dist = entdist(self, self->enemy);
	chance = 1-dist/1024.0;

	AngleVectors(self->s.angles, forward, NULL, NULL);
	VectorMA(self->s.origin, self->maxs[1]+8, forward , start);

	if (G_IsClearPath(self->enemy, MASK_SHOT, start, self->enemy->s.origin) 
		&& (random() <= chance) && (dist <= 512))
		self->monsterinfo.nextframe = FRAME_attak206;
	mybrain_suxor(self);
}
Exemplo n.º 5
0
void carpetbomb_think (edict_t *self)
{
	float		ceil;
	qboolean	failed = false;
	vec3_t		forward, right, start, end;
	trace_t		tr, tr1;

	if (!G_EntIsAlive(self->owner) || (level.time>self->delay))
	{
		G_FreeEdict(self);
		return;
	}

	// move forward
	AngleVectors(self->s.angles, forward, NULL, NULL);
	VectorMA(self->s.origin, GetRandom(CARPETBOMB_DAMAGE_RADIUS/2, CARPETBOMB_DAMAGE_RADIUS+1), forward, start);
	tr = gi.trace(self->s.origin, NULL, NULL, start, NULL, MASK_SOLID);
	VectorCopy(start, end);
	start[2]++;
	end[2] -= 8192;
	tr1 = gi.trace(start, NULL, NULL, end, NULL, MASK_SOLID);
	start[2]--;

	if ((tr.fraction < 1) || (start[2] != tr1.endpos[2]))
	{
		//gi.dprintf("will step down, start[2] %f tr1.endpos[2] %f\n", start[2], tr1.endpos[2]);
		// get current ceiling height
		VectorCopy(start, end);
		end[2] += 8192;
		tr = gi.trace(self->s.origin, NULL, NULL, end, NULL, MASK_SOLID);
		ceil = tr.endpos[2];

		// push down from above desired position
		start[2] += CARPETBOMB_STEP_SIZE;
		if ((start[2] > ceil)) // dont go thru ceiling
			start[2] = ceil;
		VectorCopy(start, end);
		end[2] -= 8192;
		tr = gi.trace(start, NULL, NULL, end, NULL, MASK_SOLID);

		// dont go thru walls
		if (tr.allsolid)
			failed = true;
		// try a bit lower
		if (tr.startsolid)
		{
			start[2] -= CARPETBOMB_STEP_SIZE;
			tr = gi.trace(start, NULL, NULL, end, NULL, MASK_SOLID);
			if (tr.startsolid || tr.allsolid)
				failed = true;
		}

		// dont go into water if we aren't already submerged
		VectorCopy(tr.endpos, start);
		start[2] += 8;
		if (!self->waterlevel && (gi.pointcontents(start) & MASK_WATER))
			failed = true;
	}

	// save position
	VectorCopy(tr.endpos, self->s.origin);
	VectorCopy(tr.endpos, start);
	// spawn explosions on either side
	// FIXME: step down from these positions, otherwise we get mid-air explosions!
	AngleVectors(self->s.angles, NULL, right, NULL);
	VectorMA(self->s.origin, (crandom()*GetRandom(CARPETBOMB_CARPET_WIDTH/4, CARPETBOMB_CARPET_WIDTH/2)), right, end);
	// make sure path is wide enough
	tr = gi.trace(self->s.origin, NULL, NULL, end, self, MASK_SHOT);
	VectorCopy(tr.endpos, self->s.origin);
	self->s.origin[2] += 32;

	//4.08 make sure the caster can see this spot
	//if (!visible(self->owner, self))
	if (!G_IsClearPath(self, MASK_SOLID, self->move_origin, self->s.origin))
		failed = true;

	// make sure bombspell is in a valid location
	if ((gi.pointcontents(self->s.origin) & CONTENTS_SOLID) || failed)
	{
		G_FreeEdict(self);
		return;
	}
	T_RadiusDamage(self, self->owner, self->dmg, NULL, self->dmg_radius, MOD_BOMBS);
	// write explosion effects
	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_EXPLOSION1);
	gi.WritePosition (self->s.origin);
	gi.multicast (self->s.origin, MULTICAST_PVS);

	VectorCopy(start, self->s.origin); // retrieve starting position
	self->nextthink = level.time + FRAMETIME;

	gi.linkentity(self);
}