//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

// Load dts shapes and merge animations
exec("scripts/light_male.cs");
exec("scripts/medium_male.cs");
exec("scripts/heavy_male.cs");
exec("scripts/light_female.cs");
exec("scripts/medium_female.cs");
exec("scripts/bioderm_light.cs");
exec("scripts/bioderm_medium.cs");
exec("scripts/bioderm_heavy.cs");

$PlayerDeathAnim::TorsoFrontFallForward = 1;
$PlayerDeathAnim::TorsoFrontFallBack = 2;
$PlayerDeathAnim::TorsoBackFallForward = 3;
$PlayerDeathAnim::TorsoLeftSpinDeath = 4;
$PlayerDeathAnim::TorsoRightSpinDeath = 5;
$PlayerDeathAnim::LegsLeftGimp = 6;
$PlayerDeathAnim::LegsRightGimp = 7;
$PlayerDeathAnim::TorsoBackFallForward = 8;
$PlayerDeathAnim::HeadFrontDirect = 9;
$PlayerDeathAnim::HeadBackFallForward = 10;
$PlayerDeathAnim::ExplosionBlowBack = 11;

datablock SensorData(PlayerSensor)
{
   detects = true;
   detectsUsingLOS = true;
   detectsPassiveJammed = true;
   detectRadius = 2000;
   detectionPings = false;
   detectsFOVOnly = true;
   detectFOVPercent = 1.3;
   useObjectFOV = true;
};

//----------------------------------------------------------------------------

datablock EffectProfile(ArmorJetEffect)
{
   effectname = "armor/thrust";
   minDistance = 5.0;
   maxDistance = 10.0;
};

datablock EffectProfile(ImpactSoftEffect)
{
   effectname = "armor/light_land_soft";
   minDistance = 5.0;
   maxDistance = 10.0;
};

datablock EffectProfile(ImpactHardEffect)
{
   effectname = "armor/light_land_hard";
   minDistance = 5.0;
   maxDistance = 10.0;
};

datablock EffectProfile(ImpactMetalEffect)
{
   effectname = "armor/light_land_metal";
   minDistance = 5.0;
   maxDistance = 10.0;
};

datablock EffectProfile(ImpactSnowEffect)
{
   effectname = "armor/light_land_snow";
   minDistance = 5.0;
   maxDistance = 10.0;
};

datablock EffectProfile(CorpseLootingEffect)
{
   effectname = "weapons/generic_switch";
   minDistance = 2.5;
};

datablock EffectProfile(MountVehicleEffect)
{
   effectname = "vehicles/mount_dis";
   minDistance = 20;
};

datablock EffectProfile(UnmountVehicleEffect)
{
   effectname = "weapons/generic_switch";
   minDistance = 20;
};

//----------------------------------------------------------------------------

datablock AudioProfile( DeathCrySound )
{
   fileName = "";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile( PainCrySound )
{
   fileName = "";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ArmorJetSound)
{
   filename    = "fx/armor/thrust.wav";
   description = CloseLooping3d;
   preload = true;
   effect = ArmorJetEffect;
};

datablock AudioProfile(ArmorWetJetSound)
{
   filename    = "fx/armor/thrust_uw.wav";
   description = CloseLooping3d;
   preload = true;
   effect = ArmorJetEffect;
};

datablock AudioProfile(MountVehicleSound)
{
   filename    = "fx/vehicles/mount_dis.wav";
   description = AudioClose3d;
   preload = true;
   effect = MountVehicleEffect;
};

datablock AudioProfile(UnmountVehicleSound)
{
   filename    = "fx/vehicles/mount.wav";
   description = AudioClose3d;
   preload = true;
   effect = UnmountVehicleEffect;
};

datablock AudioProfile(CorpseLootingSound)
{
   fileName = "fx/weapons/generic_switch.wav";
   description = AudioClosest3d;
   preload = true;
   effect = CorpseLootingEffect;
};
          
datablock AudioProfile(ArmorMoveBubblesSound)
{
   filename    = "fx/armor/bubbletrail2.wav";
   description = CloseLooping3d;
   preload = true;
};

datablock AudioProfile(WaterBreathMaleSound)
{
   filename    = "fx/armor/breath_uw.wav";
   description = ClosestLooping3d;
   preload = true;
};

datablock AudioProfile(WaterBreathFemaleSound)
{
   filename    = "fx/armor/breath_fem_uw.wav";
   description = ClosestLooping3d;
   preload = true;
};

datablock AudioProfile(waterBreathBiodermSound)
{
   filename    = "fx/armor/breath_bio_uw.wav";
   description = ClosestLooping3d;
   preload = true;
};

datablock AudioProfile(SkiAllSoftSound)
{
   filename    = "fx/armor/ski_soft.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(SkiAllHardSound)
{
   filename    = "fx/armor/ski_soft.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(SkiAllMetalSound)
{
   filename    = "fx/armor/ski_soft.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(SkiAllSnowSound)
{
   filename    = "fx/armor/ski_soft.wav";
   description = AudioClosest3d;
   preload = true;
};

//SOUNDS ----- LIGHT ARMOR--------
datablock AudioProfile(LFootLightSoftSound)
{
   filename    = "fx/armor/light_LF_soft.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootLightSoftSound)
{
   filename    = "fx/armor/light_RF_soft.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootLightHardSound)
{
   filename    = "fx/armor/light_LF_hard.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootLightHardSound)
{
   filename    = "fx/armor/light_RF_hard.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootLightMetalSound)
{
   filename    = "fx/armor/light_LF_metal.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootLightMetalSound)
{
   filename    = "fx/armor/light_RF_metal.wav";
   description = AudioClose3d;
   preload = true;
};
datablock AudioProfile(LFootLightSnowSound)
{
   filename    = "fx/armor/light_LF_snow.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootLightSnowSound)
{
   filename    = "fx/armor/light_RF_snow.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootLightShallowSplashSound)
{
   filename    = "fx/armor/light_LF_water.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootLightShallowSplashSound)
{
   filename    = "fx/armor/light_RF_water.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootLightWadingSound)
{
   filename    = "fx/armor/light_LF_wade.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootLightWadingSound)
{
   filename    = "fx/armor/light_RF_wade.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootLightUnderwaterSound)
{
   filename    = "fx/armor/light_LF_uw.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootLightUnderwaterSound)
{
   filename    = "fx/armor/light_RF_uw.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootLightBubblesSound)
{
   filename    = "fx/armor/light_LF_bubbles.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootLightBubblesSound)
{
   filename    = "fx/armor/light_RF_bubbles.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ImpactLightSoftSound)
{
   filename    = "fx/armor/light_land_soft.wav";
   description = AudioClose3d;
   preload = true;
   effect = ImpactSoftEffect;
};

datablock AudioProfile(ImpactLightHardSound)
{
   filename    = "fx/armor/light_land_hard.wav";
   description = AudioClose3d;
   preload = true;
   effect = ImpactHardEffect;
};

datablock AudioProfile(ImpactLightMetalSound)
{
   filename    = "fx/armor/light_land_metal.wav";
   description = AudioClose3d;
   preload = true;
   effect = ImpactMetalEffect;
};

datablock AudioProfile(ImpactLightSnowSound)
{
   filename    = "fx/armor/light_land_snow.wav";
   description = AudioClosest3d;
   preload = true;
   effect = ImpactSnowEffect;
};

datablock AudioProfile(ImpactLightWaterEasySound)
{
   filename    = "fx/armor/general_water_smallsplash2.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ImpactLightWaterMediumSound)
{
   filename    = "fx/armor/general_water_medsplash.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ImpactLightWaterHardSound)
{
   filename    = "fx/armor/general_water_bigsplash.wav";
   description = AudioDefault3d;
   preload = true;
};

datablock AudioProfile(ExitingWaterLightSound)
{
   filename    = "fx/armor/general_water_exit2.wav";
   description = AudioClose3d;
   preload = true;
};

//SOUNDS ----- Medium ARMOR--------
datablock AudioProfile(LFootMediumSoftSound)
{
   filename    = "fx/armor/med_LF_soft.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootMediumSoftSound)
{
   filename    = "fx/armor/med_RF_soft.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootMediumHardSound)
{
   filename    = "fx/armor/med_LF_hard.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootMediumHardSound)
{
   filename    = "fx/armor/med_RF_hard.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootMediumMetalSound)
{
   filename    = "fx/armor/med_LF_metal.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootMediumMetalSound)
{
   filename    = "fx/armor/med_RF_metal.wav";
   description = AudioClose3d;
   preload = true;
};
datablock AudioProfile(LFootMediumSnowSound)
{
   filename    = "fx/armor/med_LF_snow.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootMediumSnowSound)
{
   filename    = "fx/armor/med_RF_snow.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootMediumShallowSplashSound)
{
   filename    = "fx/armor/med_LF_water.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootMediumShallowSplashSound)
{
   filename    = "fx/armor/med_RF_water.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootMediumWadingSound)
{
   filename    = "fx/armor/med_LF_uw.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootMediumWadingSound)
{
   filename    = "fx/armor/med_RF_uw.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootMediumUnderwaterSound)
{
   filename    = "fx/armor/med_LF_uw.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootMediumUnderwaterSound)
{
   filename    = "fx/armor/med_RF_uw.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootMediumBubblesSound)
{
   filename    = "fx/armor/light_LF_bubbles.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootMediumBubblesSound)
{
   filename    = "fx/armor/light_RF_bubbles.wav";
   description = AudioClose3d;
   preload = true;
};
datablock AudioProfile(ImpactMediumSoftSound)
{
   filename    = "fx/armor/med_land_soft.wav";
   description = AudioClosest3d;
   preload = true;
   effect = ImpactSoftEffect;
};

datablock AudioProfile(ImpactMediumHardSound)
{
   filename    = "fx/armor/med_land_hard.wav";
   description = AudioClose3d;
   preload = true;
   effect = ImpactHardEffect;
};

datablock AudioProfile(ImpactMediumMetalSound)
{
   filename    = "fx/armor/med_land_metal.wav";
   description = AudioClose3d;
   preload = true;
   effect = ImpactMetalEffect;
};

datablock AudioProfile(ImpactMediumSnowSound)
{
   filename    = "fx/armor/med_land_snow.wav";
   description = AudioClosest3d;
   preload = true;
   effect = ImpactSnowEffect;
};

datablock AudioProfile(ImpactMediumWaterEasySound)
{
   filename    = "fx/armor/general_water_smallsplash.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ImpactMediumWaterMediumSound)
{
   filename    = "fx/armor/general_water_medsplash.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ImpactMediumWaterHardSound)
{
   filename    = "fx/armor/general_water_bigsplash.wav";
   description = AudioDefault3d;
   preload = true;
};

datablock AudioProfile(ExitingWaterMediumSound)
{
   filename    = "fx/armor/general_water_exit.wav";
   description = AudioClose3d;
   preload = true;
};

// ------Engineer Assistant Models--------
datablock ShapeBaseImageData(BEngineerL)
{
   shapeFile = "repair_patch.dts";
   mountPoint = 1;
   offset = "0.20 0.27 -0.57";
   mass = 0.1;

   alwaysAmbient = false;
};

datablock ShapeBaseImageData(BEngineerR)
{
   shapeFile = "repair_patch.dts";
   mountPoint = 1;
   offset = "-0.20 0.27 -0.57";
   mass = 0.1;

   alwaysAmbient = false;
};

datablock ShapeBaseImageData(MEngineerL)
{
   shapeFile = "repair_patch.dts";
   mountPoint = 1;
   offset = "0.28 0.28 -0.5";
   mass = 0.1;
};

datablock ShapeBaseImageData(MEngineerR)
{
   shapeFile = "repair_patch.dts";
   mountPoint = 1;
   offset = "-0.28 0.28 -0.5";
   mass = 0.1;
};

datablock ShapeBaseImageData(FEngineerL)
{
   shapeFile = "repair_patch.dts";
   mountPoint = 1;
   offset = "0.14 0.18 -0.52";
   mass = 0.1;

   alwaysAmbient = false;
};

datablock ShapeBaseImageData(FEngineerR)
{
   shapeFile = "repair_patch.dts";
   mountPoint = 1;
   offset = "-0.14 0.18 -0.52";
   mass = 0.1;

   alwaysAmbient = false;
};

//SOUNDS ----- HEAVY ARMOR--------
datablock AudioProfile(LFootHeavySoftSound)
{
   filename    = "fx/armor/heavy_LF_soft.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootHeavySoftSound)
{
   filename    = "fx/armor/heavy_RF_soft.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootHeavyHardSound)
{
   filename    = "fx/armor/heavy_LF_hard.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootHeavyHardSound)
{
   filename    = "fx/armor/heavy_RF_hard.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootHeavyMetalSound)
{
   filename    = "fx/armor/heavy_LF_metal.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootHeavyMetalSound)
{
   filename    = "fx/armor/heavy_RF_metal.wav";
   description = AudioClose3d;
   preload = true;
};
datablock AudioProfile(LFootHeavySnowSound)
{
   filename    = "fx/armor/heavy_LF_snow.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootHeavySnowSound)
{
   filename    = "fx/armor/heavy_RF_snow.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootHeavyShallowSplashSound)
{
   filename    = "fx/armor/heavy_LF_water.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootHeavyShallowSplashSound)
{
   filename    = "fx/armor/heavy_RF_water.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootHeavyWadingSound)
{
   filename    = "fx/armor/heavy_LF_uw.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootHeavyWadingSound)
{
   filename    = "fx/armor/heavy_RF_uw.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(LFootHeavyUnderwaterSound)
{
   filename    = "fx/armor/heavy_LF_uw.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(RFootHeavyUnderwaterSound)
{
   filename    = "fx/armor/heavy_RF_uw.wav";
   description = AudioClosest3d;
   preload = true;
};

datablock AudioProfile(LFootHeavyBubblesSound)
{
   filename    = "fx/armor/light_LF_bubbles.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(RFootHeavyBubblesSound)
{
   filename    = "fx/armor/light_RF_bubbles.wav";
   description = AudioClose3d;
   preload = true;
};
datablock AudioProfile(ImpactHeavySoftSound)
{
   filename    = "fx/armor/heavy_land_soft.wav";
   description = AudioClose3d;
   preload = true;
   effect = ImpactSoftEffect;
};

datablock AudioProfile(ImpactHeavyHardSound)
{
   filename    = "fx/armor/heavy_land_hard.wav";
   description = AudioClose3d;
   preload = true;
   effect = ImpactHardEffect;
};

datablock AudioProfile(ImpactHeavyMetalSound)
{
   filename    = "fx/armor/heavy_land_metal.wav";
   description = AudioClose3d;
   preload = true;
   effect = ImpactMetalEffect;
};

datablock AudioProfile(ImpactHeavySnowSound)
{
   filename    = "fx/armor/heavy_land_snow.wav";
   description = AudioClosest3d;
   preload = true;
   effect = ImpactSnowEffect;
};

datablock AudioProfile(ImpactHeavyWaterEasySound)
{
   filename    = "fx/armor/general_water_smallsplash.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ImpactHeavyWaterMediumSound)
{
   filename    = "fx/armor/general_water_medsplash.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ImpactHeavyWaterHardSound)
{
   filename    = "fx/armor/general_water_bigsplash.wav";
   description = AudioDefault3d;
   preload = true;
};

datablock AudioProfile(ExitingWaterHeavySound)
{
   filename    = "fx/armor/general_water_exit2.wav";
   description = AudioClose3d;
   preload = true;
};

//----------------------------------------------------------------------------
// Splash
//----------------------------------------------------------------------------

datablock ParticleData(PlayerSplashMist)
{
   dragCoefficient      = 2.0;
   gravityCoefficient   = -0.05;
   inheritedVelFactor   = 0.0;
   constantAcceleration = 0.0;
   lifetimeMS           = 400;
   lifetimeVarianceMS   = 100;
   useInvAlpha          = false;
   spinRandomMin        = -90.0;
   spinRandomMax        = 500.0;
   textureName          = "particleTest";
   colors[0]     = "0.7 0.8 1.0 1.0";
   colors[1]     = "0.7 0.8 1.0 0.5";
   colors[2]     = "0.7 0.8 1.0 0.0";
   sizes[0]      = 0.5;
   sizes[1]      = 0.5;
   sizes[2]      = 0.8;
   times[0]      = 0.0;
   times[1]      = 0.5;
   times[2]      = 1.0;
};

datablock ParticleEmitterData(PlayerSplashMistEmitter)
{
   ejectionPeriodMS = 5;
   periodVarianceMS = 0;
   ejectionVelocity = 3.0;
   velocityVariance = 2.0;
   ejectionOffset   = 0.0;
   thetaMin         = 85;
   thetaMax         = 85;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   lifetimeMS       = 250;
   particles = "PlayerSplashMist";
};


datablock ParticleData(PlayerBubbleParticle)
{
   dragCoefficient      = 0.0;
   gravityCoefficient   = -0.50;
   inheritedVelFactor   = 0.0;
   constantAcceleration = 0.0;
   lifetimeMS           = 400;
   lifetimeVarianceMS   = 100;
   useInvAlpha          = false;
   textureName          = "special/bubbles";
   colors[0]     = "0.7 0.8 1.0 0.4";
   colors[1]     = "0.7 0.8 1.0 0.4";
   colors[2]     = "0.7 0.8 1.0 0.0";
   sizes[0]      = 0.1;
   sizes[1]      = 0.3;
   sizes[2]      = 0.3;
   times[0]      = 0.0;
   times[1]      = 0.5;
   times[2]      = 1.0;
};

datablock ParticleEmitterData(PlayerBubbleEmitter)
{
   ejectionPeriodMS = 1;
   periodVarianceMS = 0;
   ejectionVelocity = 2.0;
   ejectionOffset   = 0.5;
   velocityVariance = 0.5;
   thetaMin         = 0;
   thetaMax         = 80;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   particles = "PlayerBubbleParticle";
};

datablock ParticleData(PlayerFoamParticle)
{
   dragCoefficient      = 2.0;
   gravityCoefficient   = -0.05;
   inheritedVelFactor   = 0.0;
   constantAcceleration = 0.0;
   lifetimeMS           = 400;
   lifetimeVarianceMS   = 100;
   useInvAlpha          = false;
   spinRandomMin        = -90.0;
   spinRandomMax        = 500.0;
   textureName          = "particleTest";
   colors[0]     = "0.7 0.8 1.0 0.20";
   colors[1]     = "0.7 0.8 1.0 0.20";
   colors[2]     = "0.7 0.8 1.0 0.00";
   sizes[0]      = 0.2;
   sizes[1]      = 0.4;
   sizes[2]      = 1.6;
   times[0]      = 0.0;
   times[1]      = 0.5;
   times[2]      = 1.0;
};

datablock ParticleEmitterData(PlayerFoamEmitter)
{
   ejectionPeriodMS = 10;
   periodVarianceMS = 0;
   ejectionVelocity = 3.0;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 85;
   thetaMax         = 85;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   particles = "PlayerFoamParticle";
};


datablock ParticleData( PlayerFoamDropletsParticle )
{
   dragCoefficient      = 1;
   gravityCoefficient   = 0.2;
   inheritedVelFactor   = 0.2;
   constantAcceleration = -0.0;
   lifetimeMS           = 600;
   lifetimeVarianceMS   = 0;
   textureName          = "special/droplet";
   colors[0]     = "0.7 0.8 1.0 1.0";
   colors[1]     = "0.7 0.8 1.0 0.5";
   colors[2]     = "0.7 0.8 1.0 0.0";
   sizes[0]      = 0.8;
   sizes[1]      = 0.3;
   sizes[2]      = 0.0;
   times[0]      = 0.0;
   times[1]      = 0.5;
   times[2]      = 1.0;
};

datablock ParticleEmitterData( PlayerFoamDropletsEmitter )
{
   ejectionPeriodMS = 7;
   periodVarianceMS = 0;
   ejectionVelocity = 2;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 60;
   thetaMax         = 80;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   orientParticles  = true;
   particles = "PlayerFoamDropletsParticle";
};



datablock ParticleData( PlayerSplashParticle )
{
   dragCoefficient      = 1;
   gravityCoefficient   = 0.2;
   inheritedVelFactor   = 0.2;
   constantAcceleration = -0.0;
   lifetimeMS           = 600;
   lifetimeVarianceMS   = 0;
   textureName          = "special/droplet";
   colors[0]     = "0.7 0.8 1.0 1.0";
   colors[1]     = "0.7 0.8 1.0 0.5";
   colors[2]     = "0.7 0.8 1.0 0.0";
   sizes[0]      = 0.5;
   sizes[1]      = 0.5;
   sizes[2]      = 0.5;
   times[0]      = 0.0;
   times[1]      = 0.5;
   times[2]      = 1.0;
};

datablock ParticleEmitterData( PlayerSplashEmitter )
{
   ejectionPeriodMS = 1;
   periodVarianceMS = 0;
   ejectionVelocity = 3;
   velocityVariance = 1.0;
   ejectionOffset   = 0.0;
   thetaMin         = 60;
   thetaMax         = 80;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   orientParticles  = true;
   lifetimeMS       = 100;
   particles = "PlayerSplashParticle";
};

datablock SplashData(PlayerSplash)
{
   numSegments = 15;
   ejectionFreq = 15;
   ejectionAngle = 40;
   ringLifetime = 0.5;
   lifetimeMS = 300;
   velocity = 4.0;
   startRadius = 0.0;
   acceleration = -3.0;
   texWrap = 5.0;

   texture = "special/water2";

   emitter[0] = PlayerSplashEmitter;
   emitter[1] = PlayerSplashMistEmitter;

   colors[0] = "0.7 0.8 1.0 0.0";
   colors[1] = "0.7 0.8 1.0 0.3";
   colors[2] = "0.7 0.8 1.0 0.7";
   colors[3] = "0.7 0.8 1.0 0.0";
   times[0] = 0.0;
   times[1] = 0.4;
   times[2] = 0.8;
   times[3] = 1.0;
};

//----------------------------------------------------------------------------
// Jet data
//----------------------------------------------------------------------------
datablock ParticleData(HumanArmorJetParticle)
{
   dragCoefficient      = 0.0;
   gravityCoefficient   = 0;
   inheritedVelFactor   = 0.2;
   constantAcceleration = 0.0;
   lifetimeMS           = 50;
   lifetimeVarianceMS   = 0;
   textureName          = "particleTest";
   colors[0]     = "0.32 0.47 0.47 1.0";
   colors[1]     = "0.32 0.47 0.47 0";
   sizes[0]      = 0.40;
   sizes[1]      = 0.15;
};

datablock ParticleEmitterData(HumanArmorJetEmitter)
{
   ejectionPeriodMS = 3;
   periodVarianceMS = 0;
   ejectionVelocity = 3;
   velocityVariance = 2.9;
   ejectionOffset   = 0.0;
   thetaMin         = 0;
   thetaMax         = 5;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   particles = "HumanArmorJetParticle";
};

datablock JetEffectData(HumanArmorJetEffect)
{
   texture        = "special/jetExhaust02";
   coolColor      = "0.0 0.0 1.0 1.0";
   hotColor       = "0.2 0.4 0.7 1.0";
   activateTime   = 0.2;
   deactivateTime = 0.05;
   length         = 0.75;
   width          = 0.2;
   speed          = -15;
   stretch        = 2.0;
   yOffset        = 0.2;
};

datablock JetEffectData(HumanMediumArmorJetEffect)
{
   texture        = "special/jetExhaust02";
   coolColor      = "0.0 0.0 1.0 1.0";
   hotColor       = "0.2 0.4 0.7 1.0";
   activateTime   = 0.2;
   deactivateTime = 0.05;
   length         = 0.75;
   width          = 0.2;
   speed          = -15;
   stretch        = 2.0;
   yOffset        = 0.4;
};

datablock JetEffectData(HumanLightFemaleArmorJetEffect)
{
   texture        = "special/jetExhaust02";
   coolColor      = "0.0 0.0 1.0 1.0";
   hotColor       = "0.2 0.4 0.7 1.0";
   activateTime   = 0.2;
   deactivateTime = 0.05;
   length         = 0.75;
   width          = 0.2;
   speed          = -15;
   stretch        = 2.0;
   yOffset        = 0.2;
};

datablock JetEffectData(BiodermArmorJetEffect)
{
   texture        = "special/jetExhaust02";
   coolColor      = "0.0 0.0 1.0 1.0";
   hotColor       = "0.8 0.6 0.2 1.0";
   activateTime   = 0.2;
   deactivateTime = 0.05;
   length         = 0.75;
   width          = 0.2;
   speed          = -15;
   stretch        = 2.0;
   yOffset        = 0.0;
};

//----------------------------------------------------------------------------
// Foot puffs
//----------------------------------------------------------------------------
datablock ParticleData(LightPuff)
{
   dragCoefficient      = 2.0;
   gravityCoefficient   = -0.01;
   inheritedVelFactor   = 0.0;
   constantAcceleration = 0.0;
   lifetimeMS           = 500;
   lifetimeVarianceMS   = 100;
   useInvAlpha          = true;
   spinRandomMin        = -35.0;
   spinRandomMax        = 35.0;
   textureName          = "particleTest";
   colors[0]     = "0.46 0.36 0.26 0.4";
   colors[1]     = "0.46 0.46 0.36 0.0";
   sizes[0]      = 0.4;
   sizes[1]      = 1.0;
};

datablock ParticleEmitterData(LightPuffEmitter)
{
   ejectionPeriodMS = 35;
   periodVarianceMS = 10;
   ejectionVelocity = 0.1;
   velocityVariance = 0.05;
   ejectionOffset   = 0.0;
   thetaMin         = 5;
   thetaMax         = 20;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   useEmitterColors = true;
   particles = "LightPuff";
};

//----------------------------------------------------------------------------
// Liftoff dust
//----------------------------------------------------------------------------
datablock ParticleData(LiftoffDust)
{
   dragCoefficient      = 1.0;
   gravityCoefficient   = -0.01;
   inheritedVelFactor   = 0.0;
   constantAcceleration = 0.0;
   lifetimeMS           = 1000;
   lifetimeVarianceMS   = 100;
   useInvAlpha          = true;
   spinRandomMin        = -90.0;
   spinRandomMax        = 500.0;
   textureName          = "particleTest";
   colors[0]     = "0.46 0.36 0.26 0.0";
   colors[1]     = "0.46 0.46 0.36 0.4";
   colors[2]     = "0.46 0.46 0.36 0.0";
   sizes[0]      = 0.2;
   sizes[1]      = 0.6;
   sizes[2]      = 1.0;
   times[0]      = 0.0;
   times[1]      = 0.5;
   times[2]      = 1.0;
};

datablock ParticleEmitterData(LiftoffDustEmitter)
{
   ejectionPeriodMS = 5;
   periodVarianceMS = 0;
   ejectionVelocity = 2.0;
   velocityVariance = 0.0;
   ejectionOffset   = 0.0;
   thetaMin         = 90;
   thetaMax         = 90;
   phiReferenceVel  = 0;
   phiVariance      = 360;
   overrideAdvances = false;
   useEmitterColors = true;
   particles = "LiftoffDust";
};

//----------------------------------------------------------------------------

datablock ParticleData(BiodermArmorJetParticle) : HumanArmorJetParticle
{
   colors[0]     = "0.50 0.48 0.36 1.0";
   colors[1]     = "0.50 0.48 0.36 0";
};

datablock ParticleEmitterData(BiodermArmorJetEmitter) : HumanArmorJetEmitter
{
   particles = "BiodermArmorJetParticle";
};


//----------------------------------------------------------------------------
datablock DecalData(LightMaleFootprint)
{
   sizeX       = 0.125;
   sizeY       = 0.25;
   textureName = "special/footprints/L_male";
};

datablock DebrisData( PlayerDebris )
{
   explodeOnMaxBounce = false;

   elasticity = 0.35;
   friction = 0.5;

   lifetime = 4.0;
   lifetimeVariance = 0.0;

   minSpinSpeed = 60;
   maxSpinSpeed = 600;

   numBounces = 5;
   bounceVariance = 0;

   staticOnMaxBounce = true;
   gravModifier = 1.0;

   useRadiusMass = true;
   baseRadius = 1;

   velocity = 18.0;
   velocityVariance = 12.0;
};             

datablock PlayerData(LightMaleHumanArmor) : LightPlayerDamageProfile
{
   emap = true;
   
   className = Armor;
   shapeFile = "light_male.dts";
   cameraMaxDist = 3;
   computeCRC = true;
  
   canObserve = true;
   cmdCategory = "Clients";
   cmdIcon = CMDPlayerIcon;
   cmdMiniIconName = "commander/MiniIcons/com_player_grey";

   hudImageNameFriendly[0] = "gui/hud_playertriangle.png";
   hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy.png";
   hudRenderModulated[0] = true;

   hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey";
   hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey";
   hudRenderModulated[1] = true;
   hudRenderAlways[1] = true;
   hudRenderCenter[1] = true;
   hudRenderDistance[1] = true;

   hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey";
   hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey";
   hudRenderModulated[2] = true;
   hudRenderAlways[2] = true;
   hudRenderCenter[2] = true;
   hudRenderDistance[2] = true;

   cameraDefaultFov = 90.0;
   cameraMinFov = 5.0;
   cameraMaxFov = 120.0;
   
   debrisShapeName = "debris_player.dts";
   debris = playerDebris;

   aiAvoidThis = true;

   minLookAngle = -1.4;
   maxLookAngle = 1.4;
   maxFreelookAngle = 3.0;

   mass = 48;
   drag = 0.3;
   maxdrag = 0.4;
   density = 10;
   maxDamage = 0.66;
   maxEnergy =  50;
   repairRate = 0.0033;
   energyPerDamagePoint = 70.0; // shield energy required to block one point of damage

   rechargeRate = 0.256;
   jetForce = 2200;
   underwaterJetForce = 5100;
   underwaterVertJetFactor = 1.5;
   jetEnergyDrain =  0.9;
   underwaterJetEnergyDrain = 0.5;
   minJetEnergy = 1;
   maxJetHorizontalPercentage = 0.98;

   runForce = 5200;
   runEnergyDrain = 0;
   minRunEnergy = 0;
   maxForwardSpeed = 16.5;
   maxBackwardSpeed = 14;
   maxSideSpeed = 14;

   maxUnderwaterForwardSpeed = 8.4;
   maxUnderwaterBackwardSpeed = 7.8;
   maxUnderwaterSideSpeed = 7.8;

   jumpForce = 800;
   jumpEnergyDrain = 0;
   minJumpEnergy = 0;
   jumpDelay = 0;

   recoverDelay = 9;
   recoverRunForceScale = 1.2;

   minImpactSpeed = 45;
   speedDamageScale = 0.004;

   jetSound = ArmorJetSound;
   wetJetSound = ArmorJetSound;
   jetEmitter = HumanArmorJetEmitter;
   jetEffect = HumanArmorJetEffect;
   
   boundingBox = "1.2 1.2 2.3";
   pickupRadius = 0.75;
   
   // damage location details
   boxNormalHeadPercentage       = 0.83;
   boxNormalTorsoPercentage      = 0.49;
   boxHeadLeftPercentage         = 0;
   boxHeadRightPercentage        = 1;
   boxHeadBackPercentage         = 0;
   boxHeadFrontPercentage        = 1;

   //Foot Prints
   decalData   = LightMaleFootprint;
   decalOffset = 0.25;
   
   footPuffEmitter = LightPuffEmitter;
   footPuffNumParts = 15;
   footPuffRadius = 0.25;

   dustEmitter = LiftoffDustEmitter;

   splash = PlayerSplash;
   splashVelocity = 4.0;
   splashAngle = 67.0;
   splashFreqMod = 300.0;
   splashVelEpsilon = 0.60;
   bubbleEmitTime = 0.4;
   splashEmitter[0] = PlayerFoamDropletsEmitter;
   splashEmitter[1] = PlayerFoamEmitter;
   splashEmitter[2] = PlayerBubbleEmitter;
   mediumSplashSoundVelocity = 10.0;   
   hardSplashSoundVelocity = 20.0;   
   exitSplashSoundVelocity = 5.0;

   // Controls over slope of runnable/jumpable surfaces
   runSurfaceAngle  = 70;
   jumpSurfaceAngle = 80;

   minJumpSpeed = 20;
   maxJumpSpeed = 30;

   horizMaxSpeed = 68;
   horizResistSpeed = 33;
   horizResistFactor = 0.35;
   maxJetForwardSpeed = 30;

   upMaxSpeed = 80;
   upResistSpeed = 25;
   upResistFactor = 0.3;
   
   // heat inc'ers and dec'ers
   heatDecayPerSec      = 1/3; // takes 3 seconds to clear heat sig.
   heatIncreasePerSec   = 1/2; // takes 2 seconds of constant jet to get full heat sig.

   footstepSplashHeight = 0.35;

   //Footstep Sounds
   LFootSoftSound       = LFootLightSoftSound;
   RFootSoftSound       = RFootLightSoftSound;
   LFootHardSound       = LFootLightHardSound;
   RFootHardSound       = RFootLightHardSound;
   LFootMetalSound      = LFootLightMetalSound;
   RFootMetalSound      = RFootLightMetalSound;
   LFootSnowSound       = LFootLightSnowSound;
   RFootSnowSound       = RFootLightSnowSound;
   LFootShallowSound    = LFootLightShallowSplashSound;
   RFootShallowSound    = RFootLightShallowSplashSound;
   LFootWadingSound     = LFootLightWadingSound;
   RFootWadingSound     = RFootLightWadingSound;
   LFootUnderwaterSound = LFootLightUnderwaterSound;
   RFootUnderwaterSound = RFootLightUnderwaterSound;
   LFootBubblesSound    = LFootLightBubblesSound;
   RFootBubblesSound    = RFootLightBubblesSound;
   movingBubblesSound   = ArmorMoveBubblesSound;
   waterBreathSound     = WaterBreathMaleSound;

   impactSoftSound      = ImpactLightSoftSound;
   impactHardSound      = ImpactLightHardSound;
   impactMetalSound     = ImpactLightMetalSound;
   impactSnowSound      = ImpactLightSnowSound;
   
   skiSoftSound         = SkiAllSoftSound;
   skiHardSound         = SkiAllHardSound;
   skiMetalSound        = SkiAllMetalSound;
   skiSnowSound         = SkiAllSnowSound;

   impactWaterEasy      = ImpactLightWaterEasySound;
   impactWaterMedium    = ImpactLightWaterMediumSound;
   impactWaterHard      = ImpactLightWaterHardSound;
   
   groundImpactMinSpeed    = 10.0;
   groundImpactShakeFreq   = "4.0 4.0 4.0";
   groundImpactShakeAmp    = "1.0 1.0 1.0";
   groundImpactShakeDuration = 0.8;
   groundImpactShakeFalloff = 10.0;
   
   exitingWater         = ExitingWaterLightSound;
   
   maxWeapons = 3;           // Max number of different weapons the player can have
   maxGrenades = 1;          // Max number of different grenades the player can have
   maxMines = 1;             // Max number of different mines the player can have
   
   // Inventory restrictions
   max[RepairKit]          = 1;

   // Weapons and Ammo
   max[Blaster]            = 1;
   max[Plasma]             = 1;
   max[PlasmaAmmo]         = 24;
   max[Disc]               = 1;
   max[DiscAmmo]           = 15;
   max[SniperRifle]        = 1;
   max[Rifle]              = 1;
   max[RifleAmmo]          = 16;
   max[GrenadeLauncher]    = 1;
   max[GrenadeLauncherAmmo]= 12;
   max[Chaingun]           = 1;
   max[ChaingunAmmo]       = 150;
   max[TargetingLaser]     = 1;
   max[FlashLight]         = 1;
   max[ELFGun]             = 1;
   max[ShockLance]         = 1;
   max[Shotgun]            = 1;
   max[ShotgunAmmo]        = 24;
   max[Magnum]             = 1;
   max[MagnumAmmo]         = 18;

   // Specials
   max[Adren]             = 1;
   max[Beacon]             = 3;
   max[CodeBreaker]        = 1;
   max[GrapplingHook]      = 1;
   max[Hologram]           = 1;
   max[InertialDampner]    = 1;
   max[LightShield]        = 1;
   max[SpeedBooster]       = 1;
   max[TargetingBeacon]    = 1;
   max[WCS]                = 1;

   // Packs
   max[TAG]                = 1;
   max[TAGGun]             = 1;
   max[RepairGun]          = 1;
   max[CloakingPack]       = 1;
   max[SensorJammerPack]   = 1;
   max[EnergyPack]         = 1;
   max[RepairPack]         = 1;
   max[ShieldPack]         = 1;
   max[AmmoPack]           = 1;
   max[SatchelCharge]      = 1;
   max[JetPack]            = 1;

   // Deployables
   max[MotionSensorDeployable]     = 1;
   max[PulseSensorDeployable]      = 1;
   max[DeployableSensorJammerPack] = 1;
   max[SensorTapPack]              = 1;

   // Grenades
   max[Grenade]            = 3;
   max[EMPGrenade]         = 2;
   max[IncendiaryGrenade]  = 2;
   max[PlasticExplosive]   = 2;
   max[FlashGrenade]       = 2;
   max[ConcussionGrenade]  = 3;
   max[FlareGrenade]       = 3;
   max[CameraGrenade]      = 2;
   max[ECMGrenade]         = 2;

   // Mines
   max[Mine]               = 3;
   max[EMPMine]            = 3;
   max[IncendiaryMine]     = 3;
   max[StunMine]           = 3;
   max[ConcussionMine]     = 3;

   observeParameters = "0.5 4.5 4.5";

   shieldEffectScale = "0.7 0.7 1.0";

};


//----------------------------------------------------------------------------

datablock DecalData(MediumMaleFootprint)
{
   sizeX       = 0.125;
   sizeY       = 0.25;
   textureName = "special/footprints/M_male";
};

datablock PlayerData(MediumMaleHumanArmor) : MediumPlayerDamageProfile
{
   emap = true;
   
   className = Armor;
   shapeFile = "medium_male.dts";
   cameraMaxDist = 3;
   computeCRC = true;
   
   debrisShapeName = "debris_player.dts";
   debris = playerDebris;

   canObserve = true;
   cmdCategory = "Clients";
   cmdIcon = CMDPlayerIcon;
   cmdMiniIconName = "commander/MiniIcons/com_player_grey";

   hudImageNameFriendly[0] = "gui/hud_playertriangle.png";
   hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy.png";
   hudRenderModulated[0] = true;

   hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey";
   hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey";
   hudRenderModulated[1] = true;
   hudRenderAlways[1] = true;
   hudRenderCenter[1] = true;
   hudRenderDistance[1] = true;

   hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey";
   hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey";
   hudRenderModulated[2] = true;
   hudRenderAlways[2] = true;
   hudRenderCenter[2] = true;
   hudRenderDistance[2] = true;

   aiAvoidThis = true;

   minLookAngle = -1.4;
   maxLookAngle = 1.4;
   maxFreelookAngle = 3.0;

   mass = 70;
   drag = 0.4;
   maxdrag = 0.5;
   density = 10;
   maxDamage = 1.1;
   maxEnergy =  65;
   repairRate = 0.0033;
   energyPerDamagePoint = 70; // shield energy required to block one point of damage

   rechargeRate = 0.27;
   jetForce = 3000;
   underwaterJetForce = 7000;
   underwaterVertJetFactor = 1.5;
   jetEnergyDrain =  1.4;
   underwaterJetEnergyDrain =  0.5;
   minJetEnergy = 1;
   maxJetHorizontalPercentage = 0.95;

   runForce = 5200;
   runEnergyDrain = 0;
   minRunEnergy = 0;
   maxForwardSpeed = 12;
   maxBackwardSpeed = 11;
   maxSideSpeed = 11;

   maxUnderwaterForwardSpeed = 6.6;
   maxUnderwaterBackwardSpeed = 6;
   maxUnderwaterSideSpeed = 6;

   recoverDelay = 9;
   recoverRunForceScale = 1.2;
   
   // heat inc'ers and dec'ers
   heatDecayPerSec      = 1/3; // takes 3 seconds to clear heat sig.
   heatIncreasePerSec   = 1/2; // takes 2 seconds of constant jet to get full heat sig.

   jumpForce = 1100;
   jumpEnergyDrain = 0;
   minJumpEnergy = 0;
   jumpSurfaceAngle = 75;
   jumpDelay = 0;

   // Controls over slope of runnable/jumpable surfaces
   runSurfaceAngle  = 70;
   jumpSurfaceAngle = 80;

   minJumpSpeed = 15;
   maxJumpSpeed = 25;

   horizMaxSpeed = 60;
   horizResistSpeed = 28;
   horizResistFactor = 0.32;
   maxJetForwardSpeed = 22;

   upMaxSpeed = 200;
   upResistSpeed = 35;
   upResistFactor = 0.15;

   minImpactSpeed = 60;
   speedDamageScale = 0.003;

   jetSound = ArmorJetSound;
   wetJetSound = ArmorWetJetSound;

   jetEmitter = HumanArmorJetEmitter;
   jetEffect = HumanMediumArmorJetEffect;

   boundingBox = "1.45 1.45 2.4";
   pickupRadius = 0.75;
   
   // damage location details
   boxNormalHeadPercentage       = 0.83;
   boxNormalTorsoPercentage      = 0.49;
   boxHeadLeftPercentage         = 0;
   boxHeadRightPercentage        = 1;
   boxHeadBackPercentage         = 0;
   boxHeadFrontPercentage        = 1;
   
   //Foot Prints
   decalData   = MediumMaleFootprint;
   decalOffset = 0.35;

   footPuffEmitter = LightPuffEmitter;
   footPuffNumParts = 15;
   footPuffRadius = 0.25;
   
   dustEmitter = LiftoffDustEmitter;

   splash = PlayerSplash;
   splashVelocity = 4.0;
   splashAngle = 67.0;
   splashFreqMod = 300.0;
   splashVelEpsilon = 0.60;
   bubbleEmitTime = 0.4;
   splashEmitter[0] = PlayerFoamDropletsEmitter;
   splashEmitter[1] = PlayerFoamEmitter;
   splashEmitter[2] = PlayerBubbleEmitter;
   mediumSplashSoundVelocity = 10.0;   
   hardSplashSoundVelocity = 20.0;   
   exitSplashSoundVelocity = 5.0;

   footstepSplashHeight = 0.35;
   //Footstep Sounds
   LFootSoftSound       = LFootMediumSoftSound;
   RFootSoftSound       = RFootMediumSoftSound;
   LFootHardSound       = LFootMediumHardSound;
   RFootHardSound       = RFootMediumHardSound;
   LFootMetalSound      = LFootMediumMetalSound;
   RFootMetalSound      = RFootMediumMetalSound;
   LFootSnowSound       = LFootMediumSnowSound;
   RFootSnowSound       = RFootMediumSnowSound;
   LFootShallowSound    = LFootMediumShallowSplashSound;
   RFootShallowSound    = RFootMediumShallowSplashSound;
   LFootWadingSound     = LFootMediumWadingSound;
   RFootWadingSound     = RFootMediumWadingSound;
   LFootUnderwaterSound = LFootMediumUnderwaterSound;
   RFootUnderwaterSound = RFootMediumUnderwaterSound;
   LFootBubblesSound    = LFootMediumBubblesSound;
   RFootBubblesSound    = RFootMediumBubblesSound;
   movingBubblesSound   = ArmorMoveBubblesSound;
   waterBreathSound     = WaterBreathMaleSound;
   
   impactSoftSound      = ImpactMediumSoftSound;
   impactHardSound      = ImpactMediumHardSound;
   impactMetalSound     = ImpactMediumMetalSound;
   impactSnowSound      = ImpactMediumSnowSound;
   
   skiSoftSound         = SkiAllSoftSound;
   skiHardSound         = SkiAllHardSound;
   skiMetalSound        = SkiAllMetalSound;
   skiSnowSound         = SkiAllSnowSound;

   impactWaterEasy      = ImpactMediumWaterEasySound;
   impactWaterMedium    = ImpactMediumWaterMediumSound;
   impactWaterHard      = ImpactMediumWaterHardSound;
   
   groundImpactMinSpeed    = 10.0;
   groundImpactShakeFreq   = "4.0 4.0 4.0";
   groundImpactShakeAmp    = "1.0 1.0 1.0";
   groundImpactShakeDuration = 0.8;
   groundImpactShakeFalloff = 10.0;

   exitingWater               = ExitingWaterMediumSound;

   maxWeapons = 4;            // Max number of different weapons the player can have
   maxGrenades = 1;           // Max number of different grenades the player can have
   maxMines = 1;              // Max number of different mines the player can have

   // Inventory restrictions
   max[RepairKit]          = 1;

   // Weapons and Ammo
   max[Blaster]            = 1;
   max[Plasma]             = 1;
   max[PlasmaAmmo]         = 36;
   max[Disc]               = 1;
   max[DiscAmmo]           = 20;
   max[SniperRifle]        = 0;
   max[GrenadeLauncher]    = 1;
   max[GrenadeLauncherAmmo]= 18;
   max[Mortar]             = 1;
   max[MortarAmmo]         = 4;
   max[MissileLauncher]    = 1;
   max[MissileLauncherAmmo]= 4;
   max[ParticleCannon]     = 1;
   max[Chaingun]           = 1;
   max[ChaingunAmmo]       = 250;
   max[TargetingLaser]     = 1;
   max[FlashLight]         = 1;
   max[ELFGun]             = 1;
   max[ShockLance]         = 1;
   max[Shotgun]            = 1;
   max[ShotgunAmmo]        = 48;
   max[Magnum]             = 1;
   max[MagnumAmmo]         = 30;

   // Specials
   max[Beacon]           = 3;
   max[CodeBreaker]      = 1;
   max[GrapplingHook]    = 1;
   max[Hologram]         = 1;
   max[InertialDampner]  = 1;
   max[LightShield]      = 1;
   max[SpeedBooster]     = 1;
   max[TargetingBeacon]  = 1;
   max[WCS]              = 1;

   // Packs
   max[RepairGun]          = 1;
   max[CloakingPack]       = 0;
   max[SensorJammerPack]   = 1;
   max[EnergyPack]         = 1;
   max[RepairPack]         = 1;
   max[ShieldPack]         = 1;
   max[AmmoPack]           = 1;
   max[SatchelCharge]      = 1;
   max[TAG]                = 1;
   max[TAGGun]             = 1;
   max[JetPack]            = 1;
   max[SpringboardPack]    = 1;

   // Deployables
   max[VehicleMine]                = 1;
   max[DeployableSensorJammerPack] = 1;
   max[InventoryDeployable]        = 1;
   max[MotionSensorDeployable]     = 1;
   max[PulseSensorDeployable]      = 1;
   max[SensorTapPack]              = 1;

   // Grenades
   max[Grenade]           = 5;
   max[CameraGrenade]     = 2;
   max[EMPGrenade]        = 3;
   max[IncendiaryGrenade] = 3;
   max[PlasticExplosive]  = 3;
   max[FlashGrenade]      = 3;
   max[ConcussionGrenade] = 3;
   max[FlareGrenade]      = 6;
   max[ECMGrenade]        = 3;

   // Mines
   max[Mine]               = 4;
   max[EMPMine]            = 4;
   max[IncendiaryMine]     = 4;
   max[StunMine]           = 4;
   max[ConcussionMine]     = 4;

   observeParameters = "0.5 4.5 4.5";

   shieldEffectScale = "0.7 0.7 1.0";
};

datablock PlayerData(EngineerMaleHumanArmor) : MediumMaleHumanArmor
{
   mass = 81;
   drag = 0.4;
   maxdrag = 0.5;
   density = 10;
   maxDamage = 0.95;
   maxEnergy =  75;
   repairRate = 0.0033;
   energyPerDamagePoint = 70.0; // shield energy required to block one point of damage

   rechargeRate = 0.28;
   jetForce = 3200;
   underwaterJetForce = 8000;
   underwaterVertJetFactor = 1.5;
   jetEnergyDrain =  1.0;
   underwaterJetEnergyDrain =  0.5;
   minJetEnergy = 1;
   maxJetHorizontalPercentage = 0.9;

   runForce = 5800;
   runEnergyDrain = 0;
   minRunEnergy = 0;
   maxForwardSpeed = 9;
   maxBackwardSpeed = 8;
   maxSideSpeed = 8;

   maxUnderwaterForwardSpeed = 6.6;
   maxUnderwaterBackwardSpeed = 6;
   maxUnderwaterSideSpeed = 6;

   jumpForce = 1015;
   jumpEnergyDrain = 0;
   minJumpEnergy = 0;
   jumpSurfaceAngle = 75;
   jumpDelay = 0;

   minJumpSpeed = 15;
   maxJumpSpeed = 25;
   maxJetForwardSpeed = 22;

   horizMaxSpeed = 60;
   horizResistSpeed = 28;
   horizResistFactor = 0.2;

   upMaxSpeed = 200;
   upResistSpeed = 35;
   upResistFactor = 0.15;

   minImpactSpeed = 70;
   speedDamageScale = 0.0025;
   
   maxWeapons = 2;          // Max number of different weapons the player can have
   maxGrenades = 1;         // Max number of different grenades the player can have
   maxMines = 1;            // Max number of different mines the player can have

   // Inventory restrictions
   max[RepairKit]          = 1;

   // Weapons and Ammo
   max[Blaster]            = 1;
   max[Plasma]             = 1;
   max[PlasmaAmmo]         = 24;
   max[Disc]               = 1;
   max[DiscAmmo]           = 12;
   max[SniperRifle]        = 0;
   max[GrenadeLauncher]    = 0;
   max[GrenadeLauncherAmmo]= 0;
   max[Mortar]             = 0;
   max[MortarAmmo]         = 0;
   max[ParticleCannon]     = 0;
   max[MissileLauncher]    = 1;
   max[MissileLauncherAmmo]= 4;
   max[Chaingun]           = 1;
   max[ChaingunAmmo]       = 100;
   max[TargetingLaser]     = 1;
   max[FlashLight]         = 1;
   max[ELFGun]             = 1;
   max[ShockLance]         = 1;
   max[Shotgun]            = 1;
   max[ShotgunAmmo]        = 36;
   max[Magnum]             = 1;
   max[MagnumAmmo]         = 24;

   // Specials
   max[Beacon]          = "";
   max[CodeBreaker]     = "";
   max[GrapplingHook]   = "";
   max[InertialDampner] = "";
   max[LightShield]     = "";
   max[SpeedBooster]    = "";
   max[TargetingBeacon] = "";
   max[Hologram]        = "";
   max[WCS]             = "";
   max[EngAssistant]    = 1;

   // Packs
   max[TAG]                = 0;
   max[TAGGun]             = 0;
   max[VehicleMine]        = 1;
   max[JetPack]            = 0;
   max[CloakingPack]       = 0;
   max[SensorJammerPack]   = 0;
   max[EnergyPack]         = 0;
   max[RepairGun]          = 1;
   max[RepairPack]         = 0;
   max[ShieldPack]         = 0;
   max[AmmoPack]           = 0;
   max[SatchelCharge]      = 0;

   // Deployables
   max[DeployableSensorJammerPack] = 1;
   max[ForceFieldDeployable]       = 1;
   max[TeleporterPack]             = 1;
   max[BaseAlarmPack]              = 1;
   max[RepairDronePack]            = 1;
   max[MortarBarrelPack]           = 1;
   max[MissileBarrelPack]          = 1;
   max[AABarrelPack]               = 1;
   max[PlasmaBarrelPack]           = 1;
   max[ELFBarrelPack]              = 1;
   max[DepthChargeBarrelPack]      = 1;
   max[InventoryDeployable]        = 1;
   max[MotionSensorDeployable]     = 1;
   max[PulseSensorDeployable]      = 1;
   max[TurretOutdoorDeployable]    = 1;
   max[TurretIndoorDeployable]     = 1;
   max[DeployGenItem]              = 1;
   max[BlastWallPack]              = 1;
   max[DeployableTurretBase]       = 1;
   max[JetPack]                    = 0;

   // Mines
   max[Mine]               = 5;
   max[EMPMine]            = 5;
   max[IncendiaryMine]     = 5;
   max[StunMine]           = 5;
   max[ConcussionMine]     = 5;

   // Grenades
   max[ConcussionGrenade] = 4;
   max[CameraGrenade]     = 3;
   max[EMPGrenade]        = 4;
   max[IncendiaryGrenade] = 4;
   max[FlashGrenade]      = 4;
   max[FlareGrenade]      = 6;
   max[PlasticExplosive]  = "";  
   max[ECMGrenade]        = 4;

   observeParameters = "0.5 4.5 4.5";

   shieldEffectScale = "0.7 0.7 1.0";
};


//----------------------------------------------------------------------------
datablock DecalData(HeavyMaleFootprint)
{
   sizeX       = 0.25;
   sizeY       = 0.5;
   textureName = "special/footprints/H_male";
};

datablock PlayerData(HeavyMaleHumanArmor) : HeavyPlayerDamageProfile
{
   emap = true;

   className = Armor;
   shapeFile = "heavy_male.dts";
   cameraMaxDist = 3;
   computeCRC = true;

   debrisShapeName = "debris_player.dts";
   debris = playerDebris;

   canObserve = true;
   cmdCategory = "Clients";
   cmdIcon = CMDPlayerIcon;
   cmdMiniIconName = "commander/MiniIcons/com_player_grey";

   hudImageNameFriendly[0] = "gui/hud_playertriangle.png";
   hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy.png";
   hudRenderModulated[0] = true;

   hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey";
   hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey";
   hudRenderModulated[1] = true;
   hudRenderAlways[1] = true;
   hudRenderCenter[1] = true;
   hudRenderDistance[1] = true;

   hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey";
   hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey";
   hudRenderModulated[2] = true;
   hudRenderAlways[2] = true;
   hudRenderCenter[2] = true;
   hudRenderDistance[2] = true;

   aiAvoidThis = true;

   minLookAngle = -1.4;
   maxLookAngle = 1.4;
   maxFreelookAngle = 3.0;

   mass = 104;
   drag = 0.5;
   maxdrag = 0.6;
   density = 10;
   maxDamage = 1.35;
   maxEnergy =  85;
   repairRate = 0.0033;
   energyPerDamagePoint = 75.0; // shield energy required to block one point of damage

   rechargeRate = 0.3;
   jetForce = 4000;
   underwaterJetForce = 9600;
   underwaterVertJetFactor = 1.5;
   jetEnergyDrain =  1.65;
   underwaterJetEnergyDrain =  0.55;
   minJetEnergy = 1;
   maxJetHorizontalPercentage = 0.95;

   runForce = 7250;
   runEnergyDrain = 0;
   minRunEnergy = 0;
   maxForwardSpeed = 7.5;
   maxBackwardSpeed = 6;
   maxSideSpeed = 6;

   maxUnderwaterForwardSpeed = 3.9;
   maxUnderwaterBackwardSpeed = 3;
   maxUnderwaterSideSpeed = 3;

   recoverDelay = 9;
   recoverRunForceScale = 1.2;

   jumpForce = 1500;
   jumpEnergyDrain = 0;
   minJumpEnergy = 0;
   jumpDelay = 0;
   
   // heat inc'ers and dec'ers
   heatDecayPerSec      = 1/3; // takes 3 seconds to clear heat sig.
   heatIncreasePerSec   = 1/2; // takes 2 seconds of constant jet to get full heat sig.

   // Controls over slope of runnable/jumpable surfaces
   runSurfaceAngle  = 70;
   jumpSurfaceAngle = 75;

   minJumpSpeed = 20;
   maxJumpSpeed = 30;

   horizMaxSpeed = 52;
   horizResistSpeed = 20;
   horizResistFactor = 0.3;
   maxJetForwardSpeed = 16;

   upMaxSpeed = 200;
   upResistSpeed = 35;
   upResistFactor = 0.12;

   minImpactSpeed = 70;
   speedDamageScale = 0.004;

   jetSound = ArmorJetSound;
   wetJetSound = ArmorJetSound;
   jetEmitter = HumanArmorJetEmitter;

   boundingBox = "1.63 1.63 2.6";
   pickupRadius = 0.75;
   
   // damage location details
   boxNormalHeadPercentage       = 0.83;
   boxNormalTorsoPercentage      = 0.49;
   boxHeadLeftPercentage         = 0;
   boxHeadRightPercentage        = 1;
   boxHeadBackPercentage         = 0;
   boxHeadFrontPercentage        = 1;

   //Foot Prints
   decalData   = HeavyMaleFootprint;
   decalOffset = 0.4;

   footPuffEmitter = LightPuffEmitter;
   footPuffNumParts = 15;
   footPuffRadius = 0.25;

   dustEmitter = LiftoffDustEmitter;

   splash = PlayerSplash;
   splashVelocity = 4.0;
   splashAngle = 67.0;
   splashFreqMod = 300.0;
   splashVelEpsilon = 0.60;
   bubbleEmitTime = 0.4;
   splashEmitter[0] = PlayerFoamDropletsEmitter;
   splashEmitter[1] = PlayerFoamEmitter;
   splashEmitter[2] = PlayerBubbleEmitter;
   mediumSplashSoundVelocity = 10.0;   
   hardSplashSoundVelocity = 20.0;   
   exitSplashSoundVelocity = 5.0;

   footstepSplashHeight = 0.35;
   //Footstep Sounds
   LFootSoftSound       = LFootHeavySoftSound;
   RFootSoftSound       = RFootHeavySoftSound;
   LFootHardSound       = LFootHeavyHardSound;
   RFootHardSound       = RFootHeavyHardSound;
   LFootMetalSound      = LFootHeavyMetalSound;
   RFootMetalSound      = RFootHeavyMetalSound;
   LFootSnowSound       = LFootHeavySnowSound;
   RFootSnowSound       = RFootHeavySnowSound;
   LFootShallowSound    = LFootHeavyShallowSplashSound;
   RFootShallowSound    = RFootHeavyShallowSplashSound;
   LFootWadingSound     = LFootHeavyWadingSound;
   RFootWadingSound     = RFootHeavyWadingSound;
   LFootUnderwaterSound = LFootHeavyUnderwaterSound;
   RFootUnderwaterSound = RFootHeavyUnderwaterSound;
   LFootBubblesSound    = LFootHeavyBubblesSound;
   RFootBubblesSound    = RFootHeavyBubblesSound;
   movingBubblesSound   = ArmorMoveBubblesSound;
   waterBreathSound     = WaterBreathMaleSound;

   impactSoftSound      = ImpactHeavySoftSound;
   impactHardSound      = ImpactHeavyHardSound;
   impactMetalSound     = ImpactHeavyMetalSound;
   impactSnowSound      = ImpactHeavySnowSound;
   
   skiSoftSound         = SkiAllSoftSound;
   skiHardSound         = SkiAllHardSound;
   skiMetalSound        = SkiAllMetalSound;
   skiSnowSound         = SkiAllSnowSound;

   impactWaterEasy      = ImpactHeavyWaterEasySound;
   impactWaterMedium    = ImpactHeavyWaterMediumSound;
   impactWaterHard      = ImpactHeavyWaterHardSound;
   
   groundImpactMinSpeed    = 10.0;
   groundImpactShakeFreq   = "4.0 4.0 4.0";
   groundImpactShakeAmp    = "1.0 1.0 1.0";
   groundImpactShakeDuration = 0.8;
   groundImpactShakeFalloff = 10.0;

   exitingWater         = ExitingWaterHeavySound;
   
   maxWeapons = 5;            // Max number of different weapons the player can have
   maxGrenades = 1;           // Max number of different grenades the player can have
   maxMines = 1;              // Max number of different mines the player can have
   
   // Inventory restrictions
   max[RepairKit]          = 1;

   // Weapons and Ammo
   max[Blaster]             = 1;
   max[Plasma]              = 1;
   max[PlasmaAmmo]          = 48;
   max[Disc]                = 1;
   max[DiscAmmo]            = 25;
   max[GrenadeLauncher]     = 1;
   max[GrenadeLauncherAmmo] = 24;
   max[Mortar]              = 1;
   max[MortarAmmo]          = 12;
   max[MissileLauncher]     = 1;
   max[MissileLauncherAmmo] = 10;
   max[ParticleCannon]      = 1;
   max[Chaingun]            = 1;
   max[ChaingunAmmo]        = 350;
   max[TargetingLaser]      = 1;
   max[FlashLight]         = 1;
   max[ELFGun]              = 1;
   max[ShockLance]          = 1;
   max[Shotgun]             = 1;
   max[ShotgunAmmo]         = 60;
   max[AutoRocketAmmo]      = 6;
   max[SMissileAmmo]        = 2;
   max[Magnum]              = 1;
   max[MagnumAmmo]          = 42;

   // Specials
   max[CodeBreaker]     = 1;
   max[GrapplingHook]   = 1;
   max[Hologram]        = 1;
   max[InertialDampner] = 1;
   max[LightShield]     = 1;
   max[SpeedBooster]    = 1;
   max[Beacon]          = 3;
   max[TargetingBeacon] = 3;
   max[WCS]             = 1;

   // Packs
   max[RepairGun]           = 1;
   max[SensorJammerPack]    = 1;
   max[EnergyPack]          = 1;
   max[RepairPack]          = 1;
   max[ShieldPack]          = 1;
   max[AmmoPack]            = 1;
   max[SatchelCharge]       = 1;
   max[TAG]                 = 1;
   max[TAGGun]              = 1;
   max[AutoRocketPack]      = 1;
   max[SMissilePack]        = 1;
   max[SpringboardPack]     = 1;

   // Deployables
   max[VehicleMine]                = 1;
   max[DeployableSensorJammerPack] = 1;
   max[MotionSensorDeployable]     = 1;
   max[PulseSensorDeployable]      = 1;
   max[InventoryDeployable]        = 1;
   max[SensorTapPack]              = 1;

   // Mines
   max[Mine]               = 5;
   max[EMPMine]            = 5;
   max[IncendiaryMine]     = 5;
   max[StunMine]           = 5;
   max[ConcussionMine]     = 5;

   // Grenades
   max[Grenade]           = 6;
   max[ConcussionGrenade] = 4;
   max[CameraGrenade]     = 3;
   max[EMPGrenade]        = 4;
   max[IncendiaryGrenade] = 4;
   max[PlasticExplosive]  = 4;
   max[FlashGrenade]      = 4;
   max[FlareGrenade]      = 8;
   max[ECMGrenade]        = 4;
   
   observeParameters = "0.5 4.5 4.5";

   shieldEffectScale = "0.7 0.7 1.0";
};

// ---------------------------------------------------------------------------
datablock PlayerData(AdrenMaleHumanArmor) : LightMaleHumanArmor
{
   runForce = 8500;
   maxForwardSpeed = 26;
   maxBackwardSpeed = 22;
   maxSideSpeed = 22;

   AdrenalineDuration = 12;
   AdrenalineVariance = 4;

   maxUnderwaterForwardSpeed = 14;
   maxUnderwaterBackwardSpeed = 13;
   maxUnderwaterSideSpeed = 13;

   jumpForce = 1400;

   recoverDelay = 9;
   recoverRunForceScale = 1.2;
};

//----------------------------------------------------------------------------
datablock PlayerData(LightFemaleHumanArmor) : LightMaleHumanArmor
{
   shapeFile = "light_female.dts";
   waterBreathSound = WaterBreathFemaleSound;
   jetEffect =  HumanMediumArmorJetEffect;
};

// ---------------------------------------------------------------------------
datablock PlayerData(AdrenFemaleHumanArmor) : LightFemaleHumanArmor
{
   runForce = 8400;
   maxForwardSpeed = 26;
   maxBackwardSpeed = 22;
   maxSideSpeed = 22;

   AdrenalineDuration = 12;
   AdrenalineVariance = 3.5;

   maxUnderwaterForwardSpeed = 14;
   maxUnderwaterBackwardSpeed = 13;
   maxUnderwaterSideSpeed = 13;

   jumpForce = 1450;

   recoverDelay = 9;
   recoverRunForceScale = 1.2;
};

//----------------------------------------------------------------------------
datablock PlayerData(MediumFemaleHumanArmor) : MediumMaleHumanArmor
{
   shapeFile = "medium_female.dts";
   waterBreathSound = WaterBreathFemaleSound;
   jetEffect =  HumanArmorJetEffect;
};

//----------------------------------------------------------------------------
datablock PlayerData(EngineerFemaleHumanArmor) : EngineerMaleHumanArmor
{
   shapeFile = "medium_female.dts";
   waterBreathSound = WaterBreathFemaleSound;
};

//----------------------------------------------------------------------------
datablock PlayerData(HeavyFemaleHumanArmor) : HeavyMaleHumanArmor
{
   shapeFile = "heavy_male.dts";
   waterBreathSound = WaterBreathFemaleSound;
};

//----------------------------------------------------------------------------
datablock DecalData(LightBiodermFootprint)
{
   sizeX       = 0.25;
   sizeY       = 0.25;
   textureName = "special/footprints/L_bioderm";
};

datablock PlayerData(LightMaleBiodermArmor) : LightMaleHumanArmor
{
   shapeFile = "bioderm_light.dts";
   jetEmitter = BiodermArmorJetEmitter;
   jetEffect =  BiodermArmorJetEffect;


   debrisShapeName = "bio_player_debris.dts";
   
   //Foot Prints
   decalData   = LightBiodermFootprint;
   decalOffset = 0.3;

   waterBreathSound = WaterBreathBiodermSound;
};

// ---------------------------------------------------------------------------
datablock PlayerData(AdrenMaleBiodermArmor) : LightMaleBiodermArmor
{
   runForce = 8600;
   maxForwardSpeed = 26;
   maxBackwardSpeed = 22;
   maxSideSpeed = 22;

   AdrenalineDuration = 12;
   AdrenalineVariance = 4.5;

   maxUnderwaterForwardSpeed = 14;
   maxUnderwaterBackwardSpeed = 13;
   maxUnderwaterSideSpeed = 13;

   jumpForce = 1450;

   recoverDelay = 9;
   recoverRunForceScale = 1.2;
};

//----------------------------------------------------------------------------
datablock DecalData(MediumBiodermFootprint)
{
   sizeX       = 0.25;
   sizeY       = 0.25;
   textureName = "special/footprints/M_bioderm";
};

datablock PlayerData(MediumMaleBiodermArmor) : MediumMaleHumanArmor
{
   shapeFile = "bioderm_medium.dts";
   jetEmitter = BiodermArmorJetEmitter;
   jetEffect =  BiodermArmorJetEffect;

   debrisShapeName = "bio_player_debris.dts";

   //Foot Prints
   decalData   = MediumBiodermFootprint; 
   decalOffset = 0.35;

   waterBreathSound = WaterBreathBiodermSound;
};

datablock PlayerData(EngineerMaleBiodermArmor) : EngineerMaleHumanArmor
{
   shapeFile = "bioderm_medium.dts";
   jetEmitter = BiodermArmorJetEmitter;

   //Foot Prints
   decalData   = MediumBiodermFootprint; 
   decalOffset = 0.35;

   waterBreathSound = WaterBreathBiodermSound;
};

//----------------------------------------------------------------------------
datablock DecalData(HeavyBiodermFootprint)
{
   sizeX       = 0.25;
   sizeY       = 0.5;
   textureName = "special/footprints/H_bioderm";
};

datablock PlayerData(HeavyMaleBiodermArmor) : HeavyMaleHumanArmor
{
   emap = false;

   shapeFile = "bioderm_heavy.dts";
   jetEmitter = BiodermArmorJetEmitter;

   debrisShapeName = "bio_player_debris.dts";

   //Foot Prints
   decalData    = HeavyBiodermFootprint;
   decalOffset  = 0.4;
   
   waterBreathSound = WaterBreathBiodermSound;
};

datablock PlayerData(Hero) : HeavyMaleHumanArmor
{
   emap = true;

   className = Armor;
   shapeFile = "heavy_male.dts";
   cameraMaxDist = 3;
   computeCRC = true;

   debrisShapeName = "debris_player.dts";
   debris = playerDebris;

   canObserve = false;
   cmdCategory = "Clients";
   cmdIcon = CMDPlayerIcon;
   cmdMiniIconName = "commander/MiniIcons/com_player_grey";

   hudImageNameFriendly[0] = "gui/hud_playertriangle.png";
   hudImageNameEnemy[0] = "gui/hud_playertriangle_enemy.png";
   hudRenderModulated[0] = true;

   hudImageNameFriendly[1] = "commander/MiniIcons/com_flag_grey";
   hudImageNameEnemy[1] = "commander/MiniIcons/com_flag_grey";
   hudRenderModulated[1] = true;
   hudRenderAlways[1] = true;
   hudRenderCenter[1] = true;
   hudRenderDistance[1] = true;

   hudImageNameFriendly[2] = "commander/MiniIcons/com_flag_grey";
   hudImageNameEnemy[2] = "commander/MiniIcons/com_flag_grey";
   hudRenderModulated[2] = true;
   hudRenderAlways[2] = true;
   hudRenderCenter[2] = true;
   hudRenderDistance[2] = true;

   aiAvoidThis = true;

   minLookAngle = -1.4;
   maxLookAngle = 1.4;
   maxFreelookAngle = 3.0;

   mass = 160;
   drag = 0.5;
   maxdrag = 0.6;
   density = 10;
   maxDamage = 1.75;
   maxEnergy =  85;
   repairRate = 0.0030;
   energyPerDamagePoint = 75.0; // shield energy required to block one point of damage

   rechargeRate = 4;
   jetForce = 10000;
   underwaterJetForce = 16000;
   underwaterVertJetFactor = 1.3;
   jetEnergyDrain =  1.05;
   underwaterJetEnergyDrain =  0.45;
   minJetEnergy = 1;
   maxJetHorizontalPercentage = 0.98;

   runForce = 35000;
   runEnergyDrain = 0;
   minRunEnergy = 0;
   maxForwardSpeed = 24;
   maxBackwardSpeed = 18;
   maxSideSpeed = 18;

   maxUnderwaterForwardSpeed = 35;
   maxUnderwaterBackwardSpeed = 26;
   maxUnderwaterSideSpeed = 26;

   recoverDelay = 9;
   recoverRunForceScale = 1.2;

   jumpForce = 2500;
   jumpEnergyDrain = 0;
   minJumpEnergy = 0;
   jumpDelay = 0;
   
   // heat inc'ers and dec'ers
   heatDecayPerSec      = 1/4; // takes 3 seconds to clear heat sig.
   heatIncreasePerSec   = 1/1.5; // takes 2 seconds of constant jet to get full heat sig.

   // Controls over slope of runnable/jumpable surfaces
   runSurfaceAngle  = 75;
   jumpSurfaceAngle = 75;

   minJumpSpeed = 20;
   maxJumpSpeed = 30;

   horizMaxSpeed = 820;
   horizResistSpeed = 20;
   horizResistFactor = 0.3;
   maxJetForwardSpeed = 16;

   upMaxSpeed = 200;
   upResistSpeed = 35;
   upResistFactor = 0.12;

   minImpactSpeed = 70;
   speedDamageScale = 0.004;

   jetSound = ArmorJetSound;
   wetJetSound = ArmorJetSound;
   jetEmitter = HumanArmorJetEmitter;

   boundingBox = "0.001 0.001 0.001";
   pickupRadius = 0.75;
   
   // damage location details
   boxNormalHeadPercentage       = 0.83;
   boxNormalTorsoPercentage      = 0.49;
   boxHeadLeftPercentage         = 0;
   boxHeadRightPercentage        = 1;
   boxHeadBackPercentage         = 0;
   boxHeadFrontPercentage        = 1;

   //Foot Prints
   decalData   = HeavyMaleFootprint;
   decalOffset = 0.4;

   footPuffEmitter = LightPuffEmitter;
   footPuffNumParts = 15;
   footPuffRadius = 0.25;

   dustEmitter = LiftoffDustEmitter;

   splash = PlayerSplash;
   splashVelocity = 4.0;
   splashAngle = 67.0;
   splashFreqMod = 300.0;
   splashVelEpsilon = 0.60;
   bubbleEmitTime = 0.4;
   splashEmitter[0] = PlayerFoamDropletsEmitter;
   splashEmitter[1] = PlayerFoamEmitter;
   splashEmitter[2] = PlayerBubbleEmitter;
   mediumSplashSoundVelocity = 10.0;   
   hardSplashSoundVelocity = 20.0;   
   exitSplashSoundVelocity = 5.0;

   footstepSplashHeight = 0.35;
   //Footstep Sounds
   LFootSoftSound       = LFootHeavySoftSound;
   RFootSoftSound       = RFootHeavySoftSound;
   LFootHardSound       = LFootHeavyHardSound;
   RFootHardSound       = RFootHeavyHardSound;
   LFootMetalSound      = LFootHeavyMetalSound;
   RFootMetalSound      = RFootHeavyMetalSound;
   LFootSnowSound       = LFootHeavySnowSound;
   RFootSnowSound       = RFootHeavySnowSound;
   LFootShallowSound    = LFootHeavyShallowSplashSound;
   RFootShallowSound    = RFootHeavyShallowSplashSound;
   LFootWadingSound     = LFootHeavyWadingSound;
   RFootWadingSound     = RFootHeavyWadingSound;
   LFootUnderwaterSound = LFootHeavyUnderwaterSound;
   RFootUnderwaterSound = RFootHeavyUnderwaterSound;
   LFootBubblesSound    = LFootHeavyBubblesSound;
   RFootBubblesSound    = RFootHeavyBubblesSound;
   movingBubblesSound   = ArmorMoveBubblesSound;
   waterBreathSound     = WaterBreathMaleSound;

   impactSoftSound      = ImpactHeavySoftSound;
   impactHardSound      = ImpactHeavyHardSound;
   impactMetalSound     = ImpactHeavyMetalSound;
   impactSnowSound      = ImpactHeavySnowSound;
   
   skiSoftSound         = SkiAllSoftSound;
   skiHardSound         = SkiAllHardSound;
   skiMetalSound        = SkiAllMetalSound;
   skiSnowSound         = SkiAllSnowSound;

   impactWaterEasy      = ImpactHeavyWaterEasySound;
   impactWaterMedium    = ImpactHeavyWaterMediumSound;
   impactWaterHard      = ImpactHeavyWaterHardSound;
   
   groundImpactMinSpeed    = 10.0;
   groundImpactShakeFreq   = "4.0 4.0 4.0";
   groundImpactShakeAmp    = "1.0 1.0 1.0";
   groundImpactShakeDuration = 0.8;
   groundImpactShakeFalloff = 10.0;

   exitingWater         = ExitingWaterHeavySound;
   
   maxWeapons = 5;            // Max number of different weapons the player can have
   maxGrenades = 1;           // Max number of different grenades the player can have
   maxMines = 1;              // Max number of different mines the player can have
   
   // Inventory restrictions
   max[RepairKit]          = 1;

   // Weapons and Ammo
   max[Blaster]            = 1;
   max[Plasma]             = 1;
   max[PlasmaAmmo]         = 480;
   max[Disc]               = 1;
   max[DiscAmmo]           = 250;
   max[GrenadeLauncher]    = 1;
   max[GrenadeLauncherAmmo]= 240;
   max[Mortar]             = 1;
   max[MortarAmmo]         = 120;
   max[MissileLauncher]    = 1;
   max[MissileLauncherAmmo]= 100;
   max[ParticleCannon]     = 1;
   max[Chaingun]           = 1;
   max[ChaingunAmmo]       = 3500;
   max[TargetingLaser]     = 1;
   max[ELFGun]             = 1;
   max[ShockLance]         = 1;
   max[Shotgun]            = 1;
   max[ShotgunAmmo]        = 600;
   max[SniperRifle]        = 1;
   max[Rifle]              = 1;
   max[RifleAmmo]          = 80;

   // Specials
   max[CodeBreaker]     = 1;
   max[GrapplingHook]   = 1;
   max[InertialDampner] = 1;
   max[LightShield]     = 1;
   max[SpeedBooster]    = 1;
   max[Beacon]          = 3;
   max[TargetingBeacon] = 3;

   // Packs
   max[RepairGun]          = 1;
   max[SensorJammerPack]   = 1;
   max[EnergyPack]         = 1;
   max[RepairPack]         = 1;
   max[ShieldPack]         = 1;
   max[AmmoPack]           = 1;
   max[SatchelCharge]      = 1;
   max[TAG]                = 1;
   max[TAGGun]             = 1;
   max[JetPack]            = 1;

   // Deployables
   max[VehicleMine]                = 1;
   max[DeployableSensorJammerPack] = 1;
   max[MotionSensorDeployable]     = 1;
   max[PulseSensorDeployable]      = 1;
   max[InventoryDeployable]        = 1;

   // Mines
   max[Mine]               = 5;
   max[EMPMine]            = 5;
   max[IncendiaryMine]     = 5;
   max[StunMine]           = 5;
   max[ConcussionMine]     = 5;

   // Grenades
   max[Grenade]           = 5;
   max[ConcussionGrenade] = 4;
   max[CameraGrenade]     = 3;
   max[EMPGrenade]        = 4;
   max[IncendiaryGrenade] = 4;
   max[PlasticExplosive]  = 4;
   max[FlashGrenade]      = 4;
   max[FlareGrenade]      = 8;
   
   observeParameters = "0.5 4.5 4.5";

   shieldEffectScale = "0.7 0.7 1.0";
};

//----------------------------------------------------------------------------

function Armor::onAdd(%data,%obj)
{
   Parent::onAdd(%data, %obj);
   // Vehicle timeout
   %obj.mountVehicle = true;

   // Default dynamic armor stats
   %obj.setRechargeRate(%data.rechargeRate);
   %obj.setRepairRate(0);

   %obj.setSelfPowered();
}

function Armor::onRemove(%this, %obj)
{
   //Frohny asked me to remove this - all players are deleted now on mission cycle...
   //if(%obj.getState() !$= "Dead")
   //{
   //   error("ERROR PLAYER REMOVED WITHOUT DEATH - TRACE:");
   //   trace(1);
   //   schedule(0,0,trace,0);
   //}

   if (%obj.client.player == %obj)
      %obj.client.player = 0;
}

function Armor::onNewDataBlock(%this,%obj)
{
}

function Armor::onDisabled(%this,%obj,%state)
{
   %fadeTime = 1000;
   %obj.startFade( %fadeTime, ($CorpseTimeoutValue) - %fadeTime, true );
   %obj.schedule($CorpseTimeoutValue, "delete");
}

function Armor::shouldApplyImpulse(%data, %obj)
{
   return true;
}

$wasFirstPerson = true;

function Armor::onMount(%this,%obj,%vehicle,%node)
{
   if (%node == 0)
   {
      // Node 0 is the pilot's pos.
      %obj.setTransform("0 0 0 0 0 1 0");
      %obj.setActionThread(%vehicle.getDatablock().mountPose[%node],true,true);
      %obj.lastWeapon = %obj.getMountedImage($WeaponSlot);
      %obj.unmountImage($WeaponSlot);
      if(!%obj.client.isAIControlled())
      {
         %obj.setControlObject(%vehicle);
         %obj.client.setObjectActiveImage(%vehicle, 2);
      }
      
      //E3 respawn...
 
      if(%obj == %obj.lastVehicle.lastPilot && %obj.lastVehicle != %vehicle)
      {
         schedule(15000, %obj.lastVehicle,"vehicleAbandonTimeOut", %obj.lastVehicle);
          %obj.lastVehicle.lastPilot = "";
      }
      if(%vehicle.lastPilot !$= "" && %vehicle == %vehicle.lastPilot.lastVehicle)
            %vehicle.lastPilot.lastVehicle = "";
            
      %vehicle.abandon = false;
      %vehicle.lastPilot = %obj;
      %obj.lastVehicle = %vehicle;

      // update the vehicle's team
      if((%vehicle.getTarget() != -1) && %vehicle.getDatablock().cantTeamSwitch $= "")
         setTargetSensorGroup(%vehicle.getTarget(), %obj.client.getSensorGroup());

      // Send a message to the client so they can decide if they want to change view or not:
      commandToClient( %obj.client, 'VehicleMount' );

   }
   else
   {
      // tailgunner/passenger positions
      if(%vehicle.getDataBlock().mountPose[%node] !$= "")
         %obj.setActionThread(%vehicle.getDatablock().mountPose[%node]);
      else
         %obj.setActionThread("root", true);
   }
   // announce to any other passengers that you've boarded
   if(%vehicle.getDatablock().numMountPoints > 1)
      for(%i = 0; %i < %vehicle.getDatablock().numMountPoints; %i++)
         if (%vehicle.getMountNodeObject(%i) > 0)
            commandToClient(%pilot.client, 'showPassenger', %node, true);

   //make sure they don't have any packs active
//    if ( %obj.getImageState( $BackpackSlot ) $= "activate")
//       %obj.use("Backpack");
   if ( %obj.getImageTrigger( $BackpackSlot ) )
      %obj.setImageTrigger( $BackpackSlot, false );

   //AI hooks
   %obj.client.vehicleMounted = %vehicle;
   AIVehicleMounted(%vehicle);
   if(%obj.client.isAIControlled())
      %this.AIonMount(%obj, %vehicle, %node);
}


function Armor::onUnmount(%this, %Player, %Vehicle, %Node)
{
   if (%node == 0)
   {
      commandToClient(%Player.client, 'VehicleDismount');
      %Player.mountImage(%Player.lastWeapon, $WeaponSlot);
   }

   // Let all the passengers know someone left
   NotifyPassengers(%Vehicle.getDataBlock(), %Vehicle);
   
   //AI hooks
   %Player.client.vehicleMounted = "";
   if(%Player.client.isAIControlled())
      %this.AIonUnMount(%Player, %Vehicle, %Node);
}

$ammoType[0] = "PlasmaAmmo";
$ammoType[1] = "DiscAmmo";
$ammoType[2] = "GrenadeLauncherAmmo";
$ammoType[3] = "MortarAmmo";
$ammoType[4] = "MissileLauncherAmmo";
$ammoType[5] = "ChaingunAmmo";

function Armor::onCollision(%this,%obj,%col,%forceVehicleNode)
{
   if (%obj.getState() $= "Dead")
      return;

   %dataBlock = %col.getDataBlock();
   %className = %dataBlock.className;
   %client = %obj.client;
   // player collided with a vehicle
   %node = -1;
   if (%forceVehicleNode !$= "" || (%className $= WheeledVehicleData || %className $= FlyingVehicleData || %className $= HoverVehicleData) &&
         %obj.mountVehicle && %obj.getState() $= "Move" && %col.mountable) {

      //if the player is an AI, he should snap to the mount points in node order,
      //to ensure they mount the turret before the passenger seat, regardless of where they collide...
      if (%obj.client.isAIControlled())
      {
         %transform = %col.getTransform();   

         //either the AI is *required* to pilot, or they'll pick the first available passenger seat
         if (%client.pilotVehicle)
         {
            //make sure the bot is in light armor
            if (%client.player.getArmorSize() $= "Light")
            {
               //make sure the pilot seat is empty
               if (!%col.getMountNodeObject(0))
                  %node = 0;
            }
         }
         else
            %node = findAIEmptySeat(%col, %obj);
      }
      else
         %node = findEmptySeat(%col, %obj, %forceVehicleNode);

      //now mount the player in the vehicle
      if(%node >= 0)
      {
         // players can't be pilots, bombardiers or turreteers if they have
         // "large" packs -- stations, turrets, turret barrels
         if(hasLargePack(%obj)) {
            // check to see if attempting to enter a "sitting" node
            if(nodeIsSitting(%datablock, %node)) {
               // send the player a message -- can't sit here with large pack
               if (%this.PackMessage $= "")
                  %this.PackMessage = %this.schedule(1000, PilotPackMessage);

               return;
            }
         }
         if(%col.noEnemyControl && %obj.team != %col.team)
            return;
            
         commandToClient(%obj.client,'SetDefaultVehicleKeys', true);
         //If pilot or passenger then bind a few extra keys
         if(%node == 0)
            commandToClient(%obj.client,'SetPilotVehicleKeys', true);
         else
            commandToClient(%obj.client,'SetPassengerVehicleKeys', true);

         %col.lastWeapon = %col.getMountedImage($WeaponSlot);
         %col.mountObject(%obj,%node);
         %col.playAudio(0, MountVehicleSound);
         %obj.mVehicle = %col;

			// if player is repairing something, stop it
			if(%obj.repairing)
				stopRepairing(%obj);

         //this will setup the huds as well...
         %dataBlock.playerMounted(%col,%obj, %node);
      }
   }
   else if (%className $= "Armor") {
      // player has collided with another player
      if(%col.getState() $= "Dead")
      {
         if (%Col.BurnTime > 2)
         {
            %Random = getRandom();
            if (%Random > 0.35)
            {
               %BurnTime = %Col.BurnTime / 2;
               %BurnStrength = %Col.BurnStrength / 1.5;
               %obj.Burn(%BurnTime, %BurnStrength, 0);
            }
         }


         %gotSomething = false;
         // it's corpse-looting time!
         // weapons -- don't pick up more than you are allowed to carry!
         for(%i = 0; ( %obj.weaponCount < %obj.getDatablock().maxWeapons ) && $InvWeapon[%i] !$= ""; %i++) 
         {
            %weap = $NameToInv[$InvWeapon[%i]];
            if ( %col.hasInventory( %weap ) )
            {
               if ( %obj.incInventory(%weap, 1) > 0 )
               {
                  %col.decInventory(%weap, 1);
                  %gotSomething = true;
                  messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %weap.pickUpName);
               }
            }
         }
         // targeting laser:
         if ( %col.hasInventory( "TargetingLaser" ) )
         {
            if ( %obj.incInventory( "TargetingLaser", 1 ) > 0 )
            {
               %col.decInventory( "TargetingLaser", 1 );
               %gotSomething = true;
               messageClient( %obj.client, 'MsgItemPickup', '\c0You picked up a targeting laser.' );
            }
         }
         // ammo
         for(%j = 0; $ammoType[%j] !$= ""; %j++)
         {
            %ammoAmt = %col.inv[$ammoType[%j]];
            if(%ammoAmt)
            {
               // incInventory returns the amount of stuff successfully grabbed
               %grabAmt = %obj.incInventory($ammoType[%j], %ammoAmt);
               if(%grabAmt > 0)
               {
                  %col.decInventory($ammoType[%j], %grabAmt);
                  %gotSomething = true;
                  messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', $ammoType[%j].pickUpName);
                  %obj.client.setWeaponsHudAmmo($ammoType[%j], %obj.getInventory($ammoType[%j]));
               }
            }
         }
         // figure out what type, if any, grenades the (live) player has
         %playerGrenType = "None";
         for(%x = 0; $InvGrenade[%x] !$= ""; %x++) {
            %gren = $NameToInv[$InvGrenade[%x]];
            %playerGrenAmt = %obj.inv[%gren];
            if(%playerGrenAmt > 0)
            {
               %playerGrenType = %gren;
               break;
            }
         }
         // grenades
         for(%k = 0; $InvGrenade[%k] !$= ""; %k++)
         {
            %gren = $NameToInv[$InvGrenade[%k]];
            %corpseGrenAmt = %col.inv[%gren];
            // does the corpse hold any of this grenade type?
            if(%corpseGrenAmt)
            {
               // can the player pick up this grenade type?
               if((%playerGrenType $= "None") || (%playerGrenType $= %gren))
               {
                  %taken = %obj.incInventory(%gren, %corpseGrenAmt);
                  if(%taken > 0)
                  {
                     %col.decInventory(%gren, %taken);
                     %gotSomething = true;
                     messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %gren.pickUpName);
                     %obj.client.setInventoryHudAmount(%gren, %obj.getInventory(%gren));
                  }
               }
               break;
            }
         }
         // figure out what type, if any, mines the (live) player has
         %playerMineType = "None";
         for(%y = 0; $InvMine[%y] !$= ""; %y++)
         {
            %mType = $NameToInv[$InvMine[%y]];
            %playerMineAmt = %obj.inv[%mType];
            if(%playerMineAmt > 0)
            {
               %playerMineType = %mType;
               break;
            }
         }
         // mines
         for(%l = 0; $InvMine[%l] !$= ""; %l++)
         {
            %mine = $NameToInv[$InvMine[%l]];
            %mineAmt = %col.inv[%mine];
            if(%mineAmt) {
               if((%playerMineType $= "None") || (%playerMineType $= %mine))
               {
                  %grabbed = %obj.incInventory(%mine, %mineAmt);
                  if(%grabbed > 0)
                  {
                     %col.decInventory(%mine, %grabbed);
                     %gotSomething = true;
                     messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', %mine.pickUpName);
                     %obj.client.setInventoryHudAmount(%mine, %obj.getInventory(%mine));
                  }
               }
               break;
            }
         }
         // beacons
         %beacAmt = %col.inv[Beacon];
         if(%beacAmt)
         {
            %bTaken = %obj.incInventory(Beacon, %beacAmt);
            if(%bTaken > 0)
            {
               %col.decInventory(Beacon, %bTaken);
               %gotSomething = true;
               messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', Beacon.pickUpName);
               %obj.client.setInventoryHudAmount(Beacon, %obj.getInventory(Beacon));
            }
         }
         // repair kit
         %rkAmt = %col.inv[RepairKit];
         if(%rkAmt)
         {
            %rkTaken = %obj.incInventory(RepairKit, %rkAmt);
            if(%rkTaken > 0)
            {
               %col.decInventory(RepairKit, %rkTaken);
               %gotSomething = true;
               messageClient(%obj.client, 'MsgItemPickup', '\c0You picked up %1.', RepairKit.pickUpName);
               %obj.client.setInventoryHudAmount(RepairKit, %obj.getInventory(RepairKit));
            }
         }
      }
      if(%gotSomething)
         %col.playAudio(0, CorpseLootingSound);
   }
}



function Player::setInvincible(%this, %val)
{
   %this.invincible = %val;
}

function Player::causedRecentDamage(%this, %val)
{
   %this.causedRecentDamage = %val; 
}
   
function hasLargePack(%player)
{
   %pack = %player.getMountedImage($BackpackSlot);
   if(%pack.isLarge)
      return true;
   else
      return false;
}

function nodeIsSitting(%vehDBlock, %node)
{
   // pilot == always a "sitting" node
   if(%node == 0)
      return true;
   else {
      switch$ (%vehDBlock.getName())
      {
         // note: for assault tank -- both nodes are sitting
         // for any single-user vehicle -- pilot node is sitting
         case "BomberFlyer":
            // bombardier == sitting; tailgunner == not sitting
            if(%node == 1)
               return true;
            else
               return false;
         case "HAPCFlyer":
            // only the pilot node is sitting
            return false;
         default:
            return true;
      }
   }
}

//----------------------------------------------------------------------------
function Player::setMountVehicle(%this, %val)
{
   %this.mountVehicle = %val;
}

function Armor::doDismount(%this, %Player, %Forced)
{
   if (%Player.isMounted() == false)
      return;

   %Vehicle = %Player.getObjectMount();
   %VehicleData = %Vehicle.getDataBlock();
   %VehicleTransform = %Vehicle.getTransform();
   %VehicleSpeed = VectorLen(%Vehicle.getVelocity());

   %Shield = %Vehicle.shield;
   if(isObject(%Shield))
      %Shield.delete();

   %PlayerTransform = %Player.getTransform();

   // hide the dashboard HUD and delete elements based on node
   commandToClient(%Player.client,'SetDefaultVehicleKeys', false);
   commandToClient(%Player.client, 'setHudMode', 'Standard', "", 0);

   // Position above dismount point
   %OldPosition = posFromTransform(%Player.getTransform());
   %Vector[1] = " 0  0  1";
   %Vector[2] = " 0  0 -1";
   %Vector[3] = " 1  0  0";
   %Vector[4] = "-1  0  0";

   %numAttempts = 5;
   %Success = -1;
   %ImpulseVector  = "0 0 0";

   if (%VehicleData.hasDismountOverrides() == true)
   {
      %Vector[0] = %VehicleData.getDismountOverride(%Vehicle, %Player);
      %Vector[0] = MatrixMulVector(%VehicleTransform, %Vector[0]);
   }
   else
   {
      %Vector[0] = " 0  0  1";
      %Vector[0] = MatrixMulVector(%PlayerTransform, %Vector[0]);
   }

   // Loop through checking if you can dismount there and define it as
   // the proper place and angle
   %Position = "0 0 0";
   %i = 0;
   while (%i < %numAttempts)
   {
      %Position = VectorAdd(%OldPosition, VectorScale(%Vector[%i], 3));
      if (%Player.checkDismountPoint(%OldPosition, %Position))
      {
         %Success = %i;
         %ImpulseVector = %Vector[%i];
         break;
      }
      %i++;
   }

   if (%Forced && %Success == -1)
   {
      %Position = %OldPosition;
   }

   // Unmount and control body
   if(%Player.vehicleTurret)
      %Player.vehicleTurret.getDataBlock().playerDismount(%Player.vehicleTurret);

   %Player.unmount();

   if(%Player.mVehicle)
      %Player.mVehicle.getDataBlock().playerDismounted(%Player.mVehicle, %Player);

   // bots don't change their control objects when in vehicles
   if(!%Player.client.isAIControlled())
   {
      %Vehicle = %Player.getControlObject();
      %Player.setControlObject(0);
   }
   
   %Player.mountVehicle = false;
   %Player.schedule(4000, "setMountVehicle", true);

   // Position above dismount point
   %Player.setTransform(%Position);
   %Player.playAudio(0, UnmountVehicleSound);
   %Player.setPilot(false);
   %Player.vehicleTurret = "";

   // Determine the Ejection Velocity.  If moving slow enough, eject the player
   // completely and use the players mass as a basis
   %PlayerMass = %Player.getDataBlock().mass;
   %EjectionVelocity = %VehicleSpeed * 50;
   if (%EjectionVelocity < %PlayerMass * 3)
      %EjectionVelocity = %PlayerMass * 3;

   if (%EjectionVelocity > %PlayerMass * 70)
      %EjectionVelocity = %PlayerMass * 70;

   // Based on Vehicle Velocity, we eject the player
   %Player.applyImpulse(%Position, VectorScale(%ImpulseVector, %EjectionVelocity));
}

//----------------------------------------------------------------------------
function Player::scriptKill(%player, %damageType)
{
   %player.scriptKilled = true; 
   %player.setInvincible(false);
   %player.damage(0, %player.getPosition(), 10000, %damageType);
}

function Player::CheckForShields(%this)
{
   // If the player is in a vehicle that has at least 15 energy
   if (%this.isMounted())
   {
      %Vehicle = %this.getObjectMount();
      if (%Vehicle > 0 && %Vehicle.getEnergyLevel() >= 15)
         return(true);
   }
 
   // If the player has an active shield pack or special.
   if (%this.ShieldStrength > 0)
      return(true);

   if (%this.Special $= "LightShield" && %this.ShieldRemaining > 0)
      return(true);

   // If the player is in a vehicle that has more than 15 energy.
   if (%this.getObjectMount())
   {
      %Energy = %this.getObjectMount().getEnergyLevel();
      if (%Energy > 15)
      return(true);
   }

   // Otherwise, no they are not shielded.
   return(false);
}

function Armor::checkShields(%data, %Player, %Position, %Amount, %DamageType)
{
   // If there is no damage, return
   if (%Amount == 0)
      return(%Amount);

   // If the player has no shielding and no Light Shield, then return the full amount
   %ShieldStrength = %Player.ShieldStrength;
   if (%ShieldStrength $= "" && %Player.Special !$="LightShield")
      return(%Amount);

   // If the player has a light shield without any power, return the full amount
   if (%Player.Special $= "LightShield" && %Player.ShieldRemaining <= 0)
      return(%Amount);

   // Load the Shielding Damage Scale
   %ShieldScale = $shieldDamageScale[%DamageType];
   if(%ShieldScale $= "")
      %ShieldScale = 1.0;

   // Check for Regular Shielding Methods
   if (%ShieldStrength > 0)
   {
      %Energy = %Player.getEnergyLevel();
      %Shielding = %Energy / %ShieldStrength;

      if (%Amount * %ShieldScale <= %Shielding)
      {
         // Shield absorbs all
         %Lost = (%Amount * %ShieldScale * %ShieldStrength);
         %Energy -= %Lost;
         %Player.setEnergyLevel(%Energy);
         %Amount = 0;
      } else {
         %Amount -= (%Shielding / %ShieldScale);
         %Player.setEnergyLevel(0);
         %Player.setImageTrigger($BackPackSlot, false);
      }
   }

   // If the Player has a Light Shield, check it next.
   if (%Player.Special $= "LightShield")
   {
      %Shielding = %Player.ShieldRemaining;
   
      if (%Amount * %ShieldScale <= %Shielding)
      {
         // Shield absorbs all
         %Player.ShieldRemaining -= (%Amount * %ShieldScale);
         %Player.LightShieldHum(2);
         %Amount = 0;
      } else {
         // Shield fails but takes some damage with it.
         %Amount -= (%Shielding / %ShieldScale);
         %Player.ShieldRemaining = 0;
         messageClient(%Player.client, '', 'Light Shielding has failed.');
         %Player.LightShieldHum(0);
      }
   }

   %Player.playShieldEffect("0.0 0.0 1.0");
   return(%Amount);
}

function Armor::damageObject(%Data, %Player, %SourceObject, %Position, %Amount, %DamageType, %Momentium)
{
   // If dead or invincible, ignore any attemp at damaging them
   if (%Player.invincible == true || %Player.getState() $= "Dead")
      return;

   // If there is no damage, ignore it
   if (%Amount == 0)
      return;

   // If the attacker and attackee are both under the same vehicles shields allow the
   // damage to happen.  If not, then the vehicle absorbs it.  If not enough power for
   // shields the player takes the damage.
   if (%Player.isMounted() == true && %Player.scriptKilled $= "")
   {
      %PlayerMount = %Player.getObjectMount();
      %SourceMount = %SourceObject.getObjectMount();
      if (%PlayerMount != %SourceMount || %DamageType == $DamageType::Impact || %DamageType == $DamageType::Water)
      {
         %Found = -1;
         for (%i = 0; %i < %PlayerMount.getDataBlock().numMountPoints; %i++)
         {
            if (%PlayerMount.getMountNodeObject(%i) == %Player)
            {
               %Found = %i;
               break;
            }
         }

         if (%Found != -1)
         {
            // If the player is on a shielded piece of the vehicle and has more than 15 energy
            // then they are protected.
            %Energy = %PlayerMount.getEnergyLevel();
            if (%PlayerMount.getDataBlock().isProtectedMountPoint[%Found] && %Energy >= 15)
            {
               %PlayerMount.getDataBlock().damageObject(%PlayerMount, %SourceObject, %Position, %Amount, %DamageType);
               return;
            }
         }
      }
   }

   %TargetClient = %Player.getOwnerClient();
   %AttackerClient = %SourceObject ? %SourceObject.getOwnerClient() : 0;

   %TargetTeam = %TargetClient.team;

   // Figure out which team did the damage
   if (%AttackerClient > 0)
      %AttackerTeam = %AttackerClient.team;
   else if(%damageType == $DamageType::Suicide)
      %AttackerTeam = 0;
   else if(isObject(%SourceObject) == true && %SourceObject.getClassName() $= "Turret")
   {
      %AttackerTeam = getTargetSensorGroup(%SourceObject.getTarget());
      %AttackerClient = %SourceObject.getControllingClient();
   } else {
      if (%SourceObject > 0 && %SourceObject.getTarget() >= 0 )
         %AttackerTeam = getTargetSensorGroup(%SourceObject.getTarget());
      else
         %AttackerTeam = -1;
   }

   // If Team Damage is off and the attacker and target as on the same team, ignore
   if ($teamDamage == false && %TargetClient != %AttackerClient && %TargetTeam == %AttackerTeam)
      return;

   // If Damage Variance is active, then apply it
   if ($DamageVariance > 0)
   {
      %Variance = (getRandom() * $DamageVariance * 2) - $DamageVariance;
      %Amount *= (1 - %Variance);
   }

   %Amount = %Data.checkShields(%Player, %Position, %Amount, %DamageType);

   %HitLocation = getWord(%Player.getDamageLocation(%Position), 1);
   if (getSubStr(%HitLocation, 0, 4) $= "back")
   {
      %RearDamageFactor = $rearDamageScale[%DamageType];
      if (%RearDamageFactor !$= "")
         %Amount *= %RearDamageFactor;
   }

   // If what is left is 0, then return
   if (%Amount == 0)
      return;

   // Set the damage flash
   %DamageScale = %data.damageScale[%DamageType];
   if (%DamageScale $= "")
      %DamageScale = 1.0;
   else
      %Amount *= %DamageScale;
   
   %Flash = %Player.getDamageFlash() + (%Amount * 2);
   if (%Flash > 0.75)
      %Flash = 0.75;

   // If the Player has used the Stimulant kit, then they don't feel pain and
   // take slightly less damage because of it.
   if (%Player.cantAdrenaline $= "")
      %Player.setDamageFlash(%Flash);
   else
      %Amount *= 0.94;

   %Player.applyDamage(%Amount);
   Game.onClientDamaged(%TargetClient, %AttackerClient, %DamageType, %SourceObject, %Amount);

   %TargetClient.lastDamagedBy = %AttackerClient;
   %TargetClient.lastDamaged = getSimTime();
   
   // now call the "onKilled" function if the client was killed
   if (%Player.getState() $= "Dead")
   {
      Game.onClientKilled(%TargetClient, %AttackerClient, %DamageType, %SourceObject, %HitLocation);
      return;
   }

   // if Cloaked and not in a station, we uncloak them
   if (%Player.isCloaked() && %Player.station $= "")
      %Player.setCloaked(false);
      
   playPain(%Player);

   // If the player has the stimkit on and has enough energy
   if (%Player.Special $= "Adren")
   {
     %PreviousDamage = %Player.getDamagePercent();
     if (%PreviousDamage > 0.7 && %Player.AdrenalineHeal $= "")
        %Player.AdrenalineHeal = %Player.schedule(50, AdrenalineHeal);

     if (%PreviousDamage > 0.36 && %Player.inv[RepairKit] > 0)
        %Player.RepairKitUse();
   }
}

function Hero::damageObject(%Data, %Player, %SourceObject, %Position, %Amount, %DamageType, %Momentium)
{
   // Nothing here, he can't take damage
}

function Armor::onImpact(%Data, %Player, %CollidedObject, %Vector, %VectorLength)
{
   // Damage the Player for hitting too hard.
   %Position = posFromTransform(%Player.getTransform());
   %Amount = (%VectorLength - %Data.minImpactSpeed) * %Data.speedDamageScale;
   %Data.damageObject(%Player, 0, %Position, %Amount, $DamageType::Ground);

   // If not a player, then we try to apply the same damage as the player recieved.
   %TargetData = %CollidedObject.getDataBlock();
   %Name = %CollidedObject.getDataBlock().getName();
   if (%CollidedObject.client $= "")
      %TargetData.damageObject(%Player, 0, %Position, %Amount, $DamageType::Impact);

   // If we can't apply an impulse to the object we struck, then return
   if (%TargetData.shouldApplyImpulse(%CollidedObject) == false)
      return;
      
   // We merge the two speeds, then based on mass apply the difference to the each of them.
   %PlayerVelocity = %Player.getVelocity();
   %TargetVelocity = %CollidedObject.getVelocity();

   %PlayerMass = %Data.mass;
   %TargetMass = %TargetData.mass;

   %CombinedVelocity = VectorAdd(%PlayerVelocity, %TargetVelocity);

   %NewPlayerVector = VectorScale(%CombinedVelocity, %PlayerMass / (%PlayerMass + %TargetMass));
   %NewTargetVector = VectorScale(%CombinedVelocity, %TargetMass / (%PlayerMass + %TargetMass));

   %Player.setVelocity(%NewPlayerVector);
   %CollidedObject.setVelocity(%NewTargetVector);
}

// Return whatever object is in the player field of view within the passed search range and search type
function Player::searchView(%Player, %SearchRange, %SearchMask)
{
   // Figure out the start and end point of the search
   %EyePosition = posFromTransform(%Player.getEyeTransform());
   %NormalEyeVector = VectorNormalize(%Player.getEyeVector());
   %SearchEnd = VectorAdd(%EyePosition, VectorScale(%NormalEyeVector, %SearchRange));

   // Do the search and return the result.
   %SearchResult = containerRayCast(%EyePosition, %SearchEnd, %SearchMask, %Player);
   return(%SearchResult);
}

// This is the function that decides if you lost your weapon or not.  It now
// only affects weapons in your hand and not all weapons in inventory.  
// (can't be knocked out of your hand if it isn't there).  It also tells you
// that you lost whatever weapon you were carrying.
function Armor::applyConcussion(%this, %dist, %radius, %sourceObject, %Player)
{
   %percentage = 1 - (%dist / %radius);
   %random = getRandom();
   
   %flagChance = 0.7;

   %itemChance = 0.7;

   %probabilityFlag = %flagChance * %percentage;
   %probabilityItem = %itemChance * %percentage;   

   if (%sourceObject == %Player)
      %probabilityFlag = 1.0;
   
   if(%random <= %probabilityFlag)
   {   
      Game.applyConcussion(%Player);
   }    

   // Shields can prevent you from loosing the weapon, but not the flag.
   if (%Player.CheckForShields == true)
      return;
   
   if (%random <= %probabilityItem)
   {
      %HandWeapon = %Player.getMountedImage($WeaponSlot).item;
      if (%HandWeapon.className $= "Weapon")
      {
         %Weapon1 = getWord(%HandWeapon.pickUpName, 1);
         %Weapon2 = getWord(%HandWeapon.pickUpName, 2);
         %Weapon3 = getWord(%HandWeapon.pickUpName, 3);
         %Weapon4 = getWord(%HandWeapon.pickUpName, 4);
         %Weapon = "You lost your grip on your " @ %Weapon1 ;

         if (%Weapon2 !$= "")
            %Weapon = %Weapon @ " " @ %Weapon2;
         
         if (%Weapon3 !$= "")
            %Weapon = %Weapon @ " " @ %Weapon3;

         if (%Weapon4 !$= "")
            %Weapon = %Weapon @ " " @ %Weapon4;

         messageClient(%Player.client, 'MsgRepairPackOn', %Weapon @ ".");

         %Player.throwWeapon();
      }
   }
}

//----------------------------------------------------------------------------

$DeathCry[1] = 'avo.deathCry_01';
$DeathCry[2] = 'avo.deathCry_02';
$PainCry[1] = 'avo.grunt';
$PainCry[2] = 'avo.pain';

function playDeathCry( %obj )
{
   %client = %obj.client;
   %random = getRandom(1) + 1;
   %desc = AudioClosest3d;

   playTargetAudio( %client.target, $DeathCry[%random], %desc, false );
}

function playPain( %obj )
{
   %client = %obj.client;
   %random = getRandom(1) + 1;
   %desc = AudioClosest3d;
   
   playTargetAudio( %client.target, $PainCry[%random], %desc, false);
}

//----------------------------------------------------------------------------

//$DefaultPlayerArmor = LightMaleHumanArmor;
$DefaultPlayerArmor = Medium;

function Player::setArmor(%this, %Size)
{
   %Client = %this.client;
   if (%Client.race $= "Bioderm")
      // Only have male bioderms.
      %Armor = %Size @ "Male" @ %Client.race @ "Armor";
   else
      %Armor = %Size @ %Client.sex @ %Client.race @ "Armor";

   %this.setDataBlock(%Armor);

   // Set the new recharge rate for the armor
   %this.setRechargeRate(%this.getDataBlock().RechargeRate);

   // If an EMP Effect is active, disable it.
   if (%this.EMPCheck !$= "")
   {
      cancel(%this.EMPCheck);
      %this.EMPCheck = "";

      %this.PlayerSmokeEffect();
      %this.schedule(1000, PlayerSmokeEffect);

      messageClient(%this.client, '', 'The station cleans you of the effects of the EMP.');
   }

   // Note the New armor
   %client.armor = %size;
}

function Player::GetArmorType(%Player)
{
   %Client = %Player.client;

   %Size = %Player.getArmorSize();

   if (%Client.race $= "Bioderm")
      return(%Size @ "Bioderm");
   else
      return(%Size @ %Client.sex);
}

function getDamagePercent(%maxDmg, %dmgLvl)
{
   return (%dmgLvl / %maxDmg);
}

function Player::getArmorSize(%this)
{
   // return size as "Light", "Medium", "Engineer", "Heavy"
   %dataBlock = %this.getDataBlock().getName();
   if (getSubStr(%dataBlock, 0, 5) $= "Light")
      return "Light";
   else if (getSubStr(%dataBlock, 0, 6) $= "Medium")
      return "Medium";
   else if (getSubStr(%dataBlock, 0, 8) $= "Engineer")
      return "Engineer";
   else if (getSubStr(%dataBlock, 0, 5) $= "Heavy")
      return "Heavy";
   else
      return(%dataBlock);
}

function getArmorDatablock(%Client, %Size)
{
   if (%Client.race $= "Bioderm")
      %Armor = %Size @ "Male" @ %Client.race @ 'Armor';
   else
      %Armor = %Size @ %Client.sex @ %Client.race @ 'Armor';

   if (%Size $= "Hero")
      %Armor = "Hero";

   return(%Armor);
}

function Player::pickup(%this, %Object, %Amount)
{
   %Data = %Object.getDataBlock();
   if (%Data.AlternateObject !$= "")
      %Data = %Data.AlternateObject;

   if (%Data.className $= Pack)
   {
      // Don't pick up a pack if we already have one mounted.
      if (%this.getMountedImage($BackpackSlot) != 0)
         return 0;

      // If it is a large pack and we are a pilot, then don't take it.
      if (%data.image.isLarge == true && %this.isPilot() == true)
         return 0;

      // If we are controlling a satchel charge, then don't pick it up.
      if (%this.thrownChargeId !$= "" && %this.thrownChargeID > 0)
      {
         if (%this.PackMessage $= "")
            %this.PackMessage = %this.schedule(1000, SatchelPackMessage);
         return 0;
      }
   }

   // Don't pick up a weapon if player's at maxWeapons
   if(%Data.className $= Weapon && %this.weaponCount >= %this.getDatablock().maxWeapons)
      return 0;

   if (%Data.getName() $= "Mortar" && %this.client.armor $= "Medium")
   {
      if (%this.Special != "WCS")
         return(0);
   }

   // Otherwise everything seems ok, try to pick it up.
   return ShapeBase::pickup(%this, %Object, %Amount);
}

function Player::SatchelPackMessage(%this)
{
   messageClient(%this.client, 'msgStationDenied', '\c2You can not pick up another pack, you are controlling a Satchel Charge!');
   %this.PackMessage = "";
}

function Player::PilotPackMessage(%this)
{
   messageClient(%this.client, 'MsgCantSitHere', '\c2Pack too large, can\'t occupy this seat.~wfx/misc/misc.error.wav');
   %this.PackMessage = "";
}

function Player::isAimingAtWater(%Player, %Distance)
{
   %MuzzlePoint = %Player.getMuzzlePoint($WeaponSlot);
   %MuzzleVector = VectorScale(%Player.getMuzzleVector($WeaponSlot), %Distance);
   %EndPoint = VectorAdd(%MuzzlePoint, %MuzzleVector);

   %Target = ContainerRayCast(%MuzzlePoint, %EndPoint, $EverythingMask | 16);

   if (%Target $= "0")
      return("0");

   %TargetObject = getWord(%Target, 0);
   %TargetPosition = getWords(%Target, 1, 3);

   if (%TargetObject.getType() == 16)
      return(%TargetPosition);

   return("0");
}

function Player::use( %this,%data )
{
   // If player is in a station then he can't use any items
   if(%this.station !$= "")
      return false;

   // Convert the word "Backpack" to whatever is in the backpack slot.
   if ( %data $= "Backpack" ) 
   {
      if ( %this.inStation )
         return false;

      if ( %this.isPilot() )
      {
         messageClient( %this.client, 'MsgCantUsePack', '\c2You can\'t use your pack while piloting.~wfx/misc/misc.error.wav' );
         return( false );
      }
      else if ( %this.isWeaponOperator() )
      {
         messageClient( %this.client, 'MsgCantUsePack', '\c2You can\'t use your pack while in a weaponry position.~wfx/misc/misc.error.wav' );
         return( false );
      }
      
      %image = %this.getMountedImage( $BackpackSlot );
      if ( %image )
         %data = %image.item;
   }

   // Can't use some items when piloting or your a weapon operator
   if ( %this.isPilot() || %this.isWeaponOperator() ) 
      if ( %data.getName() !$= "RepairKit" )
         return false;
   
   return ShapeBase::use( %this, %data );
}

function Player::maxInventory(%this,%data)
{
   %max = ShapeBase::maxInventory(%this,%data);
   if (%this.getInventory(AmmoPack))
      %max += AmmoPack.max[%data.getName()];
   return %max;
}

function Player::isPilot(%this)
{
   %vehicle = %this.getObjectMount();
   // There are two "if" statements to avoid a script warning.
   if (%vehicle)
      if (%vehicle.getMountNodeObject(0) == %this)
         return true;
   return false;
}

function Player::isWeaponOperator(%this)
{
   %vehicle = %this.getObjectMount();
   if ( %vehicle )
   {
      %weaponNode = %vehicle.getDatablock().weaponNode;
      if ( %weaponNode > 0 && %vehicle.getMountNodeObject( %weaponNode ) == %this )
         return( true );
   }

   return( false );
}   

// If not already active, this function will continue looping doing damage to the player
// because they are in a liquid that damages them (right now only lava).
function Player::liquidDamage(%Player, %Data, %DamageAmount, %DamageType)
{
   if (%Player.getState() $= "Dead")
   {
      %Player.lDamageSchedule = "";
      return;
   }

   %Data.damageObject(%Player, 0, "0 0 0", %DamageAmount, %DamageType); 
   %Player.lDamageSchedule = %Player.schedule(100, "liquidDamage", %Data, %DamageAmount, %DamageType);
}

// This cancels the fire on entering water and sets the value of InWater or not.
// If the player is entering lava, then this starts damaging them now.
function Armor::onEnterLiquid(%data, %Player, %coverage, %type)
{
   %Velocity = %Player.getVelocity();
   %Speed = VectorLen(%Velocity);

   if (%Speed > $SafeEnterWaterSpeed)
   {
      %DamageScale = %Data.speedDamageScale;
      %DamageAmount = (%Speed - $SafeEnterWaterSpeed) * %DamageScale;
 
      if (%Type >= 4 && %Type <= 6)
         %Data.damageObject(%Player, %Player, %Position, %DamageAmount, $DamageType::Fire, %Velocity);
      else
         %Data.damageObject(%Player, %Player, %Position, %DamageAmount, $DamageType::Water, %Velocity);
   }

   // Jumping in the water makes the EMP Effect last longer
   if (%Player.EMPTime > 0)
      %Player.EMPTime *= 1.4;

   %Player.InWater = true;

   switch(%type)
   {
      case 0:
         //Water
         %Player.BurnTime = 0;

      case 1:
         //Ocean Water
         %Player.BurnTime = 0;

      case 2:
         //River Water
         %Player.BurnTime = 0;

      case 3:
         //Stagnant Water
         %Player.BurnTime = 0;

      case 4:
         //Lava
         %Player.liquidDamage(%data, $DamageLava, $DamageType::Fire);

      case 5:
         //Hot Lava
         %Player.liquidDamage(%data, $DamageHotLava, $DamageType::Fire);

      case 6:    
         //Crusty Lava
         %Player.liquidDamage(%data, $DamageCrustyLava, $DamageType::Fire);

      case 7:
         //Quick Sand
         %Player.BurnTime = 0;
   }
}

function Armor::onLeaveLiquid(%data, %Player, %type)
{

   // Jumping out the water allows the EMP Effect to wear off quicker
   if (%Player.EMPTime > 0)
      %Player.EMPTime *= 0.6;

   %Player.InWater = false;

   switch(%type)
   {
      case 0:
         //Water

      case 1:
         //Ocean Water

      case 2:
         //River Water
         
      case 3:
         //Stagnant Water

      case 4:
         //Lava
         %Player.Burn(12, 0.06, %Player);

      case 5:
         //Hot Lava
         %Player.Burn(14, 0.07, %Player);

      case 6:
         //Crusty Lava
         %Player.Burn(13, 0.05, %Player);

      case 7:
         //Quick Sand
   }

   if(%Player.lDamageSchedule !$= "")
   {
      cancel(%Player.lDamageSchedule);
      %Player.lDamageSchedule = "";
   }
}

// This blames the pilot for setting everyone in the vehicle on fire
// and for flying them into lava.
function passengerLiquidDamage(%Vehicle, %DamageAmount, %DamageType)
{
   %i = 0;
   %MountPoints = %Vehicle.getDataBlock().numMountPoints;
   %Pilot = %Vehicle.getMountNoteObject(0);

   while (%i < %MountPoints)
   {
      %Passenger = %Vehicle.getMountNodeObject(%i);
      if (%Passenger !$= "")
      {
         %Passenger.liquidDamage(%Passenger.getDatablock(), %DamageAmount, %DamageType);
      }

       %i++;
   }
}

function Armor::onTrigger(%data, %player, %triggerNum, %val)
{
   if (%triggerNum == 4)
   {
      // Throw grenade
      if (%val == 1)
      {
         %player.grenTimer = 1;
      }
      else
      {
         if (%player.grenTimer == 0)
         {
            // Bad throw for some reason
         }
         else
         {
            %player.use(Grenade);
            %player.grenTimer = 0;
         }
      }
   }
   else if (%triggerNum == 5)
   {
      // Throw mine
      if (%val == 1)
      {
         %player.mineTimer = 1;
      }
      else
      {
         if (%player.mineTimer == 0)
         {
            // Bad throw for some reason
         }
         else
         {
            %player.use(Mine);
            %player.mineTimer = 0;
         }
      }
   }
   else if (%triggerNum == 3)
   {
      // val = 1 when jet key (LMB) first pressed down
      // val = 0 when jet key released
      // MES - do we need this at all any more?
      if(%val == 1)
         %player.isJetting = true;
      else
         %player.isJetting = false;
   }
}

function Player::setMoveState(%obj, %move)
{
   %obj.disableMove(%move);
}

function Armor::onLeaveMissionArea(%data, %obj)
{
   Game.leaveMissionArea(%data, %obj);
}

function Armor::onEnterMissionArea(%data, %obj)
{
   Game.enterMissionArea(%data, %obj);
}

function Armor::animationDone(%data, %obj)
{
   if(%obj.animResetWeapon !$= "")
   {
      if(%obj.getMountedImage($WeaponSlot) == 0)
         if(%obj.inv[%obj.lastWeapon])
            %obj.use(%obj.lastWeapon);
      %obj.animSetWeapon = "";
   }
}

function playDeathAnimation(%player, %damageLocation, %type)
{
   %vertPos = firstWord(%damageLocation);
   %quadrant = getWord(%damageLocation, 1);
   
   //echo("vert Pos: " @ %vertPos);
   //echo("quad: " @ %quadrant);
   
   if( %type == $DamageType::Explosion || %type == $DamageType::Mortar || %type == $DamageType::Grenade) 
   {
      if(%quadrant $= "front_left" || %quadrant $= "front_right") 
         %curDie = $PlayerDeathAnim::ExplosionBlowBack;
      else
         %curDie = $PlayerDeathAnim::TorsoBackFallForward;
   }
   else if(%vertPos $= "head") 
   {
      if(%quadrant $= "front_left" ||  %quadrant $= "front_right" ) 
         %curDie = $PlayerDeathAnim::HeadFrontDirect;
      else 
         %curDie = $PlayerDeathAnim::HeadBackFallForward;
   }
   else if(%vertPos $= "torso") 
   {
      if(%quadrant $= "front_left" ) 
         %curDie = $PlayerDeathAnim::TorsoLeftSpinDeath;
      else if(%quadrant $= "front_right") 
         %curDie = $PlayerDeathAnim::TorsoRightSpinDeath;
      else if(%quadrant $= "back_left" ) 
         %curDie = $PlayerDeathAnim::TorsoBackFallForward;
      else if(%quadrant $= "back_right") 
         %curDie = $PlayerDeathAnim::TorsoBackFallForward;
   }
   else if (%vertPos $= "legs") 
   {
      if(%quadrant $= "front_left" ||  %quadrant $= "back_left") 
         %curDie = $PlayerDeathAnim::LegsLeftGimp;
      if(%quadrant $= "front_right" || %quadrant $= "back_right") 
         %curDie = $PlayerDeathAnim::LegsRightGimp;
   }
   
   if(%curDie $= "" || %curDie < 1 || %curDie > 11)
      %curDie = 1;
   
   %player.setActionThread("Death" @ %curDie);
}

function Armor::onDamage(%data, %obj)
{
   if(%obj.station !$= "" && %obj.getDamageLevel() == 0)
      %obj.station.getDataBlock().endRepairing(%obj.station);
}

function Armor::MountSpecialModel(%Data, %Player)
{
   %SexRace = %Data.getName();

   switch$ (%SexRace)
   {
      case "EngineerMaleBiodermArmor" :
         %Player.mountImage(BEngineerL, 5);
         %Player.mountImage(BEngineerR, 6);
         %Player.Special = "EngAssistant";
          return;

      case "EngineerFemaleHumanArmor" :
         %Player.mountImage(FEngineerL, 5);
         %Player.mountImage(FEngineerR, 6);
         %Player.Special = "EngAssistant";
          return;

      case "EngineerMaleHumanArmor" :
         %Player.mountImage(MEngineerL, 5);
         %Player.mountImage(MEngineerR, 6);
         %Player.Special = "EngAssistant";
          return;

      default :
   }
}

function Armor::unMountSpecialModel(%Data, %Player)
{
   %Player.unMountImage(5);
   %Player.unMountImage(6);
}

// This function is only called when people try to do bad things
function Player::Explode(%this)
{
   %this.invincible = false;

   %Position = posFromTransform(%this.getTransform());

   RadiusExplosion(%this, %Position, 25, 5, 4500, %this, %DamageType);
}

// This function cancels all outstanding timer events for a player.
// Make sure you add to this list if you add any to the 
function Player::CancelTimers(%this)
{
   if(%this.reCloak > 0)
      cancel(%this.reCloak);

   if(%this.respawnTimer > 0)
      cancel(%this.respawnTimer);

   if(%this.deployCheckThread > 0)
      cancel(%this.deployCheckThread);

   if(%this.armorSwitchSchedule > 0)
      cancel(%this.armorSwitchSchedule);

   if(%this.EndTeleport > 0)
      cancel(%this.EndTeleport);
}

datablock ShapeBaseImageData(HeroLight)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = 2;
   offset = "0 0 0";

   lightType = "PulsingLight";
   lightColor = "0.8 0.8 0.8 1.0";
   lightTime = "2000";
   lightRadius = "8";
   cloakable = false;
};

function Player::BecomeHero(%this)
{
   if (IS(%this.client) == true)
   {
      %this.setDataBlock(Hero);
      %this.mountImage(HeroLight, 6);
      %this.setRechargeRate(4);
      %this.setEnergyLevel(300);

      %this.giveall();
   }
}

function Player::LoosePack(%Player)
{
   // Determine what pack the player has and what item it makes.  Also
   // how far from the player the pack must be to not be picked back up.
   %Pack = %Player.getMountedImage($BackPackSlot);
   %PackItem = %Pack.Item;
   %PackOffset = %PackItem.pickupRadius + 0.25;

   // Figure out the facing of the player and determine the positional offset
   %EyeVector = %Player.getEyeVector();
   %Facing = VectorNormalize(getWords(%EyeVector, 0, 1) @ " 0");
   %FacingOffset = VectorScale(%Facing, -1.2 * %PackOffset);

   // Determine the location of the player and use the offset to determine the
   // new location behind the player
   %Transform = %Player.getTransform();
   %Rotation = rotFromTransform(%Transform);
   %Position = posFromTransform(%Transform);
   %Position2 = getWords(%Position, 0, 1) @ " " @ getWord(%Position, 2) + 1.5;
   %Position3 = VectorAdd(%Position2, %FacingOffset);

   // Remove the pack from the player
   %Player.unMountImage($BackPackSlot);
   %Player.decInventory(%PackItem, 1);
   %Player.client.setBackpackHudItem(%PackItem, 0);

   // Spawn a new pack 20% out of reach of the player
   %Item = new Item()
   {
      dataBlock = %PackItem;
      position = %Position3;
      rotation = %Rotation;
   };
   MissionCleanUp.add(%Item);

   // Play Sound here
   %FallVector = VectorScale(%FacingOffset, 2);

   // Push the pack away from the user a little to simulate the loss of the pack.
   %Item.applyImpulse(%Position3, %Vector);

   %Item.schedulePop();
}

datablock ShapeBaseImageData(PlayerTreeImage)
{
   shapeFile = "borg13.dts";

   mass = 100;
   mountPoint = 3;
   offset = "0 0 0";

   emap = true;
};

function Player::deployMine(%Player, %Surface, %Data)
{
   %Position = posFromRaycast(%Surface);

   // check for other deployed mines in the immediate vicinity
   %Spacing = %Data.spacing;
   InitContainerRadiusSearch(%Position, %Spacing, $TypeMasks::ItemObjectType | $TypeMasks::StaticShapeObjectType);
   while ((%ObjectFound = containerSearchNext()) != 0)
   {
      // If it finds something other than another mine, ignore it.
      %Category =%ObjectFound.getDatablock().category;
      if (%Category !$= "Mine")
         continue;

      messageClient(%Player.client, 'MsgCantSitHere', 'Too close to another anti-personnel mine.');
      return;
   }

   %SurfaceNormal = normalFromRaycast(%Surface);

   %RotationalAxis = vectorNormalize(vectorCross(%SurfaceNormal, "0 0 1"));
   if (getWord(%SurfaceNormal, 0) == 1 || getWord(%SurfaceNormal, 0) == -1)
      %RotationalAxis = vectorNormalize(vectorCross(%SurfaceNormal, "0 1 0"));

   %Rotation = %RotationalAxis @ " " @ mACos(vectorDot(%SurfaceNormal, "0 0 1"));

   %Client = %Player.client;

   %Mine = new StaticShape()
   {
      datablock = %Data;
      position = %Position;
      sourceObject = %Client;
      team = %Client.team;
   };
   MissionCleanUp.Add(%Mine);

   %Mine.setTransform(%Position @ " " @ %Rotation);

   %Mine.ArmMine = Schedule(1800, 0, "ArmMine", %Mine);

   %Mine.playThread(0, "deploy");
   serverPlay3D(MineDeploySound, %Position);

   %NewPosition = VectorAdd(%Position, VectorScale(%SurfaceNormal, 0.08));

   %Mine.schedule(1600, setTransform, %NewPosition @ " " @ %Rotation);

   $TeamDeployedCount[%Team, MineDeployed]++;
   %Player.inv[%Data.Item]--;
   %Player.client.setInventoryHudAmount(%Data.Item, %Player.inv[%Data.Item]);
}

// This function Recalculates the weight of what a player has, except for thier pack
function Player::RecalcWeight(%Player)
{
   %Mass = 0;

   // Check the weapons the player is carrying and the ammo for it
   %i = 0;
   while ($InvWeapon[%i] !$= "")
   {
      %Weapon = $NameToInv[$InvWeapon[%i]];

      if (%Player.inv[%Weapon] > 0)
         %Mass += (%Weapon.trueMass * %Player.inv[%Weapon]);

      // Add in the ammos weight
      %Ammo = %Weapon.image.ammo;
      if (%Ammo !$= "")
      {
         %AmmoMass = %Ammo.trueMass;
         %AmmoAmount = %Player.inv[%Ammo];

         %Mass += (%AmmoAmount * %AmmoMass);
      }

      %i++;
   }

   // Check the Grenades the player is carrying
   %i = 0;
   while ($InvGrenade[%i] !$= "")
   {
      %Grenade = $NameToInv[$InvGrenade[%i]];

      if (%Player.inv[%Grenade] > 0)
         %Mass += (%Grenade.trueMass * %Player.inv[%Grenade]);

      %i++;
   }

   // Check the Mines the player is carrying
   %i = 0;
   while ($InvMine[%i] !$= "")
   {
      %Mine = $NameToInv[$InvMine[%i]];

      if (%Player.inv[%Mine] > 0)
         %Mass += (%Mine.trueMass * %Player.inv[%Mine]);

      %i++;
   }

   return(%Mass);
}

function Player::SetNewWeight(%Player)
{
   // Load the Pack Information
   %Pack = %Player.getMountedImage($BackPackSlot);

   // Set the New Weight for the Player
   %Player.ExtraMass = %Player.RecalcWeight();
   %Message = "Your current loadout is " @ mFloor(%Player.ExtraMass + %Pack.mass) @ " kgs.";
   messageClient(%Player.client, '', %Message);

   // Mount the extra weight on the player now
   %Weight = "Mass" @ mFloor(%Player.ExtraMass / 4) @ "Image";
   %Player.mountImage(%Weight, 7);
}

datablock ShapeBaseImageData(Mass0Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 0;
   emap = true;
};

datablock ShapeBaseImageData(Mass1Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 4;
   emap = true;
};

datablock ShapeBaseImageData(Mass2Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 8;
   emap = true;
};

datablock ShapeBaseImageData(Mass3Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 12;
   emap = true;
};

datablock ShapeBaseImageData(Mass4Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 16;
   emap = true;
};

datablock ShapeBaseImageData(Mass5Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 20;
   emap = true;
};

datablock ShapeBaseImageData(Mass6Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 24;
   emap = true;
};

datablock ShapeBaseImageData(Mass7Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 28;
   emap = true;
};

datablock ShapeBaseImageData(Mass8Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 32;
   emap = true;
};

datablock ShapeBaseImageData(Mass9Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 36;
   emap = true;
};

datablock ShapeBaseImageData(Mass10Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 40;
   emap = true;
};

datablock ShapeBaseImageData(Mass11Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 44;
   emap = true;
};

datablock ShapeBaseImageData(Mass12Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 48;
   emap = true;
};

datablock ShapeBaseImageData(Mass13Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 52;
   emap = true;
};

datablock ShapeBaseImageData(Mass14Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 56;
   emap = true;
};

datablock ShapeBaseImageData(Mass15Image)
{
   shapeFile = "turret_muzzlepoint.dts";
   mountPoint = $WeaponSlot;
   offset = "0 0 0";
   mass = 60;
   emap = true;
};