 
//--------------------------------------------------------------------------
// Pellets
//--------------------------------------------------------------------------

datablock TracerProjectileData(ShotgunPellet)
{
   doDynamicClientHits = true;

   directDamage        = 0.058;
   directDamageType    = $DamageType::Bullet;
   explosion           = "ChaingunExplosion";
   splash              = ChaingunSplash;

   kickBackStrength   = 250.0;
   sound              = ChaingunProjectile;

   dryVelocity        = 425.0;
   wetVelocity        = 100.0;
   velInheritFactor   = 1.0;
   fizzleTimeMS       = 500;
   lifetimeMS         = 1000;
   explodeOnDeath     = false;

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

   tracerLength    = 10.0;
   tracerAlpha     = false;
   tracerMinPixels = 6;
   tracerColor     = "0.82 0.83 0.49 0.5";
   tracerTex[0]    = "special/tracer00";
   tracerTex[1]    = "special/tracercross";
   tracerWidth     = 0.10;

   rearDamageFactor    = 1.22;

   crossSize       = 0.20;
   crossViewAng    = 0.990;
   renderCross     = true;

   decalData[0] = ChaingunDecal1;
   decalData[1] = ChaingunDecal2;
   decalData[2] = ChaingunDecal3;
   decalData[3] = ChaingunDecal4;
   decalData[4] = ChaingunDecal5;
   decalData[5] = ChaingunDecal6;
};

//--------------------------------------------------------------------------
// Ammo
//--------------------------------------------------------------------------

datablock ItemData(ShotgunAmmo)
{
   className = Ammo;
   catagory = "Ammo";
   shapeFile = "ammo_chaingun.dts";

   mass = 1;
   trueMass = 0.008;

   elasticity = 0.2;
   friction = 0.6;

   pickupRadius = 2;
   pickUpName = "some shotgun ammo";

   computeCRC = true;
};

//--------------------------------------------------------------------------
// Weapon
//--------------------------------------------------------------------------

datablock DebrisData(ShotgunShellDebris)
{
   shapeName = "weapon_chaingun_ammocasing.dts";

   scale = "2.0 2.0 2.0";

   lifetime = 4.0;

   minSpinSpeed = 100.0;
   maxSpinSpeed = 200.0;

   elasticity = 0.5;
   friction = 0.2;

   numBounces = 3;

   fade = true;
   staticOnMaxBounce = true;
   snapOnMaxBounce = true;
};             

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

   shapeFile    = "weapon_plasma.dts";
   image        = ShotgunImage;

   mass         = 1;
   trueMass     = 2.5;

   elasticity   = 0.2;
   friction     = 0.6;

   pickupRadius = 2;
   pickUpName   = "a shotgun";

   computeCRC = true;
   emap = true;
};

datablock ShapeBaseImageData(ShotgunImage)
{
   className = WeaponImage;
   shapeFile = "weapon_energy.dts";

   item           = Shotgun;
   ammo           = ShotgunAmmo;

   offset = "0.02 0 0.05";
   rotation = "0 0.65 0 90";

   projectile     = ShotgunPellet;
   projectileType = TracerProjectile;

   emap = true;

   casing              = ShotgunShellDebris;
   shellExitDir        = "1.0 0.3 1.0";
   shellExitOffset     = "0.15 -0.56 -0.1";
   shellExitVariance   = 10.0;
   shellVelocity       = 1.0;

   projectileSpread = 20.0 / 1000.0;
   projectileCount = 6;

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

   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.8;
   stateFire[3]                = true;
   stateRecoil[3]              = NoRecoil;
   stateAllowImageChange[3]    = false;
   stateSequence[3]            = "Fire";
   stateScript[3]              = "onFire";
   stateSound[3]               = ShotgunFireSound;

   stateName[4] = "Reload";
   stateTransitionOnNoAmmo[4] = "NoAmmo";
   stateTransitionOnTimeout[4] = "ActivateReady";
   stateTimeoutValue[4] = 3.25;
   stateAllowImageChange[3] = true;
   stateSequence[4] = "Reload";

   stateName[5] = "NoAmmo";
   stateTransitionOnAmmo[5] = "Reload";
   stateSequence[5] = "NoAmmo";
   stateTransitionOnTriggerDown[5] = "DryFire";

   stateName[6]       = "DryFire";
   stateSound[6]      = PlasmaDryFireSound;
   stateTimeoutValue[6]        = 1.5;
   stateTransitionOnTimeout[6] = "NoAmmo";
};

function ShotgunImage::onFire(%data, %Player, %slot)
{
   %Data.lightStart = getSimTime();

   // If cloaked, uncloak the player for 0.75 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(750, "setCloaked", true);
         }
      }   
   }

   %TwoPi = 2 * 3.1415926;
   %Spread =  %TwoPi * %Data.projectileSpread;
   %ProjectileCount = %Data.projectileCount;
   %ProjectileType = %Data.projectile;
   %Vector = %Player.getMuzzleVector(%Slot);
   %Position = %Player.getMuzzlePoint($WeaponSlot);

   %Count = 1;
   while (%Count <= %ProjectileCount)
   {
      %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 (%Data.projectileType)() 
      {
         dataBlock        = %ProjectileType;
         initialDirection = %FiringVector;
         initialPosition  = %Position;
         sourceObject     = %Player;
         sourceSlot       = $WeaponSlot;
      };
      MissionCleanup.add(%Projectile);

      %Count++;
   }

   %ReverseVector = VectorScale(%Vector, -450);
   %Player.applyImpulse(%Position, %ReverseVector);

   %Player.lastProjectile = %Projectile;
   %Projectile.InWater = %Player.InWater;
   %Player.decInventory(%Data.ammo,1);

   %Player.schedule(350, setImageTrigger, 1, true);

   return(%Projectile);
}

function ShotGunImage::onMount(%this, %Player, %Slot)
{
   Parent::onMount(%this, %Player, %Slot);

   %Player.mountImage(ShotgunImagePair, 1);
}

function ShotGunImage::onunMount(%this, %Player, %Slot)
{
   Parent::onunMount(%this, %Player, %Slot);

   %Player.unmountImage(1);
}

datablock ShapeBaseImageData(ShotgunImagePair)
{
   className = WeaponImage;
   shapeFile = "weapon_energy.dts";

   item           = Shotgun;
   ammo           = ShotgunAmmo;

   UseCrossHair = Chaingun;

   offset = "-0.02 0 0.05";
   rotation = "0 -0.65 0 90";

   projectile     = ShotgunPellet;
   projectileType = TracerProjectile;

   emap = true;

   casing              = ShotgunShellDebris;
   shellExitDir        = "1.0 0.3 1.0";
   shellExitOffset     = "0.15 -0.56 -0.1";
   shellExitVariance   = 10.0;
   shellVelocity       = 1.0;

   projectileSpread = 20.0 / 1000.0;
   projectileCount = 6;

   stateName[0]                     = "WaitFire";
   stateTransitionOnTriggerDown[0]  = "Fire";

   stateName[1]                     = "Fire";
   stateTransitionOnTimeout[1]      = "StopFire";
   stateTimeoutValue[1]             = 0.3;
   stateFire[1]                     = true;
   stateAllowImageChange[1]         = true;
   stateSequence[1]                 = "Fire";
   stateScript[1]                   = "onFire";
   stateSound[1]                    = ShotgunFireSound;

   stateName[2]                     = "StopFire";
   stateTimeoutValue[2]             = 0.1;
   stateTransitionOnTimeout[2]      = "WaitFire";
   stateScript[2]                   = "stopFire";
};

function ShotgunImagePair::onFire(%data, %Player, %slot)
{
   %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);
         }
      }   
   }

   %TwoPi = 2 * 3.1415926;
   %Spread =  %TwoPi * %Data.projectileSpread;
   %ProjectileCount = %Data.projectileCount;
   %ProjectileType = %Data.projectile;
   %Vector = %Player.getMuzzleVector(%Slot);
   %Position = %Player.getMuzzlePoint($WeaponSlot);

   %Count = 1;
   while (%Count <= %ProjectileCount)
   {
      %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 (%Data.projectileType)() 
      {
         dataBlock        = %ProjectileType;
         initialDirection = %FiringVector;
         initialPosition  = %Position;
         sourceObject     = %Player;
         sourceSlot       = $WeaponSlot;
      };
      MissionCleanup.add(%Projectile);

      %Count++;
   }

   %ReverseVector = VectorScale(%Vector, -450);
   %Player.applyImpulse(%Position, %ReverseVector);

   %Player.lastProjectile = %Projectile;
   %Projectile.InWater = %Player.InWater;
   %Player.decInventory(%Data.ammo,1);

   %Player.setImageTrigger(1, false);

   return(%Projectile);
}