
//--------------------------------------------------------------------------
// Projectile
//--------------------------------------
datablock GrenadeProjectileData(BasicGrenade)
{
   projectileShapeName = "grenade_projectile.dts";
   emitterDelay        = -1;
   directDamage        = 0.0;
   hasDamageRadius     = true;
   indirectDamage      = 0.40;
   damageRadius        = 15.0;
   radiusDamageType    = $DamageType::Grenade;
   kickBackStrength    = 1500;
   bubbleEmitTime      = 1.0;

   sound               = GrenadeProjectileSound;
   explosion           = "GrenadeExplosion";
   underwaterExplosion = "UnderwaterGrenadeExplosion";
   velInheritFactor    = 0.7;
   splash              = GrenadeSplash;

   baseEmitter         = GrenadeSmokeEmitter;
   bubbleEmitter       = GrenadeBubbleEmitter;

   grenadeElasticity = 0.35;
   grenadeFriction   = 0.2;
   armingDelayMS     = 1000;
   muzzleVelocity    = 47.00;
   drag = 0.1;

   rearDamageFactor    = 1.2;

   PrematureProjectile      = BasicGrenadeItem;
   PrematureWetTime         = 3000;
   PrematureWetTimeVariance = 3000;
};

datablock ItemData(BasicGrenadeItem)
{
   shapeName = "grenade_projectile.dts";
   hasDamageRadius     = true;
   indirectDamage      = 0.40;
   damageRadius        = 15.0;
   radiusDamageType    = $DamageType::Grenade;
   kickBackStrength    = 2500;

   sound               = GrenadeProjectileSound;
   explosion           = "GrenadeExplosion";
   underwaterExplosion = "UnderwaterGrenadeExplosion";
   velInheritFactor    = 0.5;
   splash              = GrenadeSplash;

   rearDamageFactor    = 1.2;

   grenadeElasticity = 0.35;
   grenadeFriction   = 0.2;
};

datablock GrenadeProjectileData(BasicEMPGrenade)
{
   projectileShapeName = "grenade_projectile.dts";

   EMPDuration = 10.0;
   EMPStrength = 0.2;

   explosion = EMPBlastExplosion;
   splash = DiscSplash;
   sound               = GrenadeProjectileSound;
   underwaterExplosion = "UnderwaterGrenadeExplosion";
   velInheritFactor    = 0.7;

   radiusDamageType = $DamageType::Grenade;
   kickBackStrength = 0;
   hasLight    = true;
   lightType = "PulsingLight";
   lightColor = "0.5 1.0 1.0 0.75";
   lightTime = "1000";
   lightRadius = 1;

   hasLightUnderwaterColor  = true;
   underWaterLightColor     = "0.5 1 1";

   hasDamageRadius = false;
   indirectDamage = 0.0;
   damageRadius = 12.0;
   radiusDamageType    = $DamageType::Grenade;

   bubbleEmitTime      = 1.0;
   emitterDelay        = -1;
   baseEmitter         = EMPHazeEmitter;
   bubbleEmitter       = GrenadeBubbleEmitter;

   grenadeElasticity = 0.35;
   grenadeFriction   = 0.2;
   armingDelayMS     = 1000;
   muzzleVelocity    = 47.00;
   drag = 0.1;

   PrematureProjectile      = BasicEMPGrenadeItem;
   PrematureWetTime         = 3000;
   PrematureWetTimeVariance = 3000;
};

datablock ItemData(BasicEMPGrenadeItem)
{
   shapeName = "grenade_projectile.dts";

   directDamage        = 0.0;
   hasDamageRadius     = true;
   damageRadius        = 12.0;

   velInheritFactor    = 0.5;

   EMPDuration = 10.0;
   EMPStrength = 0.2;

   explosion           = EMPBlastExplosion;
   underwaterExplosion = "UnderwaterMortarExplosion";
   velInheritFactor    = 0.5;
   splash              = DiscSplash;

   sound               = GrenadeProjectileSound;

   hasLight    = true;
   lightType = "PulsingLight";
   lightColor = "0.5 1.0 1.0 0.75";
   lightTime = "1000";
   lightRadius = 0.75;

   hasLightUnderwaterColor  = true;
   underWaterLightColor     = "0.5 1 1";
};

function BasicEMPGrenade::onExplode(%Data, %Projectile, %Position, %Modifier)
{
   %PositionXY = getWords(%Position, 0, 1);
   %PositionZ = getWord(%Position, 2) + 0.4;
   %Position = %PositionXY @ " " @ %PositionZ;

   %Owner = %Projectile.sourceObject;
   %Radius = %Data.damageRadius;
   %EMPStrength = %Data.EMPStrength;
   %EMPDuration = %Data.EMPDuration;

   // If the grenade is in the water, make it more potent
   if (%Projectile.InWater == true || CheckinWater(%Projectile) == true)
   {
      %EMPStrength *= 0.6;
      %EMPDuration *= 1.4;
      %Radius *= 1.2;
   }

   // Do the EMP checks
   EMPingCheck(%Position, %Radius, %EMPDuration, %EMPStrength, %Owner);
   schedule(1000, 0, EMPingCheck, %Position, %Radius, %EMPDuration * 0.8, %EMPStrength * 1.2, %Owner);
   schedule(2000, 0, EMPingCheck, %Position, %Radius, %EMPDuration * 0.6, %EMPStrength * 1.4, %Owner);

   AreaEMP(%Position);

   if ($Host::MaxBotDifficulty > 0.88)
      MakeAvoidObject(%Position, 2600);
}

function BasicEMPGrenadeItem::onDestroyed(%data, %Projectile, %lastState)
{
   %Transform = %Projectile.getTransform();
   %Position = posFromTransform(%Transform);
   %PositionXY = getWords(%Position, 0, 1);
   %PositionZ = getWord(%Position, 2) + 0.4;
   %Position = %PositionXY @ " " @ %PositionZ;

   %Owner = %Projectile.sourceObject;
   %Radius = %Data.damageRadius;
   %EMPStrength = %Data.EMPStrength;
   %EMPDuration = %Data.EMPDuration;

   // If the grenade is in the water, make it more potent
   if (%Projectile.InWater == true || CheckinWater(%Projectile) == true)
   {
      %EMPStrength *= 0.6;
      %EMPDuration *= 1.4;
      %Radius *= 1.2;
   }

   // Do the EMP checks
   EMPingCheck(%Position, %Radius, %EMPDuration, %EMPStrength, %Owner);
   schedule(1100, 0, EMPingCheck, %Position, %Radius, %EMPDuration * 0.8, %EMPStrength * 1.2, %Owner);
   schedule(2200, 0, EMPingCheck, %Position, %Radius, %EMPDuration * 0.6, %EMPStrength * 1.3, %Owner);

   AreaEMP(%Position);

   if ($Host::MaxBotDifficulty > 0.88)
      MakeAvoidObject(%Position, 2800);
}

datablock ParticleData(SmallFireParticle)
{
    dragCoefficient = 0;
    gravityCoefficient = 0;
    windCoefficient = 1;
    inheritedVelFactor = 1;
    constantAcceleration = 0;
    lifetimeMS = 200;
    lifetimeVarianceMS = 40;
    useInvAlpha = 0;
    spinRandomMin = -135;
    spinRandomMax = 135;
    textureName = "particleTest";

    times[0] = 0;
    times[1] = 0.4;
    times[2] = 1;

    colors[0] = "1.00 0.75 0.20 0.50";
    colors[1] = "1.00 0.50 0.00 0.20";
    colors[2] = "1.00 0.40 0.00 0.00";

    sizes[0] = 0.10;
    sizes[1] = 0.04;
    sizes[2] = 0.0;
};

datablock ParticleEmitterData(SmallFireEmitter)
{
    ejectionPeriodMS = 18;
    periodVarianceMS = 2;

    ejectionVelocity = 2;
    velocityVariance = 1;

    ejectionOffset =   0.05;

    thetaMin = 12.2;
    thetaMax = 20.5;

    phiReferenceVel = 360;
    phiVariance = 360;

    overrideAdvances = 0;

    orientParticles= 0;
    orientOnVelocity = 1;

    particles = "SmallFireParticle";
};

datablock GrenadeProjectileData(BasicIncGrenade)
{
   projectileShapeName = "grenade_projectile.dts";
 
   indirectDamage = 0.075;

   damageRadius = 8.0;
   radiusDamageType = $DamageType::Grenade;
   kickBackStrength = 0;

   BurnStrength = 0.04;
   BurnDuration = 9;

   explosion = "IncendiaryGrenadeExplosion";
   underwaterExplosion = "UnderwaterGrenadeExplosion";

   sound               = GrenadeProjectileSound;
   velInheritFactor    = 0.7;
   splash              = GrenadeSplash;

   emitterDelay        = -1;
   baseEmitter         = MissileFireEmitter;

   bubbleEmitTime      = 1.0;
   bubbleEmitter       = GrenadeBubbleEmitter;

   grenadeElasticity = 0.35;
   grenadeFriction   = 0.2;
   armingDelayMS     = 1000;
   muzzleVelocity    = 47.00;
   drag = 0.1;
};

function BasicIncGrenade::onExplode(%Data, %Projectile, %Position, %Modifier)
{
   %PositionXY = getWords(%Position, 0, 1);
   %PositionZ = getWord(%Position, 2) + 0.2;
   %Position = %PositionXY @ " " @ %PositionZ;

   // If the grenade is in the water, fizzle out
   if (%Projectile.InWater == true || CheckinWater(%Projectile) == true)
      return;

   %Owner = %Projectile.sourceObject;
   %IndirectDamage = %Data.indirectDamage;
   %DamageType = %Data.radiusDamageType;
   %Radius = %Data.damageRadius;
   %DamageStrength = %Data.BurnStrength;
   %DamageDuration = %Data.BurnDuration;

   %Number = (getRandom(4.0) + 1);

   // Do the OnFire checks
   IncendiaryCheck(%Position, %Radius, %DamageDuration, %DamageStrength, %Owner);
   schedule(750, 0, IncendiaryCheck, %Position, %Radius, %DamageDuration * 0.8, %DamageStrength * 0.6, %Owner);
   schedule(1500, 0, IncendiaryCheck, %Position, %Radius, %DamageDuration * 0.6, %DamageStrength * 0.5, %Owner);
   schedule(2250, 0, IncendiaryCheck, %Position, %Radius, %DamageDuration * 0.4, %DamageStrength * 0.4, %Owner);
   schedule(3000, 0, IncendiaryCheck, %Position, %Radius * 0.8, %DamageDuration * 0.2, %DamageStrength * 0.2, %Owner);
   schedule(3600, 0, FillAreaSmoke, %Position, %Number * 0.8, 450);

   FillAreaFire(%Position, %Radius * 0.8, %Number * 0.7);

   if ($Host::MaxBotDifficulty > 0.85)
      MakeAvoidObject(%Position, 4200);
}

datablock GrenadeProjectileData(BasicConcGrenade)
{
   projectileShapeName = "grenade_projectile.dts";

   hasDamageRadius   = true;
   damageRadius      = 15.0;
   radiusDamageType  = $DamageType::Explosion;
   kickBackStrength  = 3500;

   velInheritFactor    = 0.5;

   ApplyConcussion = true;

   explosion = ConcussionGrenadeExplosion;
   underwaterExplosion = UnderwaterHandGrenadeExplosion;

   hasLight    = true;
   lightType = "PulsingLight";
   lightColor = "0.8 0.8 1.0 0.4";
   lightTime = "1000";
   lightRadius = "1";

   depthTolerance      = 1.0;

   emitterDelay        = -1;
   baseEmitter         = ConcHazeEmitter;
   bubbleEmitter       = GrenadeBubbleEmitter;
   
   grenadeElasticity = 0.15;
   grenadeFriction   = 0.4;
   armingDelayMS     = 2000;
   muzzleVelocity    = 63.7;
   drag              = 0.1;

   sound             = MortarProjectileSound;

   PrematureProjectile      = BasicConcGrenadeItem;
   PrematureWetTime         = 3500;
   PrematureWetTimeVariance = 3000;
};

datablock ItemData(BasicConcGrenadeItem)
{
   Shapefile = "grenade_projectile.dts";

   hasDamageRadius   = true;
   damageRadius      = 15.0;
   radiusDamageType  = $DamageType::Explosion;
   kickBackStrength  = 3500;

   velInheritFactor    = 0.5;

   ApplyConcussion = true;

   explosion = ConcussionGrenadeExplosion;
   underwaterExplosion = UnderwaterHandGrenadeExplosion;

   hasLight    = true;
   lightType = "PulsingLight";
   lightColor = "0.5 0.0 0.5 0.4";
   lightTime = 1000;
   lightRadius = 2;

   hasLightUnderwaterColor = true;
   underWaterLightColor = "0.5 0.0 0.5";
};

function BasicConcGrenade::onExplode(%Data, %Projectile, %Position, %Modifier)
{
   %Radius = %Data.damageRadius;
   %Damage = %Data.indirectDamage;
   %KickBack = %Data.kickBackStrength;
   %Owner = %Projectile.sourceObject;
   %DamageType = %Data.radiusDamageType;

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

function BasicConcGrenadeItem::onDestroyed(%data, %Projectile, %lastState)
{
   %Transform = %Projectile.getTransform();
   %Position = posFromTransform(%Transform);

   %Radius = %Data.damageRadius;
   %Damage = %Data.indirectDamage;
   %KickBack = %Data.kickBackStrength;
   %Owner = %Projectile.sourceObject;
   %DamageType = %Data.radiusDamageType;

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

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

datablock ItemData(GrenadeLauncherAmmo)
{
   className = Ammo;
   catagory = "Ammo";
   shapeFile = "ammo_grenade.dts";

   mass = 1;
   trueMass = 0.025;

   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 2;
   pickUpName = "some grenade launcher ammo";

   computeCRC = true;
   emap = true;
};

//--------------------------------------------------------------------------
// Weapon
//--------------------------------------
datablock ItemData(GrenadeLauncher)
{
   className = Weapon;
   catagory = "Spawn Items";
   shapeFile = "weapon_grenade_launcher.dts";
   image = GrenadeLauncherImage;

   mass = 1;
   trueMass = 4;

   elasticity = 0.2;
   friction = 0.6;
   pickupRadius = 2;
   pickUpName = "a grenade launcher";

   computeCRC = true;

};

datablock ShapeBaseImageData(GrenadeLauncherImage)
{
   className = WeaponImage;
   shapeFile = "weapon_grenade_launcher.dts";

   item = GrenadeLauncher;
   ammo = GrenadeLauncherAmmo;

   offset = "0 0 0";
   emap = true;

   ProjectileType = GrenadeProjectile;
   Projectile = BasicGrenade;
   EMPProjectile = BasicEMPGrenade;
   IncProjectile = BasicIncGrenade;
   ConcProjectile = BasicConcGrenade;

   WCS = true;

   FailSound = GrenadeDryFireSound;

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

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

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

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

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

function BasicGrenade::onAdd(%this, %Projectile)
{
   Parent::onAdd(%this, %Projectile);

   schedule(20000, 0, ProjectileDetonate, %Projectile);
}