Exemple #1
0
bool Utility::AntiHumanRadiusDamage(Entity& entity, float amount, float range, meansOfDeath_t mod) {
	bool hit = false;

	ForEntities<HumanClassComponent>([&] (Entity& other, HumanClassComponent& humanClassComponent) {
		// TODO: Add LocationComponent.
		float distance = G_Distance(entity.oldEnt, other.oldEnt);
		float damage   = amount * (1.0f - distance / range);

		if (damage <= 0.0f) return;
		if (!G_IsVisible(entity.oldEnt, other.oldEnt, MASK_SOLID)) return;

		if (other.Damage(damage, entity.oldEnt, {}, {}, DAMAGE_NO_LOCDAMAGE, mod)) {
			hit = true;
		}
	});

	return hit;
}
Exemple #2
0
bool Utility::KnockbackRadiusDamage(Entity& entity, float amount, float range, meansOfDeath_t mod) {
	bool hit = false;

	// FIXME: Only considering entities with HealthComponent.
	// TODO: Allow ForEntities to iterate over all entities.
	ForEntities<HealthComponent>([&] (Entity& other, HealthComponent& healthComponent) {
		// TODO: Add LocationComponent.
		float distance = G_Distance(entity.oldEnt, other.oldEnt);
		float damage   = amount * (1.0f - distance / range);

		if (damage <= 0.0f) return;
		if (!G_IsVisible(entity.oldEnt, other.oldEnt, MASK_SOLID)) return;

		if (other.Damage(damage, entity.oldEnt, {}, {}, DAMAGE_NO_LOCDAMAGE | DAMAGE_KNOCKBACK, mod)) {
			hit = true;
		}
	});

	return hit;
}
Exemple #3
0
void G_HomingMissile(gentity_t * ent)
{
	gentity_t      *target = NULL;
	gentity_t      *blip = NULL;
	vec3_t          dir, blipdir;
	vec_t           angle;
	qboolean        chaff;

	//qboolean        ignorechaff = qfalse;
	const int       HOMING_THINK_TIME = 60;

	// explode after 15 seconds without a hit
	if(ent->spawnTime + 15000 <= level.time)
	{
		G_ExplodeMissile(ent);
		return;
	}

	/*
	if(ent->parent->health <= 0)
	{
		ent->nextthink = level.time + 15000;
		ent->think = G_ExplodeMissile;
		return;
	}
	*/

	/*
	if(ent->parent && ent->parent->client)
	{
		ignorechaff = (ent->parent->client->ps.powerups[PW_ACCURACY] > 0);
	}
	*/

	while((blip = G_FindRadius(blip, ent->r.currentOrigin, 2000)) != NULL)
	{
#if 0
		if(blip->s.weapon == WP_CHAFF)
		{
			if(ignorechaff)
			{
				continue;
			}

			chaff = qtrue;
		}
		else
#endif
		{
			chaff = qfalse;

			if(blip->client == NULL)
				continue;

			if(blip == ent->parent)
				continue;

			if(blip->health <= 0)
				continue;

			if(blip->client->sess.sessionTeam >= TEAM_SPECTATOR)
				continue;

			if((g_gametype.integer == GT_TEAM || g_gametype.integer == GT_CTF) && OnSameTeam(blip, ent->parent))
				continue;
		}

		if(!G_IsVisible(ent, blip->r.currentOrigin))
			continue;

		VectorSubtract(blip->r.currentOrigin, ent->r.currentOrigin, blipdir);

		if(chaff)
		{
			VectorScale(blipdir, 0.5, blipdir);
		}

		if((target == NULL) || (VectorLength(blipdir) < VectorLength(dir)))
		{
			if(chaff)
			{
				VectorScale(blipdir, 2, blipdir);
			}

			angle = AngleBetweenVectors(ent->r.currentAngles, blipdir);

			if(angle < 120.0f)
			{
				// We add it as our target
				target = blip;
				VectorCopy(blipdir, dir);
			}
		}
	}

	if(target == NULL)
	{
		ent->nextthink = level.time + HOMING_THINK_TIME;	// + 10000;
		ent->think = G_HomingMissile;
	}
	else
	{
		// for exact trajectory calculation, set current point to base.
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase);

		VectorNormalize(dir);
		// 0.5 is swing rate.
		VectorScale(dir, 0.5, dir);
		VectorAdd(dir, ent->r.currentAngles, dir);

		// turn nozzle to target angle
		VectorNormalize(dir);
		VectorCopy(dir, ent->r.currentAngles);

		// scale direction, put into trDelta
		if(g_rocketAcceleration.integer)
		{
			// use acceleration instead of linear velocity
			ent->s.pos.trType = TR_ACCELERATION;
			ent->s.pos.trAcceleration = g_rocketAcceleration.value;
			VectorScale(dir, g_rocketVelocity.value, ent->s.pos.trDelta);
		}
		else
		{
			ent->s.pos.trType = TR_LINEAR;
			VectorScale(dir, g_rocketVelocity.value * 0.25, ent->s.pos.trDelta);
		}

		ent->s.pos.trTime = level.time;

		SnapVector(ent->s.pos.trDelta);	// save net bandwidth
		ent->nextthink = level.time + HOMING_THINK_TIME;	// decrease this value also makes fast swing
		ent->think = G_HomingMissile;

		//G_Printf("targeting %s\n", target->classname);
	}
}
/*
================
G_HomingMissile

From XREAL r3036
================
*/
void G_HomingMissile(gentity_t * ent)
{
	gentity_t      *target = NULL;
	gentity_t      *blip = NULL;
	vec3_t          dir, blipdir;
	vec_t           angle;
	const int		HOMING_THINK_TIME = 60;

#ifdef TA_WEAPSYS // XREAL: spawnTime
	// explode after 15 seconds without a hit
	if (bg_projectileinfo[ent->s.weapon].timetolive != -1
		&& ent->spawnTime + bg_projectileinfo[ent->s.weapon].timetolive <= level.time)
	{
		G_ExplodeMissile(ent);
		return;
	}
#endif

	/*
	if(ent->parent->health <= 0)
	{
		ent->nextthink = level.time + 15000;
		ent->think = G_ExplodeMissile;
		return;
	}
	*/

	while((blip = G_FindRadius(blip, ent->r.currentOrigin, 2000)) != NULL)
	{
		if(blip->player == NULL)
			continue;

		if(blip == ent->parent)
			continue;

		if(blip->health <= 0)
			continue;

		if(blip->flags & FL_NOTARGET)
			continue;

		if(blip->player->sess.sessionTeam >= TEAM_SPECTATOR)
			continue;

		if(OnSameTeam(blip, ent->parent))
			continue;

		if(!G_IsVisible(ent->s.number, ent->r.currentOrigin, blip->r.currentOrigin))
			continue;

		VectorSubtract(blip->r.currentOrigin, ent->r.currentOrigin, blipdir);

		if((target == NULL) || (VectorLength(blipdir) < VectorLength(dir)))
		{
			angle = AngleBetweenVectors(ent->r.currentAngles, blipdir);

			if(angle < 120.0f)
			{
				// We add it as our target
				target = blip;
				VectorCopy(blipdir, dir);
			}
		}
	}

	if (target == NULL)
	{
		ent->nextthink = level.time + HOMING_THINK_TIME;	// + 10000;
		ent->think = G_HomingMissile;
	}
	else
	{
		// for exact trajectory calculation, set current point to base.
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase);

		VectorNormalize(dir);
		// 0.5 is swing rate.
		VectorScale(dir, 0.5, dir);
		VectorAdd(dir, ent->r.currentAngles, dir);

		// turn nozzle to target angle
		VectorNormalize(dir);
		VectorCopy(dir, ent->r.currentAngles);

		ent->s.pos.trTime = level.time;
		G_SetMissileVelocity(ent, dir, ent->s.weapon);

		ent->nextthink = level.time + HOMING_THINK_TIME;	// decrease this value also makes fast swing
		ent->think = G_HomingMissile;

		//G_Printf("targeting %s\n", target->classname);
	}
}