

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

// We redefine the Plasma weapon to catch people on fire if they are within the blast
datablock LinearFlareProjectileData(PlasmaBolt)
{
   projectileShapeName = "plasmabolt.dts";
   scale               = "1.6 1.6 1.6";
   faceViewer          = true;
   directDamage        = 0.0;
   hasDamageRadius     = true;
   indirectDamage      = 0.25;  // was .45 but we also catch the player on fire now
   damageRadius        = 5.0;
   kickBackStrength    = 0.0;
   radiusDamageType    = $DamageType::Fire;

   // The settings for the catching on fire.
   onFire = true;
   BurnStrength = 0.03;
   BurnDuration = 4;

   explosion           = "PlasmaBoltExplosion";
   splash              = PlasmaSplash;

   dryVelocity       = 55.0;
   wetVelocity       = -1;
   velInheritFactor  = 0.3;
   fizzleTimeMS      = 2500;
   lifetimeMS        = 3000;
   explodeOnDeath    = false;
   reflectOnWaterImpactAngle = 0.0;
   explodeOnWaterImpact      = true;
   deflectionOnWaterImpact   = 0.0;
   fizzleUnderwaterMS        = -1;

   activateDelayMS = -1;

   size[0]           = 0.2;
   size[1]           = 0.5;
   size[2]           = 0.1;

   numFlares         = 35;
   flareColor        = "1 0.75 0.25";
   flareModTexture   = "flaremod";
   flareBaseTexture  = "flarebase";

   sound        = PlasmaProjectileSound;
   fireSound    = PlasmaFireSound;
   wetFireSound = PlasmaFireWetSound;
   
   hasLight    = true;
   lightRadius = 3.0;
   lightColor  = "1 0.75 0.25";
};

function PlasmaBolt::onExplode(%Data, %Projectile, %Position, %Modifier)
{
   %Radius = %Data.damageRadius;
   %Damage = %Data.indirectDamage;
   %KickBack = %Data.kickBackStrength;
   %SourceObject = %Projectile.sourceObject;
   %DamageStrength = %Data.BurnStrength;
   %DamageDuration = %Data.BurnDuration;

   %DamageType = %Data.radiusDamageType;

   IncendiaryCheck(%Position, %Radius, %DamageDuration, %DamageStrength, %SourceObject);
   schedule(750, 0, IncendiaryCheck, %Position, %Radius, %DamageDuration * 0.45, %DamageStrength * 0.35, %SourceObject);

   RadiusExplosion(%Projectile, %Position, %Radius, %Damage, %KickBack, %SourceObject, %DamageType);
}

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

datablock ItemData(PlasmaAmmo)
{
   className = Ammo;
   catagory = "Ammo";
   shapeFile = "ammo_plasma.dts";

   mass = 1;
   trueMass = 0.002;

   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 2;

   scale = "0.6 0.6 0.6";

   pickUpName = "some plasma gun ammo";
};

datablock LinearFlareProjectileData(PlasmaBurstBolt)
{
   projectileShapeName = "plasmabolt.dts";
   scale               = "0.6 0.6 0.6";
   faceViewer          = true;
   directDamage        = 0.0;
   hasDamageRadius     = true;
   indirectDamage      = 0.075;
   damageRadius        = 3.5;
   kickBackStrength    = 0.0;
   radiusDamageType    = $DamageType::Fire;

   // The settings for the catching on fire.
   onFire = true;
   BurnStrength = 0.015;
   BurnDuration = 2;

   explosion           = "PlasmaBoltExplosion";
   splash              = PlasmaSplash;

   dryVelocity       = 45.0;
   wetVelocity       = -1;
   velInheritFactor  = 0.3;
   fizzleTimeMS      = 1500;
   lifetimeMS        = 2000;
   explodeOnDeath    = false;
   reflectOnWaterImpactAngle = 0.0;
   explodeOnWaterImpact      = true;
   deflectionOnWaterImpact   = 0.0;
   fizzleUnderwaterMS        = -1;

   activateDelayMS = -1;

   size[0]           = 0.2;
   size[1]           = 0.5;
   size[2]           = 0.1;

   numFlares         = 24;
   flareColor        = "1 0.75 0.25";
   flareModTexture   = "flaremod";
   flareBaseTexture  = "flarebase";

   sound        = PlasmaProjectileSound;
   fireSound    = PlasmaFireSound;
   wetFireSound = PlasmaFireWetSound;
   
   hasLight    = true;
   lightRadius = 2.0;
   lightColor  = "1 0.75 0.25";
};

function PlasmaBurstBolt::onExplode(%Data, %Projectile, %Position, %Modifier)
{
   %Radius = %Data.damageRadius;
   %Damage = %Data.indirectDamage;
   %KickBack = %Data.kickBackStrength;
   %SourceObject = %Projectile.sourceObject;
   %DamageStrength = %Data.BurnStrength;
   %DamageDuration = %Data.BurnDuration;

   %DamageType = %Data.radiusDamageType;

   IncendiaryCheck(%Position, %Radius, %DamageDuration, %DamageStrength, %SourceObject);
   schedule(750, 0, IncendiaryCheck, %Position, %Radius, %DamageDuration * 0.45, %DamageStrength * 0.35, %SourceObject);

   RadiusExplosion(%Projectile, %Position, %Radius, %Damage, %KickBack, %SourceObject, %DamageType);
}

//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ItemData(Plasma)
{
   className = Weapon;
   catagory = "Spawn Items";
   shapeFile = "weapon_plasma.dts";
   image = PlasmaImage;

   mass = 1;
   trueMass = 2.5;

   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 2;
   pickUpName = "a plasma gun";
};

datablock ShapeBaseImageData(PlasmaImage)
{
   className = WeaponImage;
   shapeFile = "weapon_plasma.dts";
   item = Plasma;
   ammo = PlasmaAmmo;
   offset = "0 0 0";

   projectile = PlasmaBolt;
   projectileType = LinearFlareProjectile;

   WCS = true;
   WCSFirePattern = true;

   projectileSpread = 44/1000;
   projectileCount = 3;

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

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

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

   stateName[3] = "Fire";
   stateTransitionOnTimeout[3] = "Reload";
   stateTimeoutValue[3] = 0.1;
   stateFire[3] = true;
   stateRecoil[3] = LightRecoil;
   stateAllowImageChange[3] = false;
   stateScript[3] = "onFire";
   stateEmitterTime[3] = 0.2;
   stateSound[3] = PlasmaFireSound;

   stateName[4] = "Reload";
   stateTransitionOnNoAmmo[4] = "NoAmmo";
   stateTransitionOnTimeout[4] = "Ready";
   stateTimeoutValue[4] = 0.6;
   stateAllowImageChange[4] = false;
   stateSequence[4] = "Reload";
   stateSound[4] = PlasmaReloadSound;

   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";
   
   stateName[7]       = "WetFire";
   stateSound[7]      = PlasmaFireWetSound;
   stateTimeoutValue[7]        = 1.5;
   stateTransitionOnTimeout[7] = "Ready";
   
   stateName[8]               = "CheckWet";
   stateTransitionOnWet[8]    = "WetFire";
   stateTransitionOnNotWet[8] = "Fire"; 
};

function PlasmaImage::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 !$= "" && %Player.WCSAlternating < 1)
   {   
      %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 * 200, PlasmaBurstFire, %Spread);

         %i++;
      }

      // If Alternating, tell it to fire a full powered shot next time.
      if (%Player.WCSFireMode $= "Alternating")
      {
         if (%Player.WCSReset !$= "")
            cancel(%Player.WCSReset);

         %Player.WCSReset = %Player.schedule(750, ResetAlternatingFire);
         %Player.WCSAlternating = 1;
      }
   } else {
      %Projectile = new LinearFlareProjectile()
      {
         dataBlock        = PlasmaBolt;
         initialDirection = %Player.getMuzzleVector($WeaponSlot);
         initialPosition  = %Player.getMuzzlePoint($WeaponSlot);
         sourceObject     = %Player;
         sourceSlot       = $WeaponSlot;
      };
      MissionCleanUp.Add(%Projectile);

      %Player.WCSAlternating = 0;
   }

   %Player.schedule(250, decInventory, %Data.ammo, 1);
}

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

   if (%Player.InWater == true)
      messageClient(%Player.client, '', "Weapons Control System allows changing firing modes while underwater, but will not allow you to fire!");   

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

      case "Burst" :
         %Player.WCSFireMode = "";
         %Message = "Default firing mode selected.";
         %Player.WCSAlternating = 1;

      default :
         %Player.WCSFireMode = "Alternating";
         %Message = "Alternating firing mode selected.";
         %Player.WCSAlternating = 1;
   }

   %Client = %Player.client;

   %Lines = 1;

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

function Player::PlasmaBurstFire(%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 LinearFlareProjectile()
   {
      dataBlock        = PlasmaBurstBolt;
      initialDirection = %FiringVector;
      initialPosition  = %Player.getMuzzlePoint($WeaponSlot);
      sourceObject     = %Player;
      sourceSlot       = $WeaponSlot;
   };
   MissionCleanUp.Add(%Projectile);

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

}

function Player::ResetAlternatingFire(%Player)
{
   %Player.WCSAlternating = 1;
}