
datablock ItemData(StunBomblet)
{
   shapeFile = "grenade_projectile.dts";
   mass = 0.1;

   scale = ("0.6 0.6 0.6");

   explosion = SmokeBombEffect;
   underwaterExplosion = "UnderwaterGrenadeExplosion";
   splash    = DiscSplash;
};

datablock ItemData(FlashGrenadeThrown)
{
   shapeFile = "grenade.dts";
   mass = 0.6;
   elasticity = 0.2;
   friction = 0.5;
   pickupRadius = 2;
   maxDamage = 0.2;

   emap = true;

   bubbleEmitTime = 1.0;
   explosion = FlashGrenadeExplosion;
   underwaterExplosion = "UnderwaterGrenadeExplosion";
   splash              = GrenadeSplash;

   baseEmitter         = GrenadeSmokeEmitter;
   bubbleEmitter       = GrenadeBubbleEmitter;

   computeCRC = true;
};

function FlashGrenadeThrown::onAdd(%this, %Item)
{
   schedule(200, 0, ConvertFlashGrenade, %Item);

   %Item.schedule(300, delete);
}

function ConvertFlashGrenade(%Item)
{
   %Vector = %Item.getVelocity();
   %Transform = %Item.getTransform();

   %Position = posFromTransform(%Transform);
   %Rotation = rotFromTransform(%Transform);

   %Grenade = new GrenadeProjectile()
   {
      dataBlock = FlashGrenadeProjectile;
      initialDirection = %Vector;
      initialPosition = %Position;
      initialRotation = %Rotation;
   };
   MissionCleanUp.Add(%Grenade);

   %Grenade.InWater = %Grenade.sourceObject.player.InWater;
   schedule(2250, 0, "detonateFlashGrenade", %Grenade);
}

datablock GrenadeProjectileData(FlashGrenadeProjectile)
{
   projectileShapeName = "grenade.dts";
   emitterDelay        = -1;

   directDamage        = 0.0;
   bubbleEmitTime      = 1.0;

   explosion = FlashGrenadeExplosion;
   underwaterExplosion = "UnderwaterGrenadeExplosion";
   splash              = GrenadeSplash;

   baseEmitter         = GrenadeSmokeEmitter;
   bubbleEmitter       = GrenadeBubbleEmitter;
   sound               = GrenadeProjectileSound;

   grenadeElasticity = 0.35;
   grenadeFriction   = 0.2;
   armingDelayMS     = 5000;
   muzzleVelocity    = 1.00;
   drag = 0.1;
};

datablock ItemData(FlashGrenadeFlash)
{
   shapeFile = "turret_muzzlepoint.dts";
   mass = 0.1;
   elasticity = 0.2;
   friction = 0.5;

   emap = true;

   explosion = FlashGrenadeExplosion;
   underwaterExplosion = "UnderwaterGrenadeExplosion";
};

datablock ItemData(FlashGrenade)
{
   className = HandInventory;
   catagory = "Handheld";

   shapeFile = "grenade.dts";
   mass = 1.0;
   trueMass = 0.08;

   elasticity = 0.2;
   friction = 1;
   pickupRadius = 2;

   thrownItem = FlashGrenadeThrown;
   pickUpName = "some stun grenades";

   isGrenade = true;
   computeCRC = true;
};

function detonateFlashGrenade(%Grenade)
{
   %Transform = %Grenade.getTransform();
   %Position = posFromTransform(%Transform);

   // If the Grenade is in the water, just fizzle out
   if (%Grenade.InWater == true)
   {
      UnderwaterIncendiary(%Position);
   } else {
      FlashGrenadeEffect(%Position);
      SmokeBomb(%Position, 5, 20);
   }
   %Grenade.schedule(550, "delete");
}

// Function that creates the new explosions ever 1.25 seconds
function SmokeBomb(%BasePosition, %Number, %Spread)
{
   if (%Spread $= "")
      %Spread = 10;
   %HalfSpread = %Spread / 2;

   WhiteOutCatch(%BasePosition, %Spread * 4);

   %CurrentBombCount = 1;
   %PositionZ = getWord(%BasePosition, 2) + 1;

   while (%CurrentBombCount <= %Number)
   {
      %PositionX = getWord(%BasePosition, 0) + (getRandom() * %Spread) - %HalfSpread;
      %PositionY = getWord(%BasePosition, 1) + (getRandom() * %Spread) - %HalfSpread;
      %Position1 = %PositionX @ " " @ %PositionY @ " " @ %PositionZ;
      %Position2 = %PositionX @ " " @ %PositionY @ " " @ %PositionZ + 1;
      %Position3 = %PositionX @ " " @ %PositionY @ " " @ %PositionZ + 0.5;

      // Make the bombs appear every 500 MS with a variance of up to 750 to make it more realistic
      %Time = %CurrentBombCount * 1000;
      %Time += (getRandom() * 1500) - 750;

      Schedule(%Time, 0, SmokeBombEffect, %Position1);
      Schedule(%Time, 0, SmokeBombEffect, %Position2);
      Schedule(%Time - 500, 0, FlashGrenadeEffect, %Position3);
      Schedule(%Time, 0, WhiteOutCatch, %Position3, %Spread * 2.5);

      %CurrentBombCount++;
   }
}

// Function that creates the individual flash
function FlashGrenadeEffect(%Position)
{
   // Make the Smoke
   %Item = new Item()
   {
      datablock = FlashGrenadeFlash;
      position = %Position;
   };
   MissionCleanup.add(%Item);

   schedule(450, 0, detonateGrenade, %Item);
}
 
// Function that creates the individual explosion
function SmokeBombEffect(%Position)
{
   // Make the Smoke
   %Item = new Item()
   {
      datablock = StunBomblet;
      position = %Position;
   };
   MissionCleanup.add(%Item);

   schedule(450, 0, detonateGrenade, %Item);
}
 
// Function that catches the players within the flash bomb radius and whites them out
// It is now based on whiether you are looking at it or not.
function WhiteOutCatch(%Position, %Radius)
{
   InitContainerRadiusSearch(%Position, %Radius, $TypeMasks::PlayerObjectType);

   while ((%TargetObject = containerSearchNext()) != 0)
   {
      // If the distance is greater than the radius
      %Distance = containerSearchCurrDist();
      if (%Distance > %Radius)
         continue;

      %EyeTransform = %TargetObject.getEyeTransform();
      %EyePosition = posFromTransform(%EyeTransform);

      // Check to see if the head could see it, not checking facing
      if (ContainerRayCast(%EyePosition, %Position, $TypeMasks::TerrainObjectType | $TypeMasks::InteriorObjectType | $TypeMasks::StaticObjectType, %damage) !$= "0")
         continue;

      // If it would collide with your back, then stop
      %HitLocation = getWord(%TargetObject.getDamageLocation(%Position), 1);
      if (getSubStr(%HitLocation, 0, 4) $= "back")
         continue;

      // Base the Whiteout Factor on a non-linear distance relationship (Distance^2 / Position^2)
      %DistanceFactor = 1 - (%Distance * %Distance) / (%Radius * %Radius);

      // Add the Whiteout Factor to the Current Whiteout Factor
      %WhiteoutFactor = %DistanceFactor * 0.45;
      %WhiteOut = %TargetObject.getWhiteOut();
      %TargetObject.setWhiteOut(%WhiteOut + %WhiteoutFactor);

      echo("Distance Factor: " @ %DistanceFactor);
      echo("Whiteout Factor: " @ %WhiteoutFactor);
   }
}