Example #1
0
// Fire an anti-missile. Returns true if the missile should be killed.
bool Armament::Weapon::FireAntiMissile(Ship &ship, const Projectile &projectile, list<Effect> &effects)
{
	int strength = outfit->AntiMissile();
	if(!strength)
		return false;
	
	double range = outfit->Velocity();
	
	// Check if the missile is in range.
	Point start = ship.Position() + ship.Facing().Rotate(point);
	Point offset = projectile.Position() - start;
	if(offset.Length() > range)
		return false;
	
	// Figure out where the effect should be placed. Anti-missiles do not create
	// projectiles; they just create a blast animation.
	start += (.5 * range) * offset.Unit();
	Angle aim = TO_DEG * atan2(offset.X(), -offset.Y());
	for(const auto &eit : outfit->HitEffects())
		for(int i = 0; i < eit.second; ++i)
		{
			effects.push_back(*eit.first);
			effects.back().Place(start, ship.Velocity(), aim);
		}
	
	Fire(ship);
	
	return (Random::Int(strength) > Random::Int(projectile.MissileStrength()));
}
double AsteroidField::Asteroid::Collide(const Projectile &projectile, int step) const
{
	Point pos = location - projectile.Position();
	pos = Point(-remainder(pos.X(), WRAP), -remainder(pos.Y(), WRAP));
	
	return animation.GetMask(step).Collide(pos, projectile.Velocity(), angle);
}
Example #3
0
// This ship just got hit by the given projectile. Take damage according to
// what sort of weapon the projectile it.
int Ship::TakeDamage(const Projectile &projectile, bool isBlast)
{
	int type = 0;
	
	const Outfit &weapon = projectile.GetWeapon();
	double shieldDamage = weapon.ShieldDamage();
	double hullDamage = weapon.HullDamage();
	double hitForce = weapon.HitForce();
	double heatDamage = weapon.HeatDamage();
	double ionDamage = weapon.IonDamage();
	bool wasDisabled = IsDisabled();
	bool wasDestroyed = IsDestroyed();
	
	if(shields > shieldDamage)
	{
		shields -= shieldDamage;
		heat += .5 * heatDamage;
		ionization += .5 * ionDamage;
	}
	else if(!shields || shieldDamage)
	{
		if(shieldDamage)
		{
			hullDamage *= (1. - (shields / shieldDamage));
			shields = 0.;
		}
		hull -= hullDamage;
		heat += heatDamage;
		ionization += ionDamage;
	}
	
	if(hitForce && !IsHyperspacing())
	{
		Point d = position - projectile.Position();
		double distance = d.Length();
		if(distance)
			ApplyForce((hitForce / distance) * d);
	}
	
	if(!wasDisabled && IsDisabled())
		type |= ShipEvent::DISABLE;
	if(!wasDestroyed && IsDestroyed())
		type |= ShipEvent::DESTROY;
	// If this ship was hit directly and did not consider itself an enemy of the
	// ship that hit it, it is now "provoked" against that government.
	if(!isBlast && projectile.GetGovernment() && !projectile.GetGovernment()->IsEnemy(government)
			&& (Shields() < .9 || Hull() < .9 || !personality.IsForbearing())
			&& !personality.IsPacifist())
		type |= ShipEvent::PROVOKE;
	
	return type;
}