示例#1
0
文件: drop2.c 项目: MrPnut/QHome
// Electrocute whoever's in the water
void ToasterElec ( )
{
	gedict_t *te;

	self->s.v.effects = 4;
	sound(self, 1, "weapons/lhit.wav", 1, 1);
	if ( self->s.v.waterlevel > 0 )
	{
		te = findradius( world, self->s.v.origin, 950 );
		while ( te )
		{
			if ( streq( te->s.v.classname, "player" ) && te->s.v.waterlevel > 1 ) {
				if ( te->radsuit_finished < g_globalvars.time ) {
					mtf_deathmsg( 7 );
					TF_T_Damage( te, self, PROG_TO_EDICT( self->s.v.owner ), 250, 2, 0 );
				}
			}
			te = findradius( te, self->s.v.origin, 950 );
		}
		dremove( self );
	}
	else {
		dremove( self );
		return;
	}
}
示例#2
0
///////////////////////////////////////////////////////////////////////
// Pick best goal based on importance and range. This function
// overrides the long range goal selection for items that
// are very close to the bot and are reachable.
///////////////////////////////////////////////////////////////////////
void ACEAI_PickShortRangeGoal(edict_t *self)
{
	edict_t *target;
	float weight,best_weight=0.0;
	edict_t *best;
	int index;
	
	// look for a target (should make more efficent later)
	target = findradius(NULL, self->s.origin, 200);
	
	while (target)
	{
		if (target->classname == NULL)
			return;
		
		// Missle avoidance code
		// Set our movetarget to be the rocket or grenade fired at us. 
		if (strcmp(target->classname,"rocket")==0 || strcmp(target->classname,"grenade")==0
			|| strcmp(target->classname,"homing rocket")==0)
		{
			if(debug_mode) 
				debug_printf("ROCKET ALERT!\n");

			self->movetarget = target;
			return;
		}
	
		if (ACEIT_IsReachable(self,target->s.origin))
		{
			if (infront(self, target))
			{
				index = ACEIT_ClassnameToIndex(target->classname);
				weight = ACEIT_ItemNeed(self, index);
				
				if(weight > best_weight)
				{
					best_weight = weight;
					best = target;
				}
			}
		}

		// next target
		target = findradius(target, self->s.origin, 200);
	}

	if (best_weight)
	{
		self->movetarget = best;
		
		if(debug_mode && self->goalentity != self->movetarget)
			debug_printf("%s selected a %s for SR goal.\n",self->client->pers.netname, self->movetarget->classname);
		
		self->goalentity = best;

	}

}
示例#3
0
static qboolean BOT_DMclass_FindRocket( edict_t *self, vec3_t away_from_rocket )
{
#define AI_ROCKET_DETECT_RADIUS 1000
#define AI_ROCKET_DANGER_RADIUS 200
	edict_t *target = findradius( NULL, NULL, self->s.origin, AI_ROCKET_DETECT_RADIUS );
	float min_roxx_time = 1.0f;
	qboolean any_rocket = qfalse;

	while( target )
	{
		// Missile detection code
		if( target->r.svflags & SVF_PROJECTILE && target->s.type != ET_PLASMA ) // (plasmas come in bunchs so are too complex for the bot to dodge)
		{
			if( target->r.owner && target->r.owner != self )
			{
				vec3_t end;
				trace_t trace;

				VectorMA( target->s.origin, 2, target->velocity, end );
				G_Trace( &trace, target->s.origin, target->r.mins, target->r.maxs, end, target, MASK_SOLID );
				if( trace.fraction < min_roxx_time )
				{
					vec_t l;

					any_rocket = qtrue;
					min_roxx_time = trace.fraction;
					VectorSubtract( trace.endpos, self->s.origin, end );
					// ok... end is where the impact will be.
					// trace.fraction is the time.

					if( ( l = VectorLengthFast( end ) ) < AI_ROCKET_DANGER_RADIUS )
					{
						RotatePointAroundVector( away_from_rocket, axis_identity[UP], end, -self->s.angles[YAW] );
						VectorNormalize( away_from_rocket );

						if( fabs( away_from_rocket[0] ) < 0.3 ) away_from_rocket[0] = 0;
						if( fabs( away_from_rocket[1] ) < 0.3 ) away_from_rocket[1] = 0;
						away_from_rocket[2] = 0;
						away_from_rocket[0] *= -1.0f;
						away_from_rocket[1] *= -1.0f;

						if( nav.debugMode && bot_showcombat->integer > 2 )
							G_PrintChasersf( self, "%s: ^1projectile dodge: ^2%f, %f d=%f^7\n", self->ai.pers.netname, away_from_rocket[0], away_from_rocket[1], l );
					}
				}
			}
		}
		target = findradius( target, NULL, self->s.origin, AI_ROCKET_DETECT_RADIUS );
	}

	return any_rocket;

#undef AI_ROCKET_DETECT_RADIUS
#undef AI_ROCKET_DANGER_RADIUS
}
示例#4
0
void p_berserk_crush (edict_t *self, int damage, float range, int mod)
{
	trace_t tr;
	edict_t *other=NULL;
	vec3_t	v;

	// must be on the ground to punch
	if (!self->groundentity)
		return;

	self->lastsound = level.framenum;

	gi.sound (self, CHAN_AUTO, gi.soundindex ("tank/tnkatck5.wav"), 1, ATTN_NORM, 0);
	
	while ((other = findradius(other, self->s.origin, range)) != NULL)
	{
		if (!G_ValidTarget(self, other, true))
			continue;
		if (!nearfov(self, other, 0, 30))
			continue;

		VectorSubtract(other->s.origin, self->s.origin, v);
		VectorNormalize(v);
		tr = gi.trace(self->s.origin, NULL, NULL, other->s.origin, self, (MASK_PLAYERSOLID | MASK_MONSTERSOLID));
		T_Damage (other, self, self, v, other->s.origin, tr.plane.normal, damage, damage, 0, mod);
		other->velocity[2] += damage / 2;
	}
}
示例#5
0
/*
========================
objective_area
========================
*/
void objective_area_think (edict_t *self) {

	edict_t *ent  = NULL;
	int count = 0;
	int newteam = 0;
	int delay;

	self->nextthink = level.time + FRAMETIME;

	if (self->delay) // if there's a counter running
	{
	}

	while ((ent = findradius(ent, self->s.origin, self->obj_area)) != NULL)
	{
		if (!ent->inuse)
			continue;
		if (!IsValidPlayer(ent))
			continue;

		newteam = ent->client->resp.team_on->index;

		if (newteam != self->obj_owner)
			count++;

		//gi.dprintf(DEVELOPER_MSG_GAME, "Found %d players\n", count);		
	}

	if (count >= self->obj_count) {

		team_list[self->obj_owner]->score -= self->obj_loss;

		self->obj_owner = team_list[newteam]->index;
		team_list[self->obj_owner]->score += self->obj_gain;

		if (team_list[self->obj_owner]->time_to_win) // If there already is a counter somwhere else
		{
			if (team_list[self->obj_owner]->time_to_win > (self->obj_time + level.time) )
			// If the counter is longer, shorten it up to this one
				team_list[self->obj_owner]->time_to_win = (self->obj_time + level.time);
		} else // there is no counter
			team_list[self->obj_owner]->time_to_win = (self->obj_time + level.time);

		delay = (int)(team_list[self->obj_owner]->time_to_win - level.time);

		if ((delay/60) >= 1)
			safe_bprintf(PRINT_HIGH, "Team %s has %i minutes before they win the battle.\n", team_list[self->obj_owner]->teamname, (delay/60));
		else
			safe_bprintf(PRINT_HIGH, "Team %s has %i seconds before they win the battle.\n", team_list[self->obj_owner]->teamname, delay);

		gi.sound(self, CHAN_NO_PHS_ADD, gi.soundindex(va("%s/objectives/area_cap.wav", team_list[self->obj_owner]->teamid)), 1, 0, 0);

		if (dedicated->value)
			safe_cprintf(NULL, PRINT_HIGH, "Objective %s taken by team %s!\n",  self->obj_name,  team_list[self->obj_owner]->teamname);

		centerprintall("Objective %s taken\n by team %s!\n", 
			self->obj_name, 
			team_list[self->obj_owner]->teamname);
	}
}
示例#6
0
文件: ai.c 项目: yquake2/zaero
/*
=============
zSchoolAllVisiable

Creates a list of all entities in the raduis of Z_RADUISLISTSIZE
==============
*/
void zCreateRaduisList(edict_t *self)
{
	edict_t *head, *list;
  vec3_t vec;

	if(self->zRaduisList)
  { 
    // already created for this think, don't bother doing it again...
  	return;
  }

  head = NULL;
  list = self;

  while(1)
  {
		head = findradius(head, self->s.origin, Z_RADUISLISTSIZE);
		if(head == NULL)
			break;

    if(head != self)
    {
	  	list->zRaduisList = head;
		  VectorSubtract(self->s.origin, head->s.origin, vec);
		  head->zDistance = VectorLength(vec);
  	  list = head;
    }
  }

  list->zRaduisList = NULL;
};
示例#7
0
/*
============
T_RadiusDamage
============
*/
void T_RadiusDamage (edict_t *inflictor, edict_t *attacker, float damage, edict_t *ignore, float radius, int mod)
{
	float	points;
	edict_t	*ent = NULL;
	vec3_t	v;
	vec3_t	dir;

	while ((ent = findradius(ent, inflictor->s.origin, radius)) != NULL)
	{
		if (ent == ignore)
			continue;
		if (!ent->takedamage)
			continue;

		VectorAdd (ent->mins, ent->maxs, v);
		VectorMA (ent->s.origin, 0.5, v, v);
		VectorSubtract (inflictor->s.origin, v, v);
		points = damage - 0.5 * VectorLength (v);
		if (ent == attacker)
			points = points * 0.5;
		if (points > 0)
		{
			if (CanDamage (ent, inflictor))
			{
				VectorSubtract (ent->s.origin, inflictor->s.origin, dir);
				T_Damage (ent, inflictor, attacker, dir, inflictor->s.origin, vec3_origin, (int)points, (int)points, DAMAGE_RADIUS, mod);
			}
		}
	}
}
示例#8
0
edict_t *medic_FindDeadMonster (edict_t *self)
{
  edict_t  *ent = NULL;
  edict_t  *best = NULL;

  while ((ent = findradius(ent, self->s.origin, 1024)) != NULL)
  {
    if (ent == self)
      continue;
    if (!(ent->svflags & SVF_MONSTER))
      continue;
    if (ent->monsterinfo.aiflags & AI_GOOD_GUY)
      continue;
    if (ent->owner)
      continue;
    if (ent->health > 0)
      continue;
    if (ent->nextthink)
      continue;
    if (!visible(self, ent))
      continue;
    if (!best)
    {
      best = ent;
      continue;
    }
    if (ent->max_health <= best->max_health)
      continue;
    best = ent;
  }

  return best;
}
示例#9
0
void PlagueCloudSpawn (edict_t *ent)
{
	float	radius;
	edict_t *e=NULL;

	if (ent->myskills.abilities[PLAGUE].disable)
		return;

	if (!V_CanUseAbilities(ent, PLAGUE, 0, false))
		return;

	if ((ent->myskills.class_num == CLASS_POLTERGEIST) && !ent->mtype && !PM_PlayerHasMonster(ent))
		return; // can't use this in human form

	radius = PLAGUE_DEFAULT_RADIUS+PLAGUE_ADDON_RADIUS*ent->myskills.abilities[PLAGUE].current_level;

	if (radius > PLAGUE_MAX_RADIUS)
		radius = PLAGUE_MAX_RADIUS;

	// find someone nearby to infect
	while ((e = findradius(e, ent->s.origin, radius)) != NULL)
	{
		if (!G_ValidTarget(ent, e, true))
			continue;
	//	if (HasActiveCurse(e, CURSE_PLAGUE))
		if (que_typeexists(e->curses, CURSE_PLAGUE))
			continue;
		// holy water grants temporary immunity to curses
		if (e->holywaterProtection > level.time)
			continue;

		PlagueCloud(ent, e);
	}
}
示例#10
0
void mytank_meleeattack (edict_t *self)
{
	int damage;
	trace_t tr;
	edict_t *other=NULL;
	vec3_t	v;

	// tank must be on the ground to punch
	if (!self->groundentity)
		return;

	self->lastsound = level.framenum;

	damage = 100+20*self->monsterinfo.level;
	gi.sound (self, CHAN_AUTO, gi.soundindex ("tank/tnkatck5.wav"), 1, ATTN_NORM, 0);
	
	while ((other = findradius(other, self->s.origin, 128)) != NULL)
	{
		if (!G_ValidTarget(self, other, true))
			continue;
		// bosses don't have to be facing their enemy, others do
		//if ((self->monsterinfo.control_cost < 3) && !nearfov(self, other, 0, 60))//!infront(self, other))
		//	continue;

		VectorSubtract(other->s.origin, self->s.origin, v);
		VectorNormalize(v);
		tr = gi.trace(self->s.origin, NULL, NULL, other->s.origin, self, (MASK_PLAYERSOLID | MASK_MONSTERSOLID));
		T_Damage (other, self, self, v, tr.endpos, tr.plane.normal, damage, 200, 0, MOD_TANK_PUNCH);
		//other->velocity[2] += 200;//damage / 2;
	}
}
示例#11
0
void plague_think (edict_t *self)
{
	int		dmg;
	float	radius;
	edict_t *e=NULL;
	
	// plague self-terminates if:
	if (!G_EntIsAlive(self->owner) || !G_EntIsAlive(self->enemy)	//someone dies
		|| (self->owner->flags & FL_WORMHOLE)						// owner enters a wormhole
		|| (self->owner->client->tball_delay > level.time)			//owner tballs away
		|| (self->owner->flags & FL_CHATPROTECT)					//3.0 owner is in chatprotect
		|| ((self->owner->myskills.class_num == CLASS_POLTERGEIST) && (!self->owner->mtype) && !PM_PlayerHasMonster(self->owner))  //3.0 poltergeist is in human form
		|| que_findtype(self->enemy->curses, NULL, HEALING) != NULL)	//3.0 player is blessed with healing
	{
		que_removeent(self->enemy->curses, self, true);
		return;
	}

	VectorCopy(self->enemy->s.origin, self->s.origin); // follow enemy

	radius = PLAGUE_DEFAULT_RADIUS+PLAGUE_ADDON_RADIUS*self->owner->myskills.abilities[PLAGUE].current_level;

	if (radius > PLAGUE_MAX_RADIUS)
		radius = PLAGUE_MAX_RADIUS;

	// find someone nearby to infect
	while ((e = findradius(e, self->s.origin, radius)) != NULL)
	{
		if (e == self->enemy)
			continue;
		if (!G_ValidTarget(self, e, true))
			continue;
		// don't allow more than one curse of the same type
		if (que_typeexists(e->curses, CURSE_PLAGUE))
			continue;
		// holy water grants temporary immunity to curses
		if (e->holywaterProtection > level.time)
			continue;
		// spawn another plague cloud on this entity
		PlagueCloud(self->owner, e);
	}

	if (level.time > self->wait)
	{
		dmg = (float)self->owner->myskills.abilities[PLAGUE].current_level/10 * ((float)self->enemy->max_health/20);
		if (!self->enemy->client && strcmp(self->enemy->classname, "player_tank") != 0)
			dmg *= 2; // non-clients take double damage (helps with pvm)
		if (dmg < 1)
			dmg = 1;
		if (dmg > 100)
			dmg = 100;
		T_Damage(self->enemy, self->enemy, self->owner, vec3_origin, self->enemy->s.origin, vec3_origin, 
			dmg, 0, DAMAGE_NO_ABILITIES, MOD_PLAGUE); // hurt 'em
		self->wait = level.time + PLAGUE_DELAY;
	}
	
	self->nextthink = level.time + FRAMETIME;

}
示例#12
0
 void
 bfg_explode ( edict_t *self )
 {
   edict_t *ent;
   float points;
   vec3_t v;
   float dist;

   if ( !self ) {
     return;
   }

   if ( self->s.frame == 0 ) {
     /* the BFG effect */
     ent = NULL;

     while ( ( ent = findradius ( ent, self->s.origin, self->dmg_radius ) ) != NULL ) {
       if ( !ent->takedamage ) {
         continue;
       }

       if ( ent == self->owner ) {
         continue;
       }

       if ( !CanDamage ( ent, self ) ) {
         continue;
       }

       if ( !CanDamage ( ent, self->owner ) ) {
         continue;
       }

       VectorAdd ( ent->mins, ent->maxs, v );
       VectorMA ( ent->s.origin, 0.5, v, v );
       VectorSubtract ( self->s.origin, v, v );
       dist = VectorLength ( v );
       points = self->radius_dmg * ( 1.0 - sqrt ( dist / self->dmg_radius ) );

       if ( ent == self->owner ) {
         points = points * 0.5;
       }

       gi.WriteByte ( svc_temp_entity );
       gi.WriteByte ( TE_BFG_EXPLOSION );
       gi.WritePosition ( ent->s.origin );
       gi.multicast ( ent->s.origin, MULTICAST_PHS );
       T_Damage ( ent, self, self->owner, self->velocity, ent->s.origin, vec3_origin,
                  ( q_int32_t ) points, 0, DAMAGE_ENERGY, MOD_BFG_EFFECT );
     }
   }

   self->nextthink = level.time + FRAMETIME;
   self->s.frame++;

   if ( self->s.frame == 5 ) {
     self->think = G_FreeEdict;
   }
 }
示例#13
0
文件: m_medic.c 项目: qbism/qbq2
edict_t *medic_FindDeadMonster (edict_t *self)
{
	edict_t	*ent = NULL;
	edict_t	*best = NULL;

	while ((ent = findradius(ent, self->s.origin, 1024)) != NULL)
	{
		if (ent == self)
			continue;
		if (!(ent->svflags & SVF_MONSTER))
			continue;
		if (ent->monsterinfo.aiflags & AI_GOOD_GUY)
			continue;
		if (ent->owner)
			continue;
		if (ent->health > 0)
			continue;
		if (ent->nextthink && (ent->think != M_FliesOff) && (ent->think != M_FliesOn))
			continue;
		// check to make sure we haven't bailed on this guy already
		if ((ent->monsterinfo.badMedic1 == self) || (ent->monsterinfo.badMedic2 == self))
			continue;
		if (!visible(self, ent))
			continue;
		if (embedded(ent))
			continue;
		if (!canReach(self,ent))
			continue;
		if (!best)
		{
			best = ent;
			continue;
		}
		if (ent->max_health <= best->max_health)
			continue;
		best = ent;
	}

	if(best)
	{
		self->oldenemy = self->enemy;
		self->enemy = best;
		self->enemy->owner = best;
		self->monsterinfo.aiflags |= AI_MEDIC;
		self->monsterinfo.aiflags &= ~AI_MEDIC_PATROL;
		self->monsterinfo.medicTries = 0;
		self->movetarget = self->goalentity = NULL;
		self->enemy->monsterinfo.healer = self;
		self->timestamp = level.time + MEDIC_TRY_TIME;
		FoundTarget (self);

		if(developer->value)
			gi.dprintf("medic found dead monster: %s at %s\n",
			best->classname,vtos(best->s.origin));

	}
	return best;
}
示例#14
0
void GetNearbyTeammates(edict_t *self, char *buf)
{
        unsigned char nearby_teammates[10][16];
        int nearby_teammates_num, l;
        edict_t *ent = NULL;

        nearby_teammates_num = 0;
        
        while ((ent = findradius(ent, self->s.origin, 1500)) != NULL)
        {
                if (ent == self || !ent->client || !CanDamage(ent, self) || 
                        OnSameTeam(ent, self))
                        continue;

                strncpy(nearby_teammates[nearby_teammates_num], ent->client->pers.netname, 15);
                nearby_teammates[nearby_teammates_num][15] = 0; // in case their name is 15 chars...
                nearby_teammates_num++;
                if (nearby_teammates_num >= 10)
                        break;
        }
        
        if (nearby_teammates_num == 0)
        {
                strcpy(buf, "nobody");
                return;
        }

        for (l = 0; l < nearby_teammates_num; l++)
        {
                if (l == 0)
                {
                        strcpy(buf, nearby_teammates[l]);
                }
                        else
                {
                        if (nearby_teammates_num == 2)
                        {
                                strcat(buf, " and ");
                                strcat(buf, nearby_teammates[l]);
                        }
                                else
                        {
                                if (l == (nearby_teammates_num - 1))
                                {
                                        strcat(buf, ", and ");
                                        strcat(buf, nearby_teammates[l]);
                                }
                                        else
                                {
                                        strcat(buf, ", ");
                                        strcat(buf, nearby_teammates[l]);
                                }
                        }
                }
                
        }
}
示例#15
0
edict_t *medic_FindDeadMonster (edict_t *self)
{
	float	radius;
	edict_t	*ent = NULL;
	edict_t	*best = NULL;

	if (self->monsterinfo.aiflags & AI_STAND_GROUND)
		radius = MEDIC_MAX_HEAL_DISTANCE;
	else
		radius = 1024;

	while ((ent = findradius(ent, self->s.origin, radius)) != NULL)
	{
		if (ent == self)
			continue;
		if (!(ent->svflags & SVF_MONSTER))
			continue;
		if (ent->monsterinfo.aiflags & AI_GOOD_GUY)
			continue;
		// check to make sure we haven't bailed on this guy already
		if ((ent->monsterinfo.badMedic1 == self) || (ent->monsterinfo.badMedic2 == self))
			continue;
		if (ent->monsterinfo.healer)
			// FIXME - this is correcting a bug that is somewhere else
			// if the healer is a monster, and it's in medic mode .. continue .. otherwise
			//   we will override the healer, if it passes all the other tests
			if ((ent->monsterinfo.healer->inuse) && (ent->monsterinfo.healer->health > 0) &&
				(ent->monsterinfo.healer->svflags & SVF_MONSTER) && (ent->monsterinfo.healer->monsterinfo.aiflags & AI_MEDIC))
				continue;
		if (ent->health > 0)
			continue;
		if ((ent->nextthink) && !((ent->think == M_FliesOn) || (ent->think == M_FliesOff)))
			continue;
		if (!visible(self, ent))
//		if (!canReach(self, ent))
			continue;
		if (!strncmp(ent->classname, "player", 6))		 // stop it from trying to heal player_noise entities
			continue;
		// FIXME - there's got to be a better way ..
		// make sure we don't spawn people right on top of us
		if (realrange(self, ent) <= MEDIC_MIN_DISTANCE)
			continue;
		if (!best)
		{
			best = ent;
			continue;
		}
		if (ent->max_health <= best->max_health)
			continue;
		best = ent;
	}

	if (best)
		self->timestamp = level.time + MEDIC_TRY_TIME;

	return best;
}
示例#16
0
// Knightmare- check for grenades and lasers
qboolean gekk_check_jump_hazard (edict_t *self, qboolean watertoland, qboolean farjump)
{
	vec3_t	v;
	float	distance;
	trace_t	trace;
	vec3_t	oldorg, neworg, forward, dir;
	vec_t	g1, g2;
	edict_t	*grenade;

	if (!self->enemy) // pararnoia
		return false;

	//gi.dprintf ("Gekk: checking jump for hazards...\n");

	VectorSubtract(self->s.origin, self->enemy->s.origin, v);
	distance = VectorLength(v);

	VectorCopy (self->s.origin, oldorg);
	VectorCopy (self->enemy->s.origin, neworg);

	AngleVectors (self->s.angles, forward, NULL, NULL);

	trace = gi.trace (self->s.origin, self->mins, self->maxs, neworg, self, MASK_MONSTERSOLID);

	// Lazarus: Don't intentionally move closer to a grenade,
	//          but don't perform this check if we're already evading some
	//          other problem (maybe even this grenade)
	if(!(self->monsterinfo.aiflags & AI_CHASE_THING))
	{
		grenade = NULL;
		while( (grenade = findradius(grenade,neworg,128)) != NULL)
		{
			if(!grenade->inuse)
				continue;
			if(!grenade->classname)
				continue;
			if(!Q_strcasecmp(grenade->classname,"grenade") || !Q_strcasecmp(grenade->classname,"hgrenade"))
			{
				VectorSubtract(grenade->s.origin, oldorg, dir);
				g1 = VectorLength(dir);
				VectorSubtract(grenade->s.origin, neworg, dir);
				g2 = VectorLength(dir); 
				if (g2 < g1)
				{
					//gi.dprintf ("Gekk: Jump would put me closer to live grenade, aborting\n");
					return false;
				}
			}
		}
	}

	// Maybe we could could check for lasers using badarea fields?

	return true;
}
示例#17
0
void Cmd_Nova_f (edict_t *ent, int frostLevel, float skill_mult, float cost_mult)
{
	int		damage, cost=NOVA_COST*cost_mult;

	if (!G_CanUseAbilities(ent, ent->myskills.abilities[NOVA].current_level, cost))
		return;
	if (ent->myskills.abilities[NOVA].disable)
		return;

	damage = (NOVA_DEFAULT_DAMAGE+NOVA_ADDON_DAMAGE*ent->myskills.abilities[NOVA].current_level)*skill_mult;

	T_RadiusDamage(ent, ent, damage, ent, NOVA_RADIUS, MOD_NOVA);

	//Talent: Frost Nova
	if(frostLevel > 0)
	{
		edict_t	*target = NULL;

		while ((target = findradius(target, ent->s.origin, FROSTNOVA_RADIUS)) != NULL)
		{
			if (target == ent)
				continue;
			if (!target->takedamage)
				continue;
			if (!visible1(ent, target))
				continue;

            //curse with holyfreeze
			target->chill_level = 2 * frostLevel;
			target->chill_time = level.time + 3.0;	//3 second duration

			if (random() > 0.5)
				gi.sound(target, CHAN_ITEM, gi.soundindex("spells/blue1.wav"), 1, ATTN_NORM, 0);
			else
				gi.sound(target, CHAN_ITEM, gi.soundindex("spells/blue3.wav"), 1, ATTN_NORM, 0);
		}
	}		

	// write a nice effect so everyone knows we've cast a spell
	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_TELEPORT_EFFECT);
	gi.WritePosition (ent->s.origin);
	gi.multicast (ent->s.origin, MULTICAST_PVS);

	NovaExplosionEffect(ent->s.origin);
	gi.sound (ent, CHAN_WEAPON, gi.soundindex("spells/novaelec.wav"), 1, ATTN_NORM, 0);

	ent->client->ability_delay = level.time + NOVA_DELAY/* * cost_mult*/;
	ent->client->pers.inventory[power_cube_index] -= cost;

	// calling entity made a sound, used to alert monsters
	ent->lastsound = level.framenum;
}
示例#18
0
文件: engineer.c 项目: MrPnut/QHome
int CheckArea( gedict_t * obj, gedict_t * builder )
{
    vec3_t src;
    vec3_t end;
    int pos;
    gedict_t *te;

    pos = CheckAreaNew( obj, builder );
    if ( pos == 0 )
	return 0;

    pos = trap_pointcontents( PASSVEC3( obj->s.v.origin ) );
    if ( pos == CONTENT_SOLID || pos == CONTENT_SKY )
	return 0;
    src[0] = obj->s.v.origin[0]  + 24;
    src[1] = obj->s.v.origin[1]  + 24;
    src[2] = obj->s.v.origin[2]  + 16;
    pos = trap_pointcontents( PASSVEC3( src ) );
    if ( pos == CONTENT_SOLID || pos == CONTENT_SKY )
	return 0;
    end[0] = obj->s.v.origin[0]  - 16;
    end[1] = obj->s.v.origin[1]  - 16;
    end[2] = obj->s.v.origin[2]  - 16;
    traceline( PASSVEC3( src ), PASSVEC3( end ), 1, obj );
    if ( g_globalvars.trace_fraction != 1 )
	return 0;
    pos = trap_pointcontents( PASSVEC3( end ) );
    if ( pos == CONTENT_SOLID || pos == CONTENT_SKY )
	return 0;
    src[0] = obj->s.v.origin[0] - 16;
    src[1] = obj->s.v.origin[1] + 16;
    src[2] = obj->s.v.origin[2] + 16;
    pos = trap_pointcontents( PASSVEC3( src ) );
    if ( pos == CONTENT_SOLID || pos == CONTENT_SKY )
	return 0;
    end[0] = obj->s.v.origin[0] + 16;
    end[1] = obj->s.v.origin[1] - 16;
    end[2] = obj->s.v.origin[2] - 16;
    traceline( PASSVEC3( src ), PASSVEC3( end ), 1, obj );

    if ( g_globalvars.trace_fraction != 1 )
	return 0;
    pos = trap_pointcontents( PASSVEC3( end ) );
    if ( pos == CONTENT_SOLID || pos == CONTENT_SKY )
	return 0;
    traceline( PASSVEC3( builder->s.v.origin ), PASSVEC3( obj->s.v.origin ), 1, builder );
    if ( g_globalvars.trace_fraction != 1 )
	return 0;
    te = findradius( world, obj->s.v.origin, 64 );
    if ( te )
		return 0;
    return 1;
}
示例#19
0
qboolean NearbyLasers (edict_t *ent, vec3_t org)
{
	edict_t *e=NULL;

	while((e = findradius(e, org, 8)) != NULL)
	{
		// is this a laser than we own?
		if (e && e->inuse && G_EntExists(e->activator) 
			&& (e->activator == ent) && !strcmp(e->classname, "emitter"))
			return true;
	}

	return false;
}
示例#20
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;
}
示例#21
0
// returns true if there is a nearby, visible player boss
qboolean findNearbyBoss (edict_t *self)
{
	edict_t *other=NULL;

	while ((other = findradius(other, self->s.origin, BOSS_ALLY_BONUS_RANGE)) != NULL)
	{
		if (!IsABoss(other))
			continue;
		if (!G_EntIsAlive(other))
			continue;
		return true;
	}
	return false;
}
示例#22
0
qboolean NearbyProxy (edict_t *ent, vec3_t org)
{
	edict_t *e=NULL;

	while((e = findradius(e, org, 8)) != NULL)
	{
		// is this a proxy than we own?
		if (e && e->inuse && G_EntExists(e->owner) 
			&& (e->owner == ent) && !strcmp(e->classname, "proxygrenade"))
			return true;
	}

	return false;
}
示例#23
0
void salvation_think (edict_t *self)
{
	int		radius;
	edict_t *other=NULL;
	que_t	*slot=NULL;

	// check status of owner
	if (!CheckAuraOwner(self, COST_FOR_SALVATION))
	{
		que_removeent(self->owner->auras, self, true);
		return;
	}

	// use cubes
	if (!(level.framenum % DEFAULT_AURA_FRAMES))
	{
		int cube_cost = DEFAULT_AURA_COST;

		self->owner->client->pers.inventory[power_cube_index] -= cube_cost;
	}
	que_addent(self->owner->auras, self, DEFAULT_AURA_DURATION);
	// move aura with owner
	VectorCopy(self->owner->s.origin,self->s.origin);
	self->nextthink = level.time + FRAMETIME;
	if (level.framenum % DEFAULT_AURA_SCAN_FRAMES)
		return;

	radius = 256;

	// scan for targets
	while ((other = findradius (other, self->s.origin, radius)) != NULL)
	{
		slot = NULL;
		if (other == self->owner)
			continue;
		if (!G_EntExists(other))
			continue;
		if (other->health < 1)
			continue;
		if (OnSameTeam(self->owner, other) < 2)
			continue;
		if (!visible(self->owner, other))
			continue;
		slot = que_findtype(other->auras, slot, AURA_SALVATION);
		if (slot && (slot->ent->owner != self->owner))
			continue;
		que_addent(other->auras, self, DEFAULT_AURA_DURATION);
	}
}
static edict_t * 
FindEnemy(edict_t * self, int radius)
{
// loop through all nearby entities, looking for targets
	edict_t * ent = 0;
	int nPriority = 0; // 1 grenades, 2 clients, 3 pets
	int nPotentialPriority = 0;
	edict_t * enemy = 0;
	while ((ent = findradius(ent, self->s.origin, 500)) != NULL)

	{
		if ((ent->flags & FL_NOTARGET)||(ent->svflags & SVF_NOCLIENT))
			continue;
		if (!ent->inuse || !ent->takedamage || (ent->health <= 0))
			continue;
		if (EntIsMonster(ent))
		{
			if (OnSameTeam(ent, self))
				continue;
			nPotentialPriority = 3;
		}
		else if (EntIsClient(ent))
		{
			if (OnSameTeam(ent, self))
				continue;
			nPotentialPriority = 2;
		}
		else
		{
			// first priority is grenades
			// modify this if you don't want pets shooting grenades
			nPotentialPriority = 1;
		}

		if (nPriority>nPotentialPriority)
				continue;

		if (!visible(self, ent))
			continue;

		// remember this candidate enemy
		enemy = ent;
		nPriority = nPotentialPriority;
	}
	// return best we found (might be zero)
	return enemy;
}
示例#25
0
文件: g_combat.c 项目: andrijan/ajaq
/*
  ============
  T_RadiusDamage
  ============
*/
void
T_RadiusDamage (edict_t * inflictor, edict_t * attacker, float damage,
		edict_t * ignore, float radius, int mod)
{
	float points;
	edict_t *ent = NULL;
	vec3_t v;
	vec3_t dir;

	while ((ent = findradius (ent, inflictor->s.origin, radius)) != NULL)
	{
		if (ent == ignore)
			continue;
		if (!ent->takedamage)
			continue;

		VectorAdd (ent->mins, ent->maxs, v);
		VectorMA (ent->s.origin, 0.5, v, v);
		VectorSubtract (inflictor->s.origin, v, v);
		points = damage - 0.5 * VectorLength (v);
		//zucc reduce damage for crouching, max is 32 when standing
		if (ent->maxs[2] < 20)
		{
			points = points * 0.5;	// hefty reduction in damage
		}
		//if (ent == attacker)
		//points = points * 0.5; 
		if (points > 0)
		{
#ifdef _DEBUG
			if (0 == Q_stricmp (ent->classname, "func_explosive"))
			{
				CGF_SFX_ShootBreakableGlass (ent, inflictor, 0, mod);
			}
			else
#endif
			if (CanDamage (ent, inflictor))
			{
				VectorSubtract (ent->s.origin, inflictor->s.origin, dir);
				// zucc scaled up knockback(kick) of grenades
				T_Damage (ent, inflictor, attacker, dir, ent->s.origin,
				vec3_origin, (int) (points * .75),
				(int) (points * .75), DAMAGE_RADIUS, mod);
			}
		}
	}
}
示例#26
0
void CurseRadiusAttack (edict_t *caster, int type, int range, int radius, float duration, qboolean isCurse)
{
	edict_t *e=NULL, *f=NULL;

	// write a nice effect so everyone knows we've cast a spell
	gi.WriteByte (svc_temp_entity);
	gi.WriteByte (TE_TELEPORT_EFFECT);
	gi.WritePosition (caster->s.origin);
	gi.multicast (caster->s.origin, MULTICAST_PVS);

	caster->client->idle_frames = 0;
	caster->client->ability_delay = level.time;// for monster hearing (check if ability was recently used/cast)

	// find a target closest to the caster's reticle
	while ((e = findclosestreticle(e, caster, range)) != NULL)
	{
		if (!CanCurseTarget(caster, e, type, isCurse, true))
			continue;
		if (entdist(caster, e) > range)
			continue;
		if (!infront(caster, e))
			continue;
		if (!curse_add(e, caster, type, 0, duration))
			continue;
		CurseMessage(caster, e, type, duration, isCurse);

		// target anything in-range of this entity
		while ((f = findradius(f, e->s.origin, radius)) != NULL)
		{
			if (!CanCurseTarget(caster, f, type, isCurse, false))
				continue;
			if (f == e)
				continue;
			if (!visible(e, f))
				continue;
			if (!curse_add(f, caster, type, 0, duration))
				continue;
			CurseMessage(caster, f, type, duration, isCurse);
		}

		break;
	}
}
示例#27
0
/* ** wicked ** * jump grenade -- think
=================
Jumpgen_Think
=================
*/
void Jumpgen_Think (edict_t *ent)
{
	edict_t		*blip = NULL;
	vec3_t		dir, up;
	
	while ((blip = findradius(blip, ent->s.origin, 50)) != NULL){
		if (!strcmp(blip->classname, "player")){
			VectorCopy( dir, blip->velocity ); 
			AngleVectors (dir, NULL, NULL, up);
			blip->takedamage = DAMAGE_NO;
			VectorMA(blip->velocity, 1000, up, blip->velocity);
			blip->takedamage = DAMAGE_YES;
			G_FreeEdict (ent);
		}
	}
	ent->think = Jumpgen_Think;
	ent->nextthink = level.time + .1;

}
void homing_rocket_think(edict_t *ent)
{
	vec3_t to_target;
	vec_t speed;
	if (ent->homing_target == NULL)
	{
		while ((ent->homing_target = findradius(ent->homing_target, ent->s.origin, 1000)) != NULL)
		{
				if (!ent->homing_target->client)
					continue;
				if (!ent->homing_target->takedamage)
					continue;
				if (ent->homing_target->health <= 0)
					continue;
				if (!visible(ent, ent->homing_target))
					continue;
				if (ent->homing_target == ent->owner)
					continue;
				break;
		}
		ent->nextthink = level.time + .1;
		return;
	}
	else {
		VectorSubtract(ent->homing_target->s.origin, ent->s.origin, to_target);
		to_target[2] += 16;

		VectorNormalize(to_target);
		VectorScale(to_target, 0.3, to_target);
		VectorAdd(to_target, ent->movedir, to_target);
		VectorNormalize(to_target);
		VectorCopy(to_target, ent->movedir);
		vectoangles(to_target, ent->s.angles);
		speed = VectorLength(ent->velocity);
		VectorScale(to_target, speed, ent->velocity);
		ent->nextthink = level.time + .1;
	}
}
示例#29
0
void boss_punch (edict_t *self)
{
	int damage;
	trace_t tr;
	edict_t *other=NULL;
	vec3_t	v;

	if (!self->groundentity)
		return;

	damage = TANK_PUNCH_INITIAL_DAMAGE+TANK_PUNCH_ADDON_DAMAGE*self->monsterinfo.level;
//	T_RadiusDamage(self, self, damage, self, TANK_PUNCH_RADIUS, 0);
	gi.sound (self, CHAN_AUTO, gi.soundindex ("tank/tnkatck5.wav"), 1, ATTN_NORM, 0);
	

	while ((other = findradius(other, self->s.origin, 256)) != NULL)
	{
		if (other == self)
			continue;
		if (!other->inuse)
			continue;
		if (!other->takedamage)
			continue;
		if (other->solid == SOLID_NOT)
			continue;
		if (!other->groundentity)
			continue;
		if (OnSameTeam(self, other))
			continue;
		if (!visible(self, other))
			continue;
		VectorSubtract(other->s.origin, self->s.origin, v);
		VectorNormalize(v);
		tr = gi.trace(self->s.origin, NULL, NULL, other->s.origin, self, (MASK_PLAYERSOLID | MASK_MONSTERSOLID));
		T_Damage (other, self, self, v, other->s.origin, tr.plane.normal, damage, damage, 0, MOD_TANK_PUNCH);
		other->velocity[2] += damage / 2;
	}
}
示例#30
0
文件: engineer.c 项目: MrPnut/QHome
int CheckAreaNew( gedict_t * obj, gedict_t * builder )
{
    gedict_t *te;
    vec3_t end;

    TraceCapsule( PASSVEC3( obj->s.v.origin ), PASSVEC3( obj->s.v.origin ), 0, obj, PASSVEC3( obj->s.v.mins), PASSVEC3( obj->s.v.maxs) );
    if ( g_globalvars.trace_startsolid == 1 )
    {
	VectorCopy( obj->s.v.origin, end );
	end[2] -= 48;
	TraceCapsule( PASSVEC3( obj->s.v.origin ), PASSVEC3( end ), 0, obj, PASSVEC3( obj->s.v.mins), obj->s.v.maxs[0], obj->s.v.maxs[1], 4);
	VectorCopy( g_globalvars.trace_endpos, end );
	end[2]++;
	TraceCapsule( PASSVEC3( end ), PASSVEC3( end ), 0, obj, PASSVEC3( obj->s.v.mins), PASSVEC3( obj->s.v.maxs) );
	if ( g_globalvars.trace_startsolid == 1 )
	    return 0;
    }

    te = findradius( world, obj->s.v.origin, 64 );
    if ( te )
	return 0;
    
    return 1;
}