コード例 #1
0
ファイル: shaman.c プロジェクト: Ciclop/quake-2-vortex
void MindAbsorb(edict_t *ent) 
{  
	edict_t *target = NULL;  
	int radius;  
	int take;  
	int total;
	int abilityLevel = ent->myskills.abilities[MIND_ABSORB].current_level;   
	
	if(ent->myskills.abilities[MIND_ABSORB].disable)   
		return;   
	if (!V_CanUseAbilities(ent, MIND_ABSORB, 0, false))   
		return;   //Cloaking and chat protected players can't steal anything
	if ((ent->flags & FL_CHATPROTECT) || (ent->svflags & SVF_NOCLIENT))   
		return;   
	
	take = MIND_ABSORB_AMOUNT_BASE + (MIND_ABSORB_AMOUNT_BONUS * abilityLevel);  
	radius = MIND_ABSORB_RADIUS_BASE + (MIND_ABSORB_RADIUS_BONUS * abilityLevel);   
	
	// scan for targets  
	while ((target = findclosestradius(target, ent->s.origin, radius)) != NULL)  
	{   
		if (target == ent)    
			continue;   
		if (!G_ValidTarget(ent, target, true))    
			continue;   
		
		total = 0;
		
		if (target->client)
		{
			if (target->client->pers.inventory[power_cube_index] < take)
				total += target->client->pers.inventory[power_cube_index];
			else
				total += take;

			target->client->pers.inventory[power_cube_index] -= total;

			// a bit of amnesia too
			target->client->ability_delay = level.time + 0.1 * abilityLevel;  
		}
		else
		{
			if (target->health < take)
				total += target->health;
			else
				total += take;
		}

		//Cap cube count to max cubes 
		if (ent->client->pers.inventory[power_cube_index] + total < MAX_POWERCUBES(ent))
			ent->client->pers.inventory[power_cube_index] += total;
		else if (ent->client->pers.inventory[power_cube_index] < MAX_POWERCUBES(ent))
			ent->client->pers.inventory[power_cube_index] = MAX_POWERCUBES(ent); 

		// those powercubes hurt!  
		T_Damage(target, ent, ent, vec3_origin, vec3_origin, vec3_origin, total, 0, DAMAGE_NO_ARMOR, MOD_MINDABSORB);
	}  
}
コード例 #2
0
ファイル: magmine.c プロジェクト: zardoru/vrxcl
qboolean magmine_findtarget(edict_t *self) {
    edict_t *other = NULL;

    while ((other = findclosestradius(other,
                                      self->s.origin, self->dmg_radius)) != NULL) {
        if (!G_ValidTarget(self, other, true))
            continue;
        //if (!BrainValidTarget(self, other))
        //	continue;
        self->enemy = other;
        return true;
    }
    return false;
}
コード例 #3
0
ファイル: drone_medic.c プロジェクト: Ciclop/quake-2-vortex
// search for nearby enemies, return true if one is found
// this is to make the medic stop healing if there is a higher priority target
// this function is the same as drone_findtarget(), except that it skips the medic check
qboolean mymedic_findenemy (edict_t *self)
{
	edict_t *target=NULL;

	while ((target = findclosestradius (target, self->s.origin, 1024)) != NULL)
	{
		if (!G_ValidTarget(self, target, true))
			continue;
		self->enemy = target;
		drone_wakeallies(self);
		return true;
	}
	return false;
}
コード例 #4
0
qboolean myparasite_findtarget (edict_t *self)
{
	edict_t *other=NULL;
	int para_range = PARASITE_ATTACK_RANGE;

	while ((other = findclosestradius(other, self->s.origin, para_range)) != NULL)
	{
		if (!parasite_cantarget(self, other))
			continue;
		//if (!G_ValidTarget(self, other, true))
		//	return false;
		//if (!infov(self, other, 90))
		//	return false;
		self->enemy = other;
		return true;
	}
	return false;
}
コード例 #5
0
ファイル: totems.c プロジェクト: emmamai/vortex-indy
void WaterTotem_think(edict_t *self, edict_t *caster)
{
	edict_t *target = NULL;

	//Find players in radius and attack them.
	while ((target = findclosestradius(target, self->s.origin, TOTEM_MAX_RANGE)) != NULL)
	{
		// (apple)
		// Since ice talent and watertotem work concurrently now, 
		// checking for chill_duration will throttle ice talent's refire.
		if (G_ValidTarget(self, target, true))
		{
			vec3_t normal;
			int talentLevel;
			float duration = WATERTOTEM_DURATION_BASE + self->monsterinfo.level * WATERTOTEM_DURATION_MULT;

			//Get a directional vector from the totem to the target.
			VectorSubtract(self->s.origin, target->s.origin, normal);

			//Talent: Ice. Damages players.
			talentLevel = getTalentLevel(caster, TALENT_ICE);
			if(talentLevel > 0)
			{
				int damage = GetRandom(10, 20) * talentLevel;
				vec3_t normal;
				
				//Damage the target
				VectorSubtract(target->s.origin, self->s.origin, normal);				
				T_Damage(target, self, self, vec3_origin, self->s.origin, 
					normal, damage, 0, DAMAGE_NO_KNOCKBACK, MOD_WATERTOTEM);
			}
			
			//Chill the target.
			target->chill_level = self->monsterinfo.level;
			target->chill_time = level.time + duration;
			//gi.dprintf("chilled %s for %.1f seconds at level %d\n", target->classname, duration, self->monsterinfo.level);
			
		}
	}
	//Next think.
	self->delay = level.time + WATERTOTEM_REFIRE_BASE + WATERTOTEM_REFIRE_MULT * self->monsterinfo.level;
}
コード例 #6
0
ファイル: supplystation.c プロジェクト: zardoru/vrxcl
qboolean station_findtarget (edict_t *self)
{
	edict_t *e=NULL;

	while ((e = findclosestradius(e, self->s.origin, STATION_TARGET_RADIUS)) != NULL)
	{
		if (!ValidStationTarget(self, e))
			continue;
		if (!OnSameTeam(self, e))
		{
			gi.centerprintf(self->creator, "%s is using\nyour supply station!\n", 
				e->client->pers.netname);
			continue;
		}
		self->enemy = e;
		return true;
	}
	self->enemy = NULL;
	return false;
}
コード例 #7
0
ファイル: boss_general.c プロジェクト: mylemans/vrxcl
qboolean boss_findtarget (edict_t *boss)
{
	edict_t *target = NULL;

	while ((target = findclosestradius(target, boss->s.origin, BOSS_TARGET_RADIUS)) != NULL)
	{
		if (!G_ValidTarget(boss, target, true))
			continue;
		if (!infront(boss, target))
			continue;
		boss->enemy = target;
		//if (target->client)
		//	gi.dprintf("found %s\n", target->client->pers.netname);
		//else
		//	gi.dprintf("found target %s\n", target->classname);
	//	gi.sound (boss, CHAN_WEAPON, gi.soundindex ("tank/sight1.wav"), 1, ATTN_NORM, 0);
		return true;
	}
	return false;
}
コード例 #8
0
ファイル: minisentry.c プロジェクト: emmamai/vortex-indy
qboolean minisentry_findtarget (edict_t *self)
{
	edict_t	*target=NULL;

	// don't retarget too quickly
	if (self->last_move_time > level.time)
		return false;
	while ((target = findclosestradius (target, self->s.origin, SENTRY_TARGET_RANGE)) != NULL)
	{
		if (!G_ValidTarget(self, target, true))
			continue;
		if (!infov(self, target, SENTRY_FOV))
			continue;
		self->enemy = target;
		self->last_move_time = level.time + 1.0;
		gi.sound(self, CHAN_AUTO, gi.soundindex("weapons/turrspot.wav"), 1, ATTN_NORM, 0);
		return true;
	}
	return false;
}
コード例 #9
0
ファイル: corpseexplode.c プロジェクト: emmamai/vortex-indy
void Cmd_CorpseExplode(edict_t *ent)
{
	int		damage, min_dmg, max_dmg, slvl;
	float	fraction, radius;
	vec3_t	start, end, forward, right, offset;
	trace_t	tr;
	edict_t *e=NULL;

	if (debuginfo->value)
		gi.dprintf("DEBUG: %s just called Cmd_CorpseExplode()\n", ent->client->pers.netname);

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

	if (!G_CanUseAbilities(ent, ent->myskills.abilities[CORPSE_EXPLODE].current_level, COST_FOR_CORPSEEXPLODE))
		return;

	slvl = ent->myskills.abilities[CORPSE_EXPLODE].current_level;
	radius = CORPSE_EXPLOSION_INITIAL_RADIUS + CORPSE_EXPLOSION_ADDON_RADIUS * slvl;

	// calculate starting position
	AngleVectors (ent->client->v_angle, forward, right, NULL);
	VectorSet(offset, 0, 7,  ent->viewheight-8);
	P_ProjectSource(ent->client, ent->s.origin, offset, forward, right, start);
	VectorMA(start, CORPSE_EXPLOSION_MAX_RANGE, forward, end);
	tr = gi.trace(start, NULL, NULL, end, ent, MASK_SOLID);

	while ((e = findclosestradius (e, tr.endpos, CORPSE_EXPLOSION_SEARCH_RADIUS)) != NULL)
	{
		if (!G_EntExists(e))
			continue;
		if (e->health > 0)
			continue;
		if (e->max_health < 1)
			continue;

		// kill the corpse
		T_Damage(e, e, ent, vec3_origin, e->s.origin, vec3_origin, 10000, 0, DAMAGE_NO_PROTECTION, MOD_CORPSEEXPLODE);

		// inflict damage
		fraction = 0.1 * GetRandom(5, 10);
		damage = fraction * e->max_health;
		
		// calculate min/max damage range
		min_dmg = CORPSE_EXPLOSION_INITIAL_DAMAGE + CORPSE_EXPLOSION_ADDON_DAMAGE * slvl;
		max_dmg = 5 * min_dmg;

		if (damage < min_dmg)
			damage = min_dmg;
		else if (damage > max_dmg)
			damage = max_dmg;

		T_RadiusDamage (e, ent, damage, NULL, radius, MOD_CORPSEEXPLODE);

		//gi.dprintf("fraction %.1f, damage %d, max_health: %d\n", fraction, damage, e->max_health);

		//Spells like corpse explode shouldn't display 10000 damage, so show the corpse damage instead
		ent->client->ps.stats[STAT_ID_DAMAGE] = damage;

		gi.sound(e, CHAN_ITEM, gi.soundindex("spells/corpseexplodecast.wav"), 1, ATTN_NORM, 0);
		ent->client->pers.inventory[power_cube_index] -= COST_FOR_CORPSEEXPLODE;
		ent->client->ability_delay = level.time + DELAY_CORPSEEXPLODE;
		safe_cprintf(ent, PRINT_HIGH, "Corpse exploded for %d damage!\n", damage);

		//decino: explosion effect
		gi.WriteByte (svc_temp_entity);
		gi.WriteByte (TE_GRENADE_EXPLOSION);
		gi.WritePosition (e->s.origin);
		gi.multicast (e->s.origin, MULTICAST_PVS);

		//decino: shoot 6 gibs that deal damage
		//az: todo, more copypaste.
		/*for (i = 0; i < 10; i++)
		{
			e->s.angles[YAW] += 36;
			AngleCheck(&e->s.angles[YAW]);

			AngleVectors(e->s.angles, forward, NULL, up);
			fire_gib(ent, e->s.origin, forward, dmg, 0, 1000);
		}*/

		// calling entity made a sound, used to alert monsters
		ent->lastsound = level.framenum;

		break;
	}
}
コード例 #10
0
ファイル: totems.c プロジェクト: emmamai/vortex-indy
void FireTotem_think(edict_t *self, edict_t *caster)
{
	int talentLevel;
	float chance;
	edict_t *target = NULL;

	//Totem should not work underwater (gee I wonder why).
	if(!self->waterlevel)
	{
		//Talent: Volcanic
		talentLevel = getTalentLevel(caster, TALENT_VOLCANIC);
		chance = 0.02 * talentLevel;

		//Find players in radius and attack them.
		while ((target = findclosestradius(target, self->s.origin, TOTEM_MAX_RANGE)) != NULL)
		{
			if (G_ValidTarget(self, target, true) && (self->s.origin[2]+64>target->s.origin[2]))
			{
				vec3_t forward, end;
				int damage = FIRETOTEM_DAMAGE_BASE + self->monsterinfo.level * FIRETOTEM_DAMAGE_MULT;
				int count = 10 + self->monsterinfo.level;
				int speed = 600;
				float	val, dist;
				qboolean fireball=false;

				// copy target location
				G_EntMidPoint(target, end);

				// calculate distance to target
				dist = distance(end, self->s.origin);

				// move our target point based on projectile and enemy velocity
				VectorMA(end, (float)dist/speed, target->velocity, end);

				//Talent: Volcanic - chance to shoot a fireball
				if (talentLevel > 0 && chance > random())
					fireball = true;

				// aim up
				if (fireball)
					val = ((dist/2048)*(dist/2048)*2048) + (end[2]-self->s.origin[2]);//4.4
				else
					val = ((dist/512)*(dist/512)*512) + (end[2]-self->s.origin[2]);
				if (val < 0)
					val = 0;
				end[2] += val;

				// calculate direction vector to target
				VectorSubtract(end, self->s.origin, forward);
				VectorNormalize(forward);
				
				// don't fire in a perfectly straight line
				forward[1] += 0.05*crandom(); 

				// spawn flames
				if (fireball)
					fire_fireball(self, self->s.origin, forward, 200, 125, 600, 5, 20);//4.4
				else
					ThrowFlame(self, self->s.origin, forward, distance(self->s.origin, target->s.origin), speed, damage, GetRandom(2, 4));
				
				self->lastsound = level.framenum;

				// refire delay
				self->delay = level.time + FRAMETIME;
			}
		}
	}

}