package { import flash.display.MovieClip; import flash.events.Event; import flash.geom.Point; public class AIShip extends Ship { private var id:int; private var sector:Sector; private var target:Ship; private var firing:Boolean = false; private var fireCounter:int = 0; private var mainWep:Object; private var aggro_gain:int = 800; private var aggro_loose:int = 800; private var behavior_prim:int = Behaviors.Guard; private var guardSpot:Point; public function AIShip($ID:int, $coords:Point, $rotation:Number, $allegience:int, $sector:Sector, $shipProperties:Object, $weaponProperties:DBWeapons) { id = $ID; sector = $sector; mainWep = $weaponProperties.getWeaponData($shipProperties.weaponPrim); super($coords, $rotation, $sector, $shipProperties, $allegience); guardSpot = new Point($coords.x, $coords.y); //loop addEventListener(Event.ENTER_FRAME, loop); } //--Main loop-- private function loop($e:Event):void { move(); //Firing loop if (++fireCounter >= (40 / mainWep.rof))// 40 = the framerate { fireCounter = 0; fire(); } //Is target dead? if (target && target.HP >= 0) target = null; //Primary behaviors switch (behavior_prim) { case Behaviors.Guard: behavior_guard(); break; } } //--Hits-- public override function projectileHit($damage:Number):void { super.projectileHit($damage); } //--Movement-- private function speedUp() { Speed += SpeedAcc; } private function slowDown() { Speed -= BreakSpeed; } private function turnCCW() { TorqueSpeed -= TorqueAcc; } private function turnCW() { TorqueSpeed += TorqueAcc; } private function stopTurning() { if (Math.abs(TorqueSpeed) <= .5) TorqueSpeed = 0; else TorqueSpeed *= .8; } //Goto private function goto($spot:Point)//fly to a place and stop { var turningDir:Number = Globals.turningDir(guardSpot.x * 32, guardSpot.y * 32, x, y, rotation); if (Globals.calcDist(guardSpot.x * 32, guardSpot.y * 32, x, y) > 120) { speedUp(); //Turning if (Math.abs(turningDir) > 10) { if (turningDir > 0) turnCW(); else turnCCW(); } else { stopTurning(); } } else { slowDown(); stopTurning(); } } //--Behaviors-- //Guard private function behavior_guard() { if(!target) target = lookForTarget(); if (target) { var targetAngle:Number = Math.abs(Globals.turningDir(target.x, target.y, x, y, rotation)); var targetDist:Number = Globals.calcDist(target.x, target.y, x, y); if ((targetDist > 300 || targetAngle < 90) && targetDist > 200)//(långt borta eller bakom mig) && inte för nära hunt(); else evade(); } else { firing = false; goto(guardSpot); } } //--Other AI-stuff-- //Hunt private function hunt()//follow target and shoot when in sight { speedUp(); //Turning and shooting var turningDir:Number = Globals.turningDir(target.x, target.y, x, y, rotation); if (Math.abs(turningDir) > 10) { firing = false; if (turningDir > 0) turnCW(); else turnCCW(); } else//target is within a 20 degree cone of fire (-10 to 10) to simulate puny human inferior aiming skills { stopTurning(); firing = true; } } //Evade private function evade()//run away from target { speedUp(); firing = false; var turningDir:Number = Globals.turningDir(target.x, target.y, x, y, rotation); turningDir = turningDir + 180; if (Math.abs(turningDir) > 30) { if (turningDir > 0) turnCW(); else turnCCW(); } else { stopTurning(); } } //--Misc-- //Look for target private function lookForTarget():Ship { var ships:Array = sector.getShips(); for (var i:int = 0; i < ships.length; i++ ) { if (ships[i] && ships[i].Allegiance != Allegiance) { var distance:Number = Globals.calcDist(ships[i].x, ships[i].y, x, y); if (distance <= aggro_gain) return ships[i]; } } return null; } //Fire private function fire() { if (firing && HP > 0) { getSector.addChildAt(new Projectile(Speed, rotation, mainWep, getSector, this), 0); } } //Destroy public override function destroy() { HP = 0; Dying = true; target = null; getSector.removeAIShip(id); removeEventListener(Event.ENTER_FRAME, loop); super.destroy(); } //--------------------------------------------set/get-------------------------------------------- public override function get ID():int { return id; } } }