package { import flash.display.MovieClip; import flash.events.Event; import flash.geom.Point; import Globals; public class Missile extends MovieClip { private var speed:Number = 0; private var speedX:Number = 0; private var speedY:Number = 0; private var sector:Sector; private var firedFrom:Ship; private var damage:int = 0; private var dying:Boolean = false;//prevents double destroy() calls private var weaponData:Object; private var allegiance:int; private var target:Ship; private var aggroRange:int = 500; private var lifetime:int = 200; public function Missile($speed:Number, $angle:Number, $weaponData:Object, $sector:Sector, $firedFrom:Ship) { weaponData = $weaponData; speed = $speed + parseInt(weaponData.speed, 10); rotation = $angle; sector = $sector; firedFrom = $firedFrom; damage = weaponData.damage; allegiance = firedFrom.Allegiance; gotoAndStop(weaponData.id); x = firedFrom.x; y = firedFrom.y; transform.colorTransform = sector.AllegianceColors[firedFrom.Allegiance]; addEventListener(Event.ENTER_FRAME, loop); } private function loop($e:Event):void { asteroidCollisionCheck(); shipCollisionCheck(); spawnSmoke(1, 2, 1); aiActions(); move(); //explode when lifetime runs out if (lifetime-- <= 0) destroy(); } private function move():void { speedX = Math.sin(Globals.degToRad(rotation)) * speed; speedY = Math.cos(Globals.degToRad(rotation)) * -speed; x += speedX; y += speedY; } private function aiActions():void { if (!target || target.HP <= 0) { target = lookForTarget(); } else { var turningDir:Number = Globals.turningDir(target.x, target.y, x, y, rotation); if (turningDir > 0) rotation += 3; else rotation -= 3; } } private function lookForTarget():Ship { var ships:Array = sector.getShips(); for (var i:int = 0; i < ships.length; i++ ) { if ( ships[i] && //target is not dead ships[i].Allegiance != firedFrom.Allegiance && //target is hostile Math.abs(Globals.turningDir(ships[i].x, ships[i].y, x, y, rotation)) <= 45 && //target is within a 90 degree cone in front of the missle Globals.calcDist(ships[i].x, ships[i].y, x, y) <= aggroRange //target is within aggro range ) { return ships[i]; } } return null; } private function spawnSmoke($ammount:int, $speed:Number, $scale:Number):void { for (var i:int = 0; i < $ammount; i++) { var temp:Rocket_smoke = new Rocket_smoke( (Math.random() * $speed) - ($speed / 2) - (speedX / 4), (Math.random() * $speed) - ($speed / 2) - (speedY / 4) ); temp.x = x; temp.y = y; temp.scaleX = $scale; temp.scaleY = $scale; sector.addChild(temp); } } private function asteroidCollisionCheck():void { for each (var a:Asteroid in sector.Asteroids) { if (a && Globals.calcDist(a.x, a.y, x, y) < 60) { a.hit(damage); destroy(); return; } } } private function shipCollisionCheck():void { for each(var s:Ship in sector.getShips()) { if (s && s != firedFrom && Globals.calcDist(s.x, s.y, x, y) < s.Mass) { if (s.Allegiance != allegiance)//hits enemy ship { s.projectileHit(damage, firedFrom); destroy(); } else { remove(); } } } } ///removes the projectile without any hit effect public function remove():void { if (!dying) { dying = true; removeEventListener(Event.ENTER_FRAME, loop); parent.removeChild(this); } } ///removes the projectile and adds a hit effect public function destroy():void { if (!dying) { var boom:ProjectileHit = new ProjectileHit(); boom.x = x; boom.y = y; boom.scaleX = 6; boom.scaleY = 6; parent.addChild(boom); remove(); } } //--------------------------------------------set/get-------------------------------------------- public function get Coords():Point { return new Point(Globals.posToCoords(x), Globals.posToCoords(y)); } } }