

//--------------------------------------------------------------------------
// Projectile
//--------------------------------------

datablock EnergyProjectileData(EnergyBolt)
{
   emitterDelay        = -1;
   directDamage        = 0.075;
   directDamageType    = $DamageType::Energy;
   kickBackStrength    = 0.0;
   bubbleEmitTime      = 1.0;

   sound = BlasterProjectileSound;
   velInheritFactor    = 0.5;

   explosion           = "BlasterExplosion";
   splash              = BlasterSplash;

   rearDamageFactor    = 1.22;

   grenadeElasticity = 0.998;
   grenadeFriction   = 0.0;
   armingDelayMS     = 500;

   muzzleVelocity    = 180.0;

   drag = 0.05;

   gravityMod        = 0.0;

   dryVelocity       = 350.0;
   wetVelocity       = 160.0;

   reflectOnWaterImpactAngle = 0.0;
   explodeOnWaterImpact      = false;
   deflectionOnWaterImpact   = 0.0;
   fizzleUnderwaterMS        = 3000;

   hasLight    = true;
   lightRadius = 3.0;
   lightColor  = "0.5 0.175 0.175";

   scale = "0.25 15.0 1.0";
   crossViewAng = 0.99;
   crossSize = 0.55;

   fizzleTimeMS   = 3000;
   lifetimeMS     = 4200;
   blurLifetime   = 0.2;
   blurWidth      = 0.25;
   blurColor = "0.4 0.0 0.0 1.0";

   texture[0] = "special/blasterBolt";
   texture[1] = "special/blasterBoltCross";
};

datablock EnergyProjectileData(EnergyBurstBolt)
{
   emitterDelay        = -1;
   directDamage        = 0.0335;
   directDamageType    = $DamageType::Energy;
   kickBackStrength    = 0.0;
   bubbleEmitTime      = 1.0;

   sound = BlasterProjectileSound;
   velInheritFactor    = 0.5;

   explosion           = "BlasterExplosion";
   splash              = BlasterSplash;

   rearDamageFactor    = 1.22;

   grenadeElasticity = 0.998;
   grenadeFriction   = 0.0;
   armingDelayMS     = 250;

   muzzleVelocity    = 160.0;

   drag = 0.05;

   gravityMod        = 0.0;

   dryVelocity       = 350.0;
   wetVelocity       = 160.0;

   reflectOnWaterImpactAngle = 0.0;
   explodeOnWaterImpact      = false;
   deflectionOnWaterImpact   = 0.0;
   fizzleUnderwaterMS        = 2000;

   hasLight    = true;
   lightRadius = 2.0;
   lightColor  = "0.5 0.175 0.175";

   scale = "0.2 6.5 0.8";
   crossViewAng = 0.99;
   crossSize = 0.55;

   fizzleTimeMS   = 2200;
   lifetimeMS     = 2800;
   blurLifetime   = 0.2;
   blurWidth      = 0.25;
   blurColor = "0.4 0.0 0.0 1.0";

   texture[0] = "special/blasterBolt";
   texture[1] = "special/blasterBoltCross";
};

//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ShapeBaseImageData(BlasterImage)
{
   className = WeaponImage;
   shapeFile = "weapon_energy.dts";
   item = Blaster;
   projectile = EnergyBolt;
   projectileType = EnergyProjectile;

   usesEnergy = true;
   fireEnergy = 4;
   minEnergy = 4;

   WCS = true;
   WCSFirePattern = true;

   projectileSpread = 44/1000;
   projectileCount = 2;

   stateName[0] = "Activate";
   stateTransitionOnTimeout[0] = "ActivateReady";
   stateTimeoutValue[0] = 0.5;
   stateSequence[0] = "Activate";
   stateSound[0] = BlasterSwitchSound;

   stateName[1] = "ActivateReady";
   stateTransitionOnLoaded[1] = "Ready";
   stateTransitionOnNoAmmo[1] = "NoAmmo";

   stateName[2] = "Ready";
   stateTransitionOnNoAmmo[2] = "NoAmmo";
   stateTransitionOnTriggerDown[2] = "Fire";

   stateName[3] = "Fire";
   stateTransitionOnTimeout[3] = "Reload";
   stateTimeoutValue[3] = 0.3;
   stateFire[3] = true;
   stateRecoil[3] = NoRecoil;
   stateAllowImageChange[3] = false;
   stateSequence[3] = "Fire";
   stateSound[3] = BlasterFireSound;
   stateScript[3] = "onFire";

   stateName[4] = "Reload";
   stateTransitionOnNoAmmo[4] = "NoAmmo";
   stateTransitionOnTimeout[4] = "Ready";
   stateAllowImageChange[4] = false;
   stateSequence[4] = "Reload";

   stateName[5] = "NoAmmo";
   stateTransitionOnAmmo[5] = "Reload";
   stateSequence[5] = "NoAmmo";
   stateTransitionOnTriggerDown[5] = "DryFire";
   
   stateName[6] = "DryFire";
   stateTimeoutValue[6] = 0.3;
   stateSound[6] = BlasterDryFireSound;
   stateTransitionOnTimeout[6] = "Ready";
};

datablock ItemData(Blaster)
{
   className = Weapon;
   catagory = "Spawn Items";

   shapeFile = "weapon_energy.dts";
   image = BlasterImage;

   mass = 1;
   trueMass = 1.5;

   elasticity = 0.2;
   friction = 0.6;

   pickupRadius = 2;
   pickUpName = "a blaster";
};

function BlasterImage::onFire(%Data, %Player, %slot)
{
   if (%Player.PlayerNoFire == true)
      return;   %Data.lightStart = getSimTime();

   // If cloaked, uncloak the player for 0.5 seconds to cause the partial phasing effect
   if (%Player.station $= "" && %Player.isCloaked())
   {
      if (%Player.respawnCloakThread !$= "")
      {
         Cancel(%Player.respawnCloakThread);
         %Player.setCloaked(false);
         %Player.respawnCloakThread = "";
      } else {
         if (%Player.getEnergyLevel() > 20)
         {   
            %Player.setCloaked(false);
            %Player.reCloak = %Player.schedule(650, "setCloaked", true);
         }
      }   
   }

   if (%Player.WCSFireMode $= "Burst")
   {   
      %Pi = 3.1415926;
      %ProjectileCount = %Data.projectileCount;

      // If the Player has a prefered spread set, then use that.
      if (%Player.client.WCSBurstSpread !$= "")
         %Spread = 2 * %Pi * %Player.client.WCSBurstSpread;
      else
         %Spread = 2 * %Pi * %Data.projectileSpread;

      %i = 0;
      while (%i < %ProjectileCount)
      {
         %Player.schedule(%i * 150, BlasterBurstFire, %Spread);

         %i++;
      }
   } else {
      %Projectile = new EnergyProjectile()
      {
         dataBlock        = EnergyBolt;
         initialDirection = %Player.getMuzzleVector($WeaponSlot);
         initialPosition  = %Player.getMuzzlePoint($WeaponSlot);
         sourceObject     = %Player;
         sourceSlot       = $WeaponSlot;
      };
      MissionCleanUp.Add(%Projectile);
   }

   %Energy = %Player.getEnergyLevel();
   %Player.setEnergyLevel(%Energy - %Data.fireEnergy);
}

function BlasterImage::WCS(%WCS, %Player, %Direction)
{
   // If not moving backwards, then move forward
   if (%Direction != -1)
      %Direction = 1;

   switch$ (%Player.WCSFireMode)
   {
      case "Burst" :
         %Player.WCSFireMode = "";
         %Message = "Default firing mode selected.";

      default :
         %Player.WCSFireMode = "Burst";
         %Message = "Burst firing mode selected.";
   }

   %Client = %Player.client;

   %Lines = 1;

   bottomPrint(%Client, %Message, 10, %Lines);
      
   %Client.HelpSchedule = schedule(%Lines * 6000, %Client, clearBottomPrint, %Client);
}

function Player::BlasterBurstFire(%Player, %Spread)
{
   %Vector = %Player.getMuzzleVector($WeaponSlot);
   %VectorX = (getRandom() - 0.5) * %Spread;
   %VectorY = (getRandom() - 0.5) * %Spread;
   %VectorZ = (getRandom() - 0.5) * %Spread;
   %Matrix = MatrixCreateFromEuler(%VectorX @ " " @ %VectorY @ " " @ %VectorZ);
   %FiringVector = MatrixMulVector(%Matrix, %Vector);

   %Projectile = new EnergyProjectile()
   {
      dataBlock        = EnergyBurstBolt;
      initialDirection = %FiringVector;
      initialPosition  = %Player.getMuzzlePoint($WeaponSlot);
      sourceObject     = %Player;
      sourceSlot       = $WeaponSlot;
   };
   MissionCleanUp.Add(%Projectile);

   // AI hook
   if(%Player.client)
      %Player.client.projectile = %Projectile;

}