
datablock ParticleData(SMissileSmokeParticle)
{
   dragCoeffiecient     = 0.0;
   gravityCoefficient   = -0.02;
   inheritedVelFactor   = 0.1;

   lifetimeMS           = 1000;
   lifetimeVarianceMS   = 100;

   textureName          = "particleTest";

   useInvAlpha = true;
   spinRandomMin = -90.0;
   spinRandomMax = 90.0;

   colors[0]     = "1.0 0.75 0.0 0.0";
   colors[1]     = "0.5 0.5 0.5 1.0";
   colors[2]     = "0.3 0.3 0.3 0.0";
   sizes[0]      = 0.75;
   sizes[1]      = 1.4;
   sizes[2]      = 2;
   times[0]      = 0.0;
   times[1]      = 0.1;
   times[2]      = 1.0;
};

datablock ParticleEmitterData(SMissileSmokeEmitter)
{
   ejectionPeriodMS = 12;
   periodVarianceMS = 0;

   ejectionVelocity = 1.5;
   velocityVariance = 0.3;

   thetaMin         = 0.0;
   thetaMax         = 50.0;  

   particles = "SMissileSmokeParticle";
};


datablock ParticleData(SMissileFireParticle)
{
   dragCoeffiecient     = 0.0;
   gravityCoefficient   = 0.0;
   inheritedVelFactor   = 1.0;

   lifetimeMS           = 220;
   lifetimeVarianceMS   = 000;

   textureName          = "particleTest";

   spinRandomMin = -135;
   spinRandomMax =  135;

   colors[0]     = "1.0 0.75 0.2 1.0";
   colors[1]     = "1.0 0.5 0.0 1.0";
   colors[2]     = "1.0 0.40 0.0 0.0";
   sizes[0]      = 0;
   sizes[1]      = 0.6;
   sizes[2]      = 1;
   times[0]      = 0.0;
   times[1]      = 0.3;
   times[2]      = 1.0;
};

datablock ParticleEmitterData(SMissileFireEmitter)
{
   ejectionPeriodMS = 6;
   periodVarianceMS = 2;

   ejectionVelocity = 12.0;
   velocityVariance = 2.0;

   thetaMin         = 0.0;
   thetaMax         = 20.0;  

   particles = "SMissileFireParticle";
};

datablock ParticleData(SMissilePuffParticle)
{
   dragCoeffiecient     = 0.0;
   gravityCoefficient   = 0.0;
   inheritedVelFactor   = 0.0;

   lifetimeMS           = 400;
   lifetimeVarianceMS   = 300;

   textureName          = "particleTest";

   spinRandomMin = -135;
   spinRandomMax =  135;

   colors[0]     = "1.0 1.0 1.0 0.5";
   colors[1]     = "0.7 0.7 0.7 0.0";
   sizes[0]      = 0.25;
   sizes[1]      = 0.8;
   times[0]      = 0.0;
   times[1]      = 1.0;
};

datablock ParticleEmitterData(SMissilePuffEmitter)
{
   ejectionPeriodMS = 50;
   periodVarianceMS = 3;

   ejectionVelocity = 0.5;
   velocityVariance = 0.0;

   thetaMin         = 0.0;
   thetaMax         = 90.0;

   particles = "SMissilePuffParticle";
};

datablock ParticleData(SMissileExhaustParticle)
{
   dragCoeffiecient     = 0.0;
   gravityCoefficient   = 0.01;
   inheritedVelFactor   = 1.0;

   lifetimeMS           = 400;
   lifetimeVarianceMS   = 300;

   textureName          = "particleTest";

   useInvAlpha = true;
   spinRandomMin = -135;
   spinRandomMax =  135;

   colors[0]     = "1.0 1.0 1.0 0.5";
   colors[1]     = "0.7 0.7 0.7 0.0";
   sizes[0]      = 0.25;
   sizes[1]      = 0.8;
   times[0]      = 0.0;
   times[1]      = 1.0;
};

datablock ParticleEmitterData(SMissileExhaustEmitter)
{
   ejectionPeriodMS = 15;
   periodVarianceMS = 0;

   ejectionVelocity = 3.0;
   velocityVariance = 0.0;

   thetaMin         = 0.0;
   thetaMax         = 20.0;

   particles = "SMissileExhaustParticle";
};

datablock SeekerProjectileData(DFMissile)
{
   projectileShapeName = "ammo_missile.dts";

   hasDamageRadius     = true;
   indirectDamage      = 0.96;
   damageRadius        = 7.5;
   radiusDamageType    = $DamageType::Explosion;
   kickBackStrength    = 2000;

   explosion           = "MissileExplosion";
   splash              = MissileSplash;
   velInheritFactor    = 1.0;

   delayEmitter        = SMissileFireEmitter;
//   puffEmitter         = SMissilePuffEmitter;
   bubbleEmitter       = GrenadeBubbleEmitter;
   bubbleEmitTime      = 1.0;

//   exhaustEmitter      = SMissileExhaustEmitter;
//   exhaustTimeMs       = 300;
//   exhaustNodeName     = "muzzlePoint1";

   lifetimeMS          = 8000;
   muzzleVelocity      = 10.0;
   maxVelocity         = 140.0;
   turningSpeed        = 10.0;
   acceleration        = 40.0;

   proximityRadius     = 3;

   terrainAvoidanceSpeed         = 10;
   terrainScanAhead              = 5;
   terrainHeightFail             = 2;
   terrainAvoidanceRadius        = 10;  
   
   flareDistance = 2;
   flareAngle    = 1;

   sound = MissileProjectileSound;

   hasLight    = true;
   lightRadius = 6.0;
   lightColor  = "0.2 0.05 0";

   explodeOnWaterImpact = true;
};

datablock ItemData(SMissilePack)
{
   className = Pack;
   catagory = "Packs";

   shapeFile = "ammo_missile.dts";

   image = SMissilePackImage;

   mass = 2.5;

   elasticity = 0.2;
   friction = 0.6;

   pickupRadius = 2;
   pickUpName = "a Shoulder-Rocket Pack";

   computeCRC = true;
   emap = true;
};

datablock ItemData(SMissileExtra)
{
   className = Pack;
   catagory = "Packs";

   shapeFile = "turret_belly_base.dts";

   image = SMissilePackImage;

   mass = 2.5;

   elasticity = 0.2;
   friction = 0.6;

   pickupRadius = 0;
   pickUpName = "an Shoulder-Rocket Pack";

   computeCRC = true;
   emap = true;
};

function SMissilePack::onAdd(%Data, %Pack)
{
   %Item = new Item()
   {
      datablock = SMissileExtra;
   };
   MissionCleanUp.Add(%Item);

   if (%Pack.sensors == 0)
      %Pack.schedule(450, delete);

   %Pack.Slave = %Item;

   FollowObject(%Item, %Pack);
}

function SMissilePack::onRemove(%Data, %Pack)
{
   %Pack.slave.delete();
}

function SMissilePack::onPickup(%this, %Pack, %Player, %Amount)
{
   if (%Pack.sensors !$= "")
   {
      // Get the ammo from the pack
      %Player.inv[SMissileAmmo] += %pack.sensors;
      if (%Player.inv[SMissileAmmo] > %Player.getDataBlock().max[SMissileAmmo])
         %Player.inv[SMissileAmmo] = %Player.getDataBlock().max[SMissileAmmo];

      %Player.client.updateSensorPackText(%Player.inv[SMissileAmmo]);
   }
}

function SMissilePack::onThrow(%this,%pack,%player)
{
   %Player.throwSensorPack = true;

   %Pack.sensors = %Player.inv[SMissileAmmo];
   %Player.inv[SMissileAmmo] = 0;
   %Player.client.updateSensorPackText(%Player.inv[SMissileAmmo]);

   // do the normal ItemData::onThrow stuff -- sound and schedule deletion
   serverPlay3D(ItemThrowSound, %Player.getTransform());
   %Pack.schedulePop();
}

datablock ShapeBaseImageData(BRDualSMissileImage)
{
   shapeFile = "ammo_missile.dts";
   mass = 3;

   mountPoint = 0;
   offset = "0.42 0.1 0.3";
   rotation = "0 1 0 90";
};

datablock ShapeBaseImageData(BLDualSMissileImage)
{
   shapeFile = "ammo_missile.dts";
   mass = 3;

   mountPoint = 1;
   offset = "-0.42 0.1 0.3";
   rotation = "0 1 0 90";
};

datablock ShapeBaseImageData(BRSingleSMissileImage)
{
   shapeFile = "weapon_missile_projectile.dts";
   mass = 1.5;

   mountPoint = 0;
   offset = "0.42 0.1 0.3";
   rotation = "0 1 0 90";
};

datablock ShapeBaseImageData(BLSingleSMissileImage)
{
   shapeFile = "weapon_missile_projectile.dts";
   mass = 1.5;

   mountPoint = 1;
   offset = "-0.42 0.1 0.3";
   rotation = "0 1 0 90";
};

datablock ShapeBaseImageData(HRDualSMissileImage)
{
   shapeFile = "ammo_missile.dts";
   mass = 3;

   mountPoint = 0;
   offset = "0.36 -0.4 0.45";
   rotation = "0 1 0 100";
};

datablock ShapeBaseImageData(HLDualSMissileImage)
{
   shapeFile = "ammo_missile.dts";
   mass = 3;

   mountPoint = 1;
   offset = "-0.82 0.3 0.05";
   rotation = "0 1 0 90";
};

datablock ShapeBaseImageData(HRSingleSMissileImage)
{
   shapeFile = "weapon_missile_projectile.dts";
   mass = 1.5;

   mountPoint = 0;
   offset = "0.36 -0.4 0.45";
   rotation = "0 1 0 100";
};

datablock ShapeBaseImageData(HLSingleSMissileImage)
{
   shapeFile = "weapon_missile_projectile.dts";
   mass = 1.5;

   mountPoint = 1;
   offset = "-0.82 0.3 0.05";
   rotation = "0 1 0 90";
};

datablock ShapeBaseImageData(SMissilePackImage)
{
   shapeFile = "turret_belly_base.dts";

   mass = 12;
   item = SMissilePack;

   mountPoint = 1;

   offset = "0 0.1 0.03";
   rotation = "1 0 0 90";

   stateName[0] = "Idle";
   stateTransitionOnTriggerDown[0] = "Activate";

   stateName[1] = "Activate";
   stateScript[1] = "onActivate";
   stateSequence[1] = "fire";
   stateTransitionOnTriggerUp[1] = "Deactivate";

   stateName[2] = "Deactivate";
   stateScript[2] = "onDeactivate";
   stateTransitionOnTimeout[2] = "Idle";   
};

function Player::MountSMissileImage(%Player)
{
   %Ammo = %Player.inv[SMissileAmmo];
   if (%Ammo > 0)
   {
      if (%Ammo > 1)
      {
         if (%Player.client.race $= "Bioderm")
         {
            %Player.mountImage("BRDualSMissileImage", 6);
            %Player.mountImage("BLDualSMissileImage", 7);
         } else {
            %Player.mountImage("HRDualSMissileImage", 6);
            %Player.mountImage("HLDualSMissileImage", 7);
         }
      } else {
         if (%Player.client.race $= "Bioderm")
         {
            %Player.mountImage("BRSingleSMissileImage", 6);
            %Player.mountImage("BLSingleSMissileImage", 7);
         } else {
            %Player.mountImage("HRSingleSMissileImage", 6);
            %Player.mountImage("HLSingleSMissileImage", 7);
         }
      }
   }
}

function SMissilePackImage::onMount(%data, %Player, %Slot)
{
   %Player.unMountImage(6);
   %Player.unMountImage(7); 

   %Player.schedule(650, MountSMissileImage);
}

function SMissilePackImage::onUnmount(%data, %Player, %Slot)
{
   %Player.unMountImage(6);
   %Player.unMountImage(7);
}

function SMissilePackImage::onActivate(%Data, %Player, %slot)
{
   // Ignore the player attempting to fire if it is reloading
   if (%Player.SMissileReload == true)
      return;

   if (%Player.inv[SMissileAmmo] <= 0)
   {
      messageClient(%Player.client, '', "You are out of Shoulder-Mounted Missiles");
      return;
   }

   // Prevent further firing
   %Player.SMissileReload = true;

   %PlayerVelocity = %Player.getVelocity();

   // Do the actual firing here
   %BasePosition = %Player.getMuzzlePoint($BackPackSlot);

   %MuzzleVector = VectorNormalize(%Player.getMuzzleVector($WeaponSlot));

   %StartPosition = VectorAdd(%BasePosition, VectorScale(%MuzzleVector, 1));
   %EndPosition = VectorAdd(%BasePosition, VectorScale(%MuzzleVector, 41.5));

   %Target1 = ContainerRayCast(%StartPosition, %EndPosition, $EverythingMask, %Player);

   %Transform = %Player.getTransform();
   %PositionXY = getWords(%Transform, 0, 1);
   %PositionZ = getWord(%Transform, 2) + 3;

   %Position2 = VectorAdd(%PositionXY @ " " @ %PositionZ, "0 0 100");

   %Target2 = containerRayCast(%PositionXY @ " " @ %PositionZ, %Position2, $EverythingMask, %Player);

   %Item = new ParticleEmissionDummy()
   {
      position = %BasePosition;
      scale = "1.5 1.5 1.5";
      dataBlock = "defaultEmissionDummy";
      emitter = "MissileLauncherExhaustEmitter";
      velocity = %PlayerVelocity;
   };
   MissionCleanup.add(%Item);

   %Item.schedule(1650, delete);

   %Item = new ParticleEmissionDummy()
   {
      position = %StartPosition;
      scale = "1.8 1.8 1.8";
      dataBlock = "defaultEmissionDummy";
      emitter = "MissileLauncherExhaustEmitter";
      velocity = %PlayerVelocity;
   };
   MissionCleanup.add(%Item);

   %Item.schedule(650, delete);

   // If something is within 40 meters in front of you fire a dumbfire missile pair
   // If you are inside, fire a dumbfire missile pair
   if (%Target1 !$= "0" || %Target2 !$= "0")
   {
      %Projectile = new SeekerProjectile()
      {
         dataBlock        = DFMissile;
         initialDirection = %MuzzleVector;
         initialPosition  = %StartPosition;
         sourceObject     = %Player;
         sourceSlot       = $BackPackSlot;
      };
      MissionCleanUp.Add(%Projectile);
   } else {
      %StartPosition = VectorAdd(%BasePosition, VectorScale(%MuzzleVector, 2.25));

      %Rotation = rotFromTransform(%Transform);

      %Drone = CreateMissileDrone(SMissileDrone, %StartPosition, %Rotation, %Player.client);

      %FiringVector = VectorScale(%MuzzleVector, 4800);

      %Drone.ApplyImpulse(%StartPosition, %FiringVector);

      schedule(1000, 0, SetControl, %Player.client, %Drone);
   }

   // Decrement the Ammo and reflect it on the player's image
   %Player.inv[SMissileAmmo]--;
   if (%Player.inv[SMissileAmmo] <= 0)
   {
      %Player.unMountImage(6);
      %Player.unMountImage(7); 
   } else {
      if (%Player.client.race $= "Bioderm")
      {
         %Player.mountImage("BRSingleSMissileImage", 6);
         %Player.mountImage("BLSingleSMissileImage", 7);
      } else {
         %Player.mountImage("HRSingleSMissileImage", 6);
         %Player.mountImage("HLSingleSMissileImage", 7);
      }
   }

   serverPlay3D(MissileFireSound, %NewPosition);

   // Apply the firing kickback
   %KickBackStrength = -1250;

   %Velocity = %Player.getVelocity();
   %Speed = VectorLen(%Velocity);
   if (%Speed > 20)
      %KickBackStrength *= 1.35;

   if (%Player.InWater == true)
      %KickBackStrength *= 2;

   %KickBackVector = VectorScale(%ForwardVector, %KickBackStrength);

   %Player.ApplyImpulse(%Position, %KickBackVector);

   // Apply the Damage and check to see if the player catchs on fire
   %Random = getRandom();
   if (%Player.InWater != true && %Random > 0.94)
   {
      %PerOver = (%Random - 0.8) / 0.2;
      %Duration = 8 * %PerOver;
      %Damage = 0.02 * %PerOver;

      %Player.Burn(%Duration, %Damage, %Player);

      %Random -= 0.2;
   }

   %Damage = (0.06 * %Random) + 0.04;
   %Player.getDataBlock().damageObject(%Player, %Player, %Position, %Damage, %DamageType, %Velocity);

   %Player.setImageTrigger($BackPackSlot, false);

   // Schedule the Reloading now
   %Player.schedule(2750, ReloadSMissile);   
}

function Player::ReloadSMissile(%Player)
{
   %Player.SMissileReload = "";
}

datablock ShapeBaseImageData(SMissileDroneImage)
{
   shapeFile = "ammo_missile.dts";
   mountPoint = 1;
   offset = "0 -0.5 0.4";
   mass = 0.1;

   alwaysAmbient = false;
};

datablock StaticShapeData(SMissileDroneObject)
{
   shapeFile = "ammo_missile.dts";

   mountPoint = 1;
   offset = "0 -0.5 0.4";

   mass = 0.1;

   alwaysAmbient = false;
};

datablock FlyingVehicleData(SMissileDrone) : ShrikeDamageProfile
{
   spawnOffset = "0 0 2";

   catagory = "Vehicles";
   shapeFile = "turret_fusion_large.dts";
   multipassenger = false;
   computeCRC = true;

   ControlRange = 450;
   BurnTime = 8;
   Thrust = 750;

   NoDisturbance = true;

   Name = "Shoulder Mounted Missiles";

   numWeapons = 3;

   AlternateHUD = MortarBarrelLarge;

   debrisShapeName = "debris_generic_small.dts";
   debris = DeployableDebris;

   drag    = 0.15;
   density = 1.0;

   mountPose[0] = sitting;
   numMountPoints = 3;  
   isProtectedMountPoint[0] = true;

   canObserve = false;
   cameraMaxDist = 15;
   cameraOffset = 2.5;
   cameraLag = 0.9;

   explosion = GrenadeExplosion;
   explosionDamage = 0.94;
   explosionRadius = 14;
   explosionImpulse = 1800;

   maxDamage = 0.1;
   destroyedLevel = 0.1;

   isShielded = false;
   maxEnergy = 1;               // Afterburner and any energy weapon pool
   minDrag = 1;                 // Linear Drag (eventually slows you down when not thrusting...constant drag)
   rotationalDrag = 900;        // Anguler Drag (dampens the drift after you stop moving the mouse...also tumble drag)
   rechargeRate = 0.0;

   maxAutoSpeed = 10;            // Autostabilizer kicks in when less than this speed. (meters/second)
   autoAngularForce = 400;       // Angular stabilizer force (this force levels you out when autostabilizer kicks in)
   autoLinearForce = 300;        // Linear stabilzer force (this slows you down when autostabilizer kicks in)
   autoInputDamping = 0.95;      // Dampen control input so you don't` whack out at very slow speeds
   
   // Maneuvering
   maxSteeringAngle = 5;         // Max radiens you can rotate the wheel. Smaller number is more maneuverable.
   horizontalSurfaceForce = 6;   // Horizontal center "wing" (provides "bite" into the wind for climbing/diving and turning)
   verticalSurfaceForce = 4;     // Vertical center "wing" (controls side slip. lower numbers make MORE slide.)
   maneuveringForce = 0;         // Horizontal jets (W,S,D,A key thrust)
   steeringForce = 1200;         // Steering jets (force applied when you move the mouse)
   steeringRollForce = 600;      // Steering jets (how much you heel over when you turn)
   rollForce = 4;                // Auto-roll (self-correction to right you after you roll/invert)
   hoverHeight = 1.5;            // Height off the ground at rest
   createHoverHeight = 1;        // Height off the ground when created

   // Turbo Jet
   jetForce = 0;                 // Afterburner thrust (this is in addition to normal thrust)
   minJetEnergy = 100;           // Afterburner can't be used if below this threshhold.
   jetEnergyDrain = 100;         // Energy use of the afterburners (low number is less drain...can be fractional)                                                                                                                                                                                                                                                                                          // Auto stabilize speed
   vertThrustMultiple = 0;
   maxForwardSpeed = 1000;
   minForwardSpeed = 100;

   ELFDrain  = 1.6;

   // Rigid body
   mass = 120;                   // Mass of the vehicle
   bodyFriction = 0;             // Don't mess with this.
   bodyRestitution = 0.5;        // When you hit the ground, how much you rebound. (between 0 and 1)
   minRollSpeed = 0;             // Don't mess with this.
   softImpactSpeed = 1998;         // Sound hooks. This is the soft hit.
   hardImpactSpeed = 2000;         // Sound hooks. This is the hard hit.

   // Ground Impact Damage (uses DamageType::Ground)
   minImpactSpeed = 30;          // If hit ground at speed above this then it's an impact. Meters/second
   speedDamageScale = 0.04;

   // Object Impact Damage (uses DamageType::Impact)
   collDamageThresholdVel = 25.0;
   collDamageMultiplier   = 0.02;

   minTrailSpeed = 2;           // The speed your contrail shows up at.
   trailEmitter = ContrailEmitter;
   forwardJetEmitter = FlyerJetEmitter;
   downJetEmitter = FlyerJetEmitter;

   jetSound         = MissileProjectileSound;
   engineSound      = MissileProjectileSound;
   floatSound       = MissileProjectileSound;
   softImpactSound = SoftImpactSound;
   hardImpactSound = HardImpactSound;
   
   softSplashSoundVelocity = 10.0; 
   mediumSplashSoundVelocity = 15.0;   
   hardSplashSoundVelocity = 20.0;   
   exitSplashSoundVelocity = 10.0;
   
   exitingWater      = VehicleExitWaterMediumSound;
   impactWaterEasy   = VehicleImpactWaterSoftSound;
   impactWaterMedium = VehicleImpactWaterMediumSound;
   impactWaterHard   = VehicleImpactWaterMediumSound;
   waterWakeSound    = VehicleWakeMediumSplashSound; 
    
   dustEmitter = VehicleLiftoffDustEmitter;
   triggerDustHeight = 2.0;
   dustHeight = 0.5;

   damageEmitter[0] = SMissileFireEmitter;
   damageEmitter[1] = SMissileFireEmitter;
   damageEmitter[2] = SMissileFireEmitter;
   damageEmitter[3] = SMissileFireEmitter;
   damageEmitterOffset[0] = "-0.55 -5.5 0";
   damageEmitterOffset[1] = "0.55 -5.5 0";
   damageLevelTolerance[0] = 0.01;
   damageLevelTolerance[1] = 0.1;
   damageLevelTolerance[2] = 0.2;
   numDmgEmitterAreas = 2;

   minMountDist = 4;

   splashEmitter[0] = VehicleFoamDropletsEmitter;
   splashEmitter[1] = VehicleFoamEmitter;

   shieldImpact = VehicleShieldImpact;

   cmdCategory = "Tactical";
   cmdIcon = CMDFlyingScoutIcon;
   cmdMiniIconName = "commander/MiniIcons/com_scout_grey";

   targetNameTag = 'Guided Missile';
   targetTypeTag = 'Guided Missile';
   sensorData = VehiclePulseSensor;
   
   checkRadius = 5.5;
   observeParameters = "1 4 2";

   canControl = true;
};

function SMissileDrone::onAdd(%this, %Vehicle)
{
   Parent::onAdd(%this, %Vehicle);

   %Vehicle.setCloaked(true);

   %Vehicle.getDataBlock().damageObject(%Vehicle, %Vehicle, "0 0 0", 0.015, 0, "0 0 0");
}

function CreateMissileDrone(%Data, %Position, %Rotation, %Owner)
{
   %Owner.player.PlayerNoFire = true;

   // Place the guided missile in the proper place
   %Drone = new FlyingVehicle()
   {
      dataBlock    = %Data;
      position     = %Position;
      rotation     = %Rotation;
      sourceObject = %Owner;
      team         = %Owner.team;
      owner        = %Owner;
   };                
   MissionCleanUp.add(%Drone);

   schedule(350, 0, CheckControlStatus, %Owner, %Drone);
   schedule(1350, 0, CheckControlStatus, %Owner, %Drone);
   schedule(2350, 0, CheckControlStatus, %Owner, %Drone);

   %Drone.setTransform(%Position @ " " @ %Rotation);

   %Drone.target = createTarget(%Drone, "", "", "", %Drone.getDataBlock().targetTypeTag, %Drone.Team, 0);
   setTargetSensorGroup(%Drone.getTarget(), %Drone.Team);

   %Drone.BurnTime = %Data.BurnTime;

   %PlayerPosition = posFromTransform(%Owner.player.getTransform());

   %Drone.mountable = false;

   %Range = %Data.ControlRange;
   schedule(1800, 0, CheckMissileDroneStatus, %Drone, %PlayerPosition, %Range);

   %Thrust = %Data.Thrust;
   schedule(400, 0, MissileDroneThrust, %Drone, %Thrust);

   schedule(12500, 0, ResetFire, %Owner.Player);

   return(%Drone);
}

function SMissileDrone::onTrigger(%data, %Vehicle, %trigger, %state)
{
   if (%Trigger == 0 || %Trigger == 2)
   {
      if (%State == true)
      {
         %Vehicle.setDamagestate(Destroyed);
         schedule(500, 0, ResetFire, %Vehicle.owner.Player);         
      }
      %Vehicle.setImageTrigger(0, false);
   }
}

function SMissileDrone::onCollision(%data, %Drone, %Object)
{
   %Drone.setDamageState(Destroyed);
}

function SMissileDrone::onDestroyed(%this, %Drone, %prevState)
{
   CheckControlStatus(%Drone.owner, %Drone);
   RestorePlayer(%Drone.owner);
   schedule(450, 0, ResetFire, %Drone.owner.Player);

   Parent::onDestroyed(%this, %Drone, %prevState);
}

function MissileDroneThrust(%Drone, %Thrust)
{
   if (isObject(%Drone) == false || %Drone.getDamageState() !$= "Enabled")
      return;

   %FacingVector = VectorNormalize(%Drone.getForwardVector());
   %InitialVector = VectorScale(%FacingVector, %Thrust);

   %Position = posFromTransform(%Drone.getTransform());
   %Drone.ApplyImpulse(%Position, %InitialVector);

   schedule(375, 0, MissileDroneThrust, %Drone, %Thrust);
}

function CheckMissileDroneStatus(%Drone, %Position, %Range)
{
   if (isObject(%Drone) == false || %Drone.getDamageState() !$= "Enabled")
      return;

   // Check the Burn Time allowed for the missile
   if (%Drone.BurnTime <= 0)
   {
      CrashMissileDrone(%Drone);
      return;
   }
   %Drone.BurnTime--;

   // Check to make sure it is not out of range.
   %Transform = %Drone.getTransform();
   %DronePosition = posFromTransform(%Transform);

   %VectorBetween = VectorSub(%DronePosition, %Position);
   %Distance = VectorLen(%VectorBetween);

   if (%Distance > %Range)
   {
      %Drone.setImageTrigger(1, false);

      %Message = "Lost contact with " @ %Drone.getDataBlock().Name @ ".";
      messageClient(%Drone.owner, '', %Message);

      CheckControlStatus(%Drone.owner, %Drone);
      RestorePlayer(%Drone.owner);

      CrashMissileDrone(%Drone);
      return;
   }

   // Check the status of the owner
   %ControlObject = %Drone.owner.getControlObject();
   if (%ControlObject != %Drone)
   {
      CrashMissileDrone(%Drone);

      return;
   }

   // Check the range and give notice if needed.
   if (%Distance > %Range * 0.7)
   {
      if (%Drone.NearEdge != true)
         messageClient(%Drone.owner, '', 'Nearing edge of missile control range.~wfx/misc/misc.error.wav');   

      %Drone.NearEdge = true;
   } else {
      %Drone.NearEdge = "";
   }

   schedule(1000, 0, CheckMissileDroneStatus, %Drone, %Position, %Range);
}

function CrashMissileDrone(%Drone)
{
   if (isObject(%Drone) == false)
      return;

   %Position = %Drone.getWorldBoxCenter();

   %Drone.ApplyImpulse(%Position, "0 0 -650");

   ResetFire(%Drone.owner.player);

   schedule(500, 0, CrashMissileDrone, %Drone);
}

function CheckControlStatus(%Client, %Drone)
{
   if (isObject(%Drone) == false || %Drone.getDamageState() !$= "Enabled")
   {
      serverCmdResetControlObject(%client);
      schedule(450, 0, ResetFire, %client.Player);
   }
}

function ResetFire(%Player)
{
   %Player.PlayerNoFire = "";
}

function RestorePlayer(%Client)
{
   %Weapon = %client.player.getMountedImage($WeaponSlot);
   %Item = %Weapon.UseCrossHair;
   if (%Item $= "")
      %Item = %Weapon.item;
   %client.setWeaponsHudActive(%Item);
}