/*
* SpacePirate.cs
* Authors: August Zinsser
*
* Copyright Matthew Belmonte 2007
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Pina3D.Particles;
using tAC_Engine;
namespace Astropolis
{
///
/// The enemy ships that spawn from wormholes in meteor madness
/// Space Pirates can shoot at the player
/// They also explode when the player shoots them enough times or they hit enough meteors
/// Upon explosion, they drop coins that can be collected by the player
///
class SpacePirate : UFO
{
private double mArcPosition; // Degrees of a circle corresponding to the player's ship's position
private double mArcVelocity; // Speed at which the ship can change its arcposition
private float mCooldownTime; // The minimum base time between shots
private float mCooldownTimer; // Counts down until the next shot
public double ArcPosition { set { mArcPosition = value; UpdatePosition(); } get { return mArcPosition; } }
public double ArcVelocity { set { mArcVelocity = value; } get { return mArcVelocity; } }
///
/// Constructor
///
/// Image to use
/// In Space3D units
/// In Space3D units
/// In Space3D units
/// Damage this ship can take before dying
/// Base time between shots, although this time is reduced at later levels
public SpacePirate(Texture2D texture, float width, float height, float depth, int hitPoints, float shotCooldown)
: base(texture, width, height, depth, hitPoints)
{
mArcVelocity = Math.PI / 1920;
mCooldownTimer = (3 + (shotCooldown * 2)) * GenericBaseApplication.GameManager.RandomNumber(.90f, 1.10f); // Wait for the player to react before opening fire
mCooldownTime = shotCooldown;
}
///
/// Deals the specified amount of damage to the space priate, potentially killing it
///
///
public override void GetHit(int damage)
{
mHitPoints -= damage;
if (mHitPoints <= 0)
Destroy();
else
{
if (mPos.Z > -1)
{
// Shield particle effect
mShieldEmitter.RegularEmissionType.LifeExpectancy = .1f;
mShieldEmitter = Sparx.LoadParticleEffect(@"Content\Particle Effects\Shield.spx");
// Redden the shields to indicate that they are low
float percentLeft = (float)(mHitPoints / 100f);
Color newColor = new Color((byte)((255 * (1 - percentLeft))),
(byte)((150 * (percentLeft))),
(byte)((255 * (percentLeft))));
mShieldEmitter.RegularEmissionType.Modifiers[0].InitialTint = newColor;
mShieldEmitter.RegularEmissionType.Modifiers[0].InitialOpacity = percentLeft;
Sparx.AddEmitter(mShieldEmitter);
}
}
}
///
/// Spawns the appropriate particle effects and/or entities
///
public override void Destroy()
{
mAlive = false;
Emitter splosion = Sparx.LoadParticleEffect(@"Content\Particle Effects\MediumExplosion.spx");
Rectangle proj = Space3D.Project(this.X, this.Y, this.Z, this.Width, this.Height, -1f);
float scaling = proj.Width * .01f;
splosion.RenderScale = scaling;
splosion.Transform = Matrix.CreateScale(scaling) * Matrix.CreateTranslation(proj.X, proj.Y, MathHelper.Clamp(this.Z / 5f, 0f, 1f));
Sparx.AddEmitter(splosion);
splosion = Sparx.LoadParticleEffect(@"Content\Particle Effects\MediumExplosion.spx");
scaling *= .5f;
splosion.RenderScale = scaling;
splosion.Transform = Matrix.CreateScale(scaling) * Matrix.CreateTranslation(proj.X, proj.Y, MathHelper.Clamp(this.Z / 5f, 0f, 1f));
Sparx.AddEmitter(splosion);
}
///
/// Damages player
///
public override void CollideWithPlayer(Entity player)
{
((MeteorMadness)AstroBaseApplication.MiniGame).ShooterShieldHit(50);
Destroy();
}
///
/// Implements basic AI
///
/// True if the AI should fire, false if it should not
public override bool React(CheetahFighter playerShip)
{
float dt = AstroBaseApplication.GameManager.ElapsedMilliseconds;
mCooldownTimer -= dt / 1000;
if (playerShip == null)
return false;
if (Math.Abs(mArcPosition - playerShip.ArcPosition) > .01)
{
if (mArcPosition < playerShip.ArcPosition)
MoveLeft(dt);
else
MoveRight(dt);
}
// Fire if the space pirate is lined up with the player
if (Collides2D(this, playerShip) && mCooldownTimer < 0)
{
Fire();
return true;
}
return false;
}
///
/// Moves the space pirate clockwise along the circumference of the Space3D cylinder
///
/// Seconds since last update
private void MoveLeft(float dt)
{
mArcPosition += mArcVelocity * dt;
UpdatePosition();
}
///
/// Moves the space pirate counterclockwise along the circumference of the Space3D cylinder
///
/// Seconds since last update
private void MoveRight(float dt)
{
mArcPosition -= mArcVelocity * dt;
UpdatePosition();
}
///
/// Reset the firing cooldown
///
private void Fire()
{
mCooldownTimer = mCooldownTime;
}
///
/// Updates the inherited Position properties based on the arcposition
///
private void UpdatePosition()
{
Vector2 PositionFromOrigin = new Vector2((float)Math.Cos(mArcPosition), (float)Math.Sin(mArcPosition));
mArcPosition %= Math.PI * 2;
mPos.X = .8F * PositionFromOrigin.X;
mPos.Y = .8F * PositionFromOrigin.Y;
mRot = mArcPosition - Math.PI / 2;
}
public override void Update()
{
base.Update();
Rectangle proj = Space3D.Project(this.X, this.Y, this.Z, this.Width, this.Height, -1f);
float scaling = proj.Width * .015f;
mShieldEmitter.RenderScale = scaling;
mShieldEmitter.Transform = Matrix.CreateScale(scaling) * Matrix.CreateTranslation(proj.X, proj.Y, MathHelper.Clamp(this.Z / 5f, 0f, 1f));
}
}
}