--------------------------------------------------------------------------------------------
Long Range Artillery Tutorial
--------------------------------------------------------------------------------------------
This tutorial creates a tank type vehicle with a dual chaingun turret. It also has two stationary cannons pointing up in the air. When the targeting laser is used between 250 and 750 meters away, the vehicle auto fires the cannons at the spot being lazed. It becomes a little less accurate when firing at max distance. This one could probably stand to be toned down a little for balancing purposes, but I'll leave that up to you.
Step #1
// ------------------------------------------
// Station.cs
// ------------------------------------------
In function StationVehiclePad::onAdd, add this:

   if(%obj.Artillery !$= "Removed")
   	%sv.vehicle[Artillery] = true;


Step #2
// ------------------------------------------
// ServerVehicleHud.cs
// ------------------------------------------
In function VehicleHud::updateHud, add this:

   if ( %station.vehicle[Artillery] )
   {
      messageClient( %client, 'SetLineHud', "", %tag, %count, "LONG RANGE ARTILLERY", "", Artillery, $VehicleMax[Artillery] - $VehicleTotalCount[%team, Artillery] );
      %count++;
   }


Step #3
// ------------------------------------------
// Vehicle.cs
// ------------------------------------------
3a)Add this line at the appropriate spot:

$VehicleMax[Artillery] = 2;


3b) In function clearVehicleCount, add this:

   $VehicleTotalCount[%team, Artillery]         = 0;


Step #4
// ------------------------------------------
// Server.cs
// ------------------------------------------
In function CreateServer, above this line:

   exec("scripts/vehicles/vehicle.cs");

Add this:

   exec("scripts/vehicles/vehicle_artillery.cs");


Step #5
// ------------------------------------------
// Projectiles.cs
// ------------------------------------------
Add this to the bottom of function TargetingLaserImage::onFire:

   %obj.posLaze = 1;

Next below that function, add this function:

function TargetingLaserImage::deconstruct(%data, %obj, %slot)
{
   %obj.posLaze = 0;
   Parent::deconstruct(%data, %obj, %slot);
}


Step #6
// ------------------------------------------
// vehicle_artillery.cs
// ------------------------------------------
Create a file called vehicle_artillery.cs in your vehicle's directory. Add all this into it.


//**************************************************************
// Long Range Artillery
//**************************************************************
//**************************************************************
// SOUNDS
//**************************************************************

datablock AudioProfile(ArtillerySkid)
{
   filename    = "fx/vehicles/tank_skid.wav";
   description = ClosestLooping3d;
   preload = true;
};

datablock AudioProfile(ArtilleryEngineSound)
{
   filename    = "fx/vehicles/tank_engine.wav";
   description = AudioDefaultLooping3d;
   preload = true;
};

datablock AudioProfile(ArtilleryThrustSound)
{
   filename    = "fx/vehicles/tank_boost.wav";
   description = AudioDefaultLooping3d;
   preload = true;
};

datablock AudioProfile(ArtilleryChaingunFireSound)
{
   filename    = "fx/vehicles/tank_chaingun.wav";
   description = AudioDefaultLooping3d;
   preload = true;
};

datablock AudioProfile(ArtilleryChaingunReloadSound)
{
   filename    = "fx/weapons/chaingun_dryfire.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(TankChaingunProjectile)
{
   filename    = "fx/weapons/chaingun_projectile.wav";
   description = ProjectileLooping3d;
   preload = true;
};

datablock AudioProfile(ArtilleryTurretActivateSound)
{
    filename    = "fx/vehicles/tank_activate.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ArtilleryChaingunDryFireSound)
{
   filename    = "fx/weapons/chaingun_dryfire.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ArtilleryChaingunIdleSound)
{
   filename    = "fx/misc/diagnostic_on.wav";
   description = ClosestLooping3d;
   preload = true;
};

datablock AudioProfile(ArtilleryMortarDryFireSound)
{
   filename    = "fx/weapons/mortar_dryfire.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ArtilleryMortarFireSound)
{
   filename    = "fx/vehicles/tank_mortar_fire.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ArtilleryMortarReloadSound)
{
   filename    = "fx/weapons/mortar_reload.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(ArtilleryMortarIdleSound)
{
   filename    = "fx/misc/diagnostic_on.wav";
   description = ClosestLooping3d;
   preload = true;
};

//**************************************************************
// LIGHTS
//**************************************************************
datablock RunningLightData(TankLight1)
{
   radius = 1.5;
   color = "1.0 1.0 1.0 0.2";
   nodeName = "Headlight_node01";
   direction = "0.0 1.0 0.0";
   texture = "special/headlight4";
};

datablock RunningLightData(TankLight2)
{
   radius = 1.5;
   color = "1.0 1.0 1.0 0.2";
   nodeName = "Headlight_node02";
   direction = "0.0 1.0 0.0";
   texture = "special/headlight4";
};

datablock RunningLightData(TankLight3)
{
   radius = 1.5;
   color = "1.0 1.0 1.0 0.2";
   nodeName = "Headlight_node03";
   direction = "0.0 1.0 0.0";
   texture = "special/headlight4";
};

datablock RunningLightData(TankLight4)
{
   radius = 1.5;
   color = "1.0 1.0 1.0 0.2";
   nodeName = "Headlight_node04";
   direction = "0.0 1.0 0.0";
   texture = "special/headlight4";
};

//**************************************************************
// VEHICLE CHARACTERISTICS
//**************************************************************

datablock HoverVehicleData(Artillery) : TankDamageProfile
{
   spawnOffset = "0 0 4";

   floatingGravMag = 4.5;

   catagory = "Vehicles";
   shapeFile = "vehicle_grav_tank.dts";
   multipassenger = true;
   computeCRC = true;
   renderWhenDestroyed = false;

   weaponNode = 1;

   debrisShapeName = "vehicle_land_assault_debris.dts";
   debris = ShapeDebris;

   drag = 0.0;
   density = 0.9;

   mountPose[0] = sitting;
   mountPose[1] = sitting;
   numMountPoints = 2;
   isProtectedMountPoint[0] = true;
   isProtectedMountPoint[1] = true;

   cameraMaxDist = 20;
   cameraOffset = 3;
   cameraLag = 1.5;
   explosion = LargeGroundVehicleExplosion2;
   explosionDamage = 0.5;
   explosionRadius = 5.0;

   maxSteeringAngle = 0.5;  // 20 deg.

   maxDamage = 1.575;
   destroyedLevel = 1.575;

   isShielded = true;
   rechargeRate = 1.0;
   energyPerDamagePoint = 300;
   maxEnergy = 400;
   minJetEnergy = 15;
   jetEnergyDrain = 2.0;

   // Rigid Body
   mass = 4000;
   bodyFriction = 0.8;
   bodyRestitution = 0.5;
   minRollSpeed = 3;
   gyroForce = 400;
   gyroDamping = 0.3;
   stabilizerForce = 20;
   minDrag = 10;
   softImpactSpeed = 15;       // Play SoftImpact Sound
   hardImpactSpeed = 18;      // Play HardImpact Sound

   // Ground Impact Damage (uses DamageType::Ground)
   minImpactSpeed = 17;
   speedDamageScale = 0.060;

   // Object Impact Damage (uses DamageType::Impact)
   collDamageThresholdVel = 18;
   collDamageMultiplier   = 0.045;

   dragForce            = 40 / 20;
   vertFactor           = 0.0;
   floatingThrustFactor = 0.15;

   mainThrustForce    = 50;
   reverseThrustForce = 40;
   strafeThrustForce  = 40;
   turboFactor        = 1.7;

   brakingForce = 25;
   brakingActivationSpeed = 4;

   stabLenMin = 3.25;
   stabLenMax = 4;
   stabSpringConstant  = 50;
   stabDampingConstant = 20;

   gyroDrag = 20;
   normalForce = 20;
   restorativeForce = 10;
   steeringForce = 15;
   rollForce  = 5;
   pitchForce = 3;

   dustEmitter = TankDustEmitter;
   triggerDustHeight = 3.5;
   dustHeight = 1.0;
   dustTrailEmitter = TireEmitter;
   dustTrailOffset = "0.0 -1.0 0.5";
   triggerTrailHeight = 3.6;
   dustTrailFreqMod = 15.0;

   jetSound         = ArtilleryThrustSound;
   engineSound      = ArtilleryEngineSound;
   floatSound       = ArtillerySkid;
   softImpactSound  = GravSoftImpactSound;
   hardImpactSound  = HardImpactSound;
   wheelImpactSound = WheelImpactSound;

   forwardJetEmitter = TankJetEmitter;

   //
   softSplashSoundVelocity = 5.0;
   mediumSplashSoundVelocity = 10.0;
   hardSplashSoundVelocity = 15.0;
   exitSplashSoundVelocity = 10.0;

   exitingWater      = VehicleExitWaterMediumSound;
   impactWaterEasy   = VehicleImpactWaterSoftSound;
   impactWaterMedium = VehicleImpactWaterMediumSound;
   impactWaterHard   = VehicleImpactWaterMediumSound;
   waterWakeSound    = VehicleWakeMediumSplashSound;

   minMountDist = 4;

   damageEmitter[0] = SmallLightDamageSmoke;
   damageEmitter[1] = SmallHeavyDamageSmoke;
   damageEmitter[2] = DamageBubbles;
   damageEmitterOffset[0] = "0.0 -1.5 3.5 ";
   damageLevelTolerance[0] = 0.3;
   damageLevelTolerance[1] = 0.7;
   numDmgEmitterAreas = 1;

   splashEmitter[0] = VehicleFoamDropletsEmitter;
   splashEmitter[1] = VehicleFoamEmitter;

   shieldImpact = VehicleShieldImpact;

   cmdCategory = "Tactical";
   cmdIcon = CMDGroundTankIcon;
   cmdMiniIconName = "commander/MiniIcons/com_tank_grey";
   targetNameTag = 'Beowulf';
   targetTypeTag = 'Long Range Artillery';
   sensorData = VehiclePulseSensor;

   checkRadius = 5.5535;
   observeParameters = "1 10 10";
   runningLight[0] = TankLight1;
   runningLight[1] = TankLight2;
   runningLight[2] = TankLight3;
   runningLight[3] = TankLight4;
   shieldEffectScale = "0.9 1.0 0.6";
   showPilotInfo = 1;
};

//**************************************************************
// WEAPONS
//**************************************************************

//-------------------------------------
// Artillery CHAINGUN (projectile)
//-------------------------------------

datablock TracerProjectileData(ArtilleryChaingunBullet)
{
   doDynamicClientHits = true;

   projectileShapeName = "";
   directDamage        = 0.16;
   directDamageType    = $DamageType::TankChaingun;
   hasDamageRadius     = false;
   splash			   = ChaingunSplash;

   kickbackstrength    = 0.0;
   sound          	   = TankChaingunProjectile;

   dryVelocity       = 425.0;
   wetVelocity       = 100.0;
   velInheritFactor  = 1.0;
   fizzleTimeMS      = 3000;
   lifetimeMS        = 3000;
   explodeOnDeath    = false;
   reflectOnWaterImpactAngle = 0.0;
   explodeOnWaterImpact      = false;
   deflectionOnWaterImpact   = 0.0;
   fizzleUnderwaterMS        = 3000;

   tracerLength    = 15.0;
   tracerAlpha     = false;
   tracerMinPixels = 6;
   tracerColor     = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75";
	tracerTex[0]  	 = "special/tracer00";
	tracerTex[1]  	 = "special/tracercross";
	tracerWidth     = 0.10;
   crossSize       = 0.20;
   crossViewAng    = 0.990;
   renderCross     = true;

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

   activateDelayMS   = 100;

   explosion = ChaingunExplosion;
};

//-------------------------------------
// Artillery CHAINGUN CHARACTERISTICS
//-------------------------------------

datablock TurretData(ArtilleryPlasmaTurret) : TurretDamageProfile
{
   className      = VehicleTurret;
   catagory       = "Turrets";
   shapeFile      = "Turret_tank_base.dts";
   preload        = true;

   mass           = 1.0;  // Not really relevant

   maxEnergy               = 1;
   maxDamage               = Artillery.maxDamage;
   destroyedLevel          = Artillery.destroyedLevel;
   repairRate              = 0;

   // capacitor
   maxCapacitorEnergy      = 250;
   capacitorRechargeRate   = 1.0;

   thetaMin = 0;
   thetaMax = 100;

   inheritEnergyFromMount = true;
   firstPersonOnly = true;
   useEyePoint = true;
   numWeapons = 1;

   cameraDefaultFov = 90.0;
   cameraMinFov = 5.0;
   cameraMaxFov = 120.0;

   targetNameTag = 'Artillery Chaingun';
   targetTypeTag = 'Turret';
};

datablock TurretImageData(ArtilleryTurretParam)
{
   mountPoint = 2;
   shapeFile = "turret_muzzlepoint.dts";

   projectile = ArtilleryChaingunBullet;
   projectileType = TracerProjectile;

   useCapacitor = true;
   usesEnergy = true;

   // Turret parameters
   activationMS      = 1000;
   deactivateDelayMS = 1500;
   thinkTimeMS       = 200;
   degPerSecTheta    = 500;
   degPerSecPhi      = 500;

   attackRadius      = 75;
};

datablock TurretImageData(ArtilleryPlasmaTurretBarrel)
{
   shapeFile = "turret_tank_barrelchain.dts";
   mountPoint = 1;

   projectile = ArtilleryChaingunBullet;
   projectileType = TracerProjectile;

   casing              = ShellDebris;
   shellExitDir        = "1.0 0.3 1.0";
   shellExitOffset     = "0.15 -0.56 -0.1";
   shellExitVariance   = 15.0;
   shellVelocity       = 3.0;

   projectileSpread = 12.0 / 1000.0;

   useCapacitor = true;
   usesEnergy = true;
   useMountEnergy = true;
   fireEnergy = 3.75;
   minEnergy = 15.0;

   // Turret parameters
   activationMS      = 4000;
   deactivateDelayMS = 500;
   thinkTimeMS       = 200;
   degPerSecTheta    = 360;
   degPerSecPhi      = 360;
   attackRadius      = 75;

   // State transitions
   stateName[0]                        = "Activate";
   stateTransitionOnNotLoaded[0]       = "Dead";
   stateTransitionOnLoaded[0]          = "ActivateReady";
   stateSound[0]                       = ArtilleryTurretActivateSound;

   stateName[1]                        = "ActivateReady";
   stateSequence[1]                    = "Activate";
   stateSound[1]                       = ArtilleryTurretActivateSound;
   stateTimeoutValue[1]                = 1;
   stateTransitionOnTimeout[1]         = "Ready";
   stateTransitionOnNotLoaded[1]       = "Deactivate";

   stateName[2]                        = "Ready";
   stateTransitionOnNotLoaded[2]       = "Deactivate";
   stateTransitionOnTriggerDown[2]     = "Fire";
   stateTransitionOnNoAmmo[2]          = "NoAmmo";

   stateName[3]                        = "Fire";
   stateSequence[3]                    = "Fire";
   stateSequenceRandomFlash[3]         = true;
   stateFire[3]                        = true;
   stateAllowImageChange[3]            = false;
   stateSound[3]                       = ArtilleryChaingunFireSound;
   stateScript[3]                      = "onFire";
   stateTimeoutValue[3]                = 0.1;
   stateTransitionOnTimeout[3]         = "Fire";
   stateTransitionOnTriggerUp[3]       = "Reload";
   stateTransitionOnNoAmmo[3]          = "noAmmo";

   stateName[4]                        = "Reload";
   stateSequence[4]                    = "Reload";
   stateTimeoutValue[4]                = 0.1;
   stateAllowImageChange[4]            = false;
   stateTransitionOnTimeout[4]         = "Ready";
   stateTransitionOnNoAmmo[4]          = "NoAmmo";
   stateWaitForTimeout[4]              = true;

   stateName[5]                        = "Deactivate";
   stateSequence[5]                    = "Activate";
   stateDirection[5]                   = false;
   stateTimeoutValue[5]                = 30;
   stateTransitionOnTimeout[5]         = "ActivateReady";

   stateName[6]                        = "Dead";
   stateTransitionOnLoaded[6]          = "ActivateReady";
   stateTransitionOnTriggerDown[6]     = "DryFire";

   stateName[7]                        = "DryFire";
   stateSound[7]                       = ArtilleryChaingunDryFireSound;
   stateTimeoutValue[7]                = 0.5;
   stateTransitionOnTimeout[7]         = "NoAmmo";

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

datablock TurretImageData(ArtilleryPlasmaTurretBarrel2) : ArtilleryPlasmaTurretBarrel
{
   mountPoint = 0;
};

datablock ShapeBaseImageData(ArtilleryCannonTurret)
{
   className = WeaponImage;
   shapeFile = "turret_tank_barrelmortar.dts";
   mountPoint = 3;
   offset = "2 -2.5 1.5";
   rotation = "-1 0 0 80";
   activationMS      = 1000;
   deactivateDelayMS = 1500;
   thinkTimeMS       = 200;
   degPerSecTheta    = 500;
   degPerSecPhi      = 500;
   attackRadius      = 500;
};

datablock ShapeBaseImageData(ArtilleryCannonTurret2)
{
   className = WeaponImage;
   shapeFile = "turret_tank_barrelmortar.dts";
   mountPoint = 3;
   offset = "-2 -2.5 1.5";
   rotation = "-1 0 0 80";
   activationMS      = 1000;
   deactivateDelayMS = 1500;
   thinkTimeMS       = 200;
   degPerSecTheta    = 500;
   degPerSecPhi      = 500;
   attackRadius      = 500;
};

function Artillery::onAdd(%this, %obj)
{
   Parent::onAdd(%this, %obj);
   %turret = TurretData::create(ArtilleryPlasmaTurret);
   %turret.selectedWeapon = 1;
   MissionCleanup.add(%turret);
   %turret.team = %obj.teamBought;
   %turret.setSelfPowered();
   %obj.mountObject(%turret, 10);
   %turret.setCapacitorRechargeRate( %turret.getDataBlock().capacitorRechargeRate );
   %obj.turretObject = %turret;
   %turret.setAutoFire(false);
   %turret.mountImage(ArtilleryPlasmaTurretBarrel, 2);
   %turret.mountImage(ArtilleryPlasmaTurretBarrel2, 4);
   %turret.mountImage(AssaultTurretParam, 0);
   %obj.schedule(6000, "playThread", $ActivateThread, "activate");
   setTargetSensorGroup(%turret.getTarget(), %turret.team);
   setTargetNeverVisMask(%turret.getTarget(), 0xffffffff);

   %obj.mountImage(ArtilleryCannonTurret, 3);
   %obj.mountImage(ArtilleryCannonTurret2, 4);
   schedule(6100, 0, "ArtilleryLookForTarget", %obj);
}

function Artillery::deleteAllMounted(%data, %obj)
{
   %turret = %obj.getMountNodeObject(10);
   if (%turret)
   {
      if(%client = %turret.getControllingClient())
      {
         %client.player.setControlObject(%client.player);
         %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot);
         %client.player.mountVehicle = false;
      }
      %turret.delete();
   }
   %turret = %obj.getMountNodeObject(10);
   if(%turret)
      %turret.delete();
}

function Artillery::playerMounted(%data, %obj, %player, %node)
{
   if(%node == 0)
      commandToClient(%player.client, 'setHudMode', 'Pilot', "Assault", %node);
   else if(%node == 1)
   {
      %turret = %obj.getMountNodeObject(10);
      %player.vehicleTurret = %turret;
      %player.setTransform("0 0 0 0 0 1 0");
      %player.lastWeapon = %player.getMountedImage($WeaponSlot);
      %player.unmountImage($WeaponSlot);
      if(!%player.client.isAIControlled())
      {
         %player.setControlObject(%turret);
         %player.client.setObjectActiveImage(%turret, 2);
      }
      %turret.turreteer = %player;
      $aWeaponActive = 0;
      commandToClient(%player.client,'SetWeaponryVehicleKeys', true);
      %obj.getMountNodeObject(10).selectedWeapon = 1;
	   commandToClient(%player.client, 'setHudMode', 'Pilot', "Assault", %node);
   }
   if( %player.client.observeCount > 0 )
      resetObserveFollow( %player.client, false );
   %passString = buildPassengerString(%obj);
	for(%i = 0; %i < %data.numMountPoints; %i++)
		if(%obj.getMountNodeObject(%i) > 0)
		   commandToClient(%obj.getMountNodeObject(%i).client, 'checkPassengers', %passString);
}

function ArtilleryPlasmaTurret::onDamage(%data, %obj)
{
   %newDamageVal = %obj.getDamageLevel();
   if(%obj.lastDamageVal !$= "")
      if(isObject(%obj.getObjectMount()) && %obj.lastDamageVal > %newDamageVal)
         %obj.getObjectMount().setDamageLevel(%newDamageVal);
   %obj.lastDamageVal = %newDamageVal;
}

function ArtilleryPlasmaTurret::damageObject(%this, %targetObject, %sourceObject, %position, %amount, %damageType ,%vec, %client, %projectile)
{
   %vehicle = %targetObject.getObjectMount();
   if(%vehicle)
      %vehicle.getDataBlock().damageObject(%vehicle, %sourceObject, %position, %amount, %damageType, %vec, %client, %projectile);
}

function ArtilleryPlasmaTurret::onTrigger(%data, %obj, %trigger, %state)
{
   switch (%trigger)
   {
      case 0:
         %obj.fireTrigger = %state;
         if(%state)
         {
            %obj.setImageTrigger(2, true);
            %obj.setImageTrigger(4, true);
         }
         else
         {
            %obj.setImageTrigger(2, false);
            %obj.setImageTrigger(4, false);
         }
      case 2:
         if(%state)
            %obj.getDataBlock().playerDismount(%obj);
   }
}

function ArtilleryPlasmaTurret::playerDismount(%data, %obj)
{
   %obj.fireTrigger = 0;
   %obj.setImageTrigger(2, false);
   %obj.setImageTrigger(4, false);
   %client = %obj.getControllingClient();
   %client.player.mountImage(%client.player.lastWeapon, $WeaponSlot);
   %client.player.mountVehicle = false;
   setTargetSensorGroup(%obj.getTarget(), 0);
   setTargetNeverVisMask(%obj.getTarget(), 0xffffffff);
}

function ArtilleryCannonTurret::onMount(%this, %obj, %slot)
{
}

function ArtilleryCannonTurret::onUnmount(%this, %obj, %slot)
{
}

function ArtilleryCannonTurret2::onMount(%this, %obj, %slot)
{
}

function ArtilleryCannonTurret2::onUnmount(%this, %obj, %slot)
{
}

function ArtilleryLookForTarget(%obj)
{
   if (isObject(%obj))
   {
      if (%obj.lastcannon == 3)
         %obj.lastcannon = 4;
      else
         %obj.lastcannon = 3;
      %pos = %obj.getMuzzlePoint(%obj.lastcannon);
      %vec = %obj.getMuzzleVector(%obj.lastcannon);
      %count = ClientGroup.getCount();
      %mainDist = 760;
      %targetPos = "";
      %damageMasks = $TypeMasks::PlayerObjectType | $TypeMasks::VehicleObjectType |
                     $TypeMasks::StationObjectType | $TypeMasks::GeneratorObjectType |
                     $TypeMasks::SensorObjectType | $TypeMasks::TurretObjectType |
                     $TypeMasks::InteriorObjectType | $TypeMasks::TerrainObjectType;
      for (%i=0;%i<%count;%i++)
      {
         %obj2 = ClientGroup.getObject(%i);
         %player = %obj2.player;
         if (%player)
         {
            if ((%player.team == %obj.team) && (%player.posLaze))
            {
               %muzzlePos = %player.getMuzzlePoint($WeaponSlot);
               %muzzleVec = %player.getMuzzleVector($WeaponSlot);
               %endPos    = VectorAdd(%muzzlePos, VectorScale(%muzzleVec, 1000));
               %hit = ContainerRayCast(%muzzlePos, %endPos, %damageMasks, %player);
               if (%hit)
                  %pos2 = getWords(%hit, 1, 3);
               %dist = VectorDist(%pos, %pos2);
               if ((%dist > 250) && (%dist < 750) && (%dist < %mainDist))
               {
                  %targetPos = %pos2;
                  %mainDist = %dist;
               }
            }
         }
      }
      if (%targetPos)
      {
         %p = new GrenadeProjectile() {
            dataBlock        = ArtilleryShot;
            initialDirection = %vec;
            initialPosition  = %pos;
            sourceObject     = %obj.lastpilot;
            sourceSlot       = %obj.lastcannon;
            vehicleObject    = %obj;
         };
         MissionCleanup.add(%p);
         schedule(2000, 0, ArtilleryShotDrop, %p, %pos, %targetPos);
      }
      schedule (5000, 0, ArtilleryLookForTarget, %obj);
   }
}

function ArtilleryShotDrop(%b, %pos, %pos2)
{
   if (isObject(%b))
   {
      %dist = VectorDist(%pos, %pos2);
      %accuracy = %dist / 100;
      %b.schedule(50, "delete");
      %pos3 = VectorAdd(%pos2, "0 0 500");
      %vec = "0 0 -1";
      %x = (getRandom() - 0.5) * 2 * 3.1415926 * %accuracy / 1000;
      %y = (getRandom() - 0.5) * 2 * 3.1415926 * %accuracy / 1000;
      %z = (getRandom() - 0.5) * 2 * 3.1415926 * %accuracy / 1000;
      %mat = MatrixCreateFromEuler(%x @ " " @ %y @ " " @ %z);
      %vec = MatrixMulVector(%mat, %vec);
      %p = new GrenadeProjectile() {
         dataBlock        = ArtilleryShot;
         initialDirection = %vec;
         initialPosition  = %pos3;
         sourceObject     = %b.sourceObject;
         sourceSlot       = %b.sourceSlot;
         vehicleObject    = %b.vehicleObject;
      };
      MissionCleanup.add(%p);
   }
}

datablock GrenadeProjectileData(ArtilleryShot)
{
   projectileShapeName = "mortar_projectile.dts";
   emitterDelay        = -1;
   directDamage        = 0.0;
   hasDamageRadius     = true;
   indirectDamage      = 1.0;
   damageRadius        = 25.0;
   radiusDamageType    = $DamageType::Mortar;
   kickBackStrength    = 2500;
   scale = "2 2 2";
   explosion           = "MortarExplosion";
   underwaterExplosion = "UnderwaterMortarExplosion";
   velInheritFactor    = 0.5;
   splash              = MortarSplash;
   depthTolerance      = 10.0; // depth at which it uses underwater explosion
   baseEmitter         = MortarSmokeEmitter;
   bubbleEmitter       = MortarBubbleEmitter;
   grenadeElasticity = 0.15;
   grenadeFriction   = 0.4;
   armingDelayMS     = 10;
   muzzleVelocity    = 300;
   drag              = 0.01;
   sound			 = MortarProjectileSound;
   hasLight    = true;
   lightRadius = 4;
   lightColor  = "0.05 0.2 0.05";
   hasLightUnderwaterColor = true;
   underWaterLightColor = "0.05 0.075 0.2";
};