//**************************************************************
// JERICHO FORWARD BASE (Mobile Point Base)
//**************************************************************
$VehicleMax[MobileBaseVehicle] = 1;
//**************************************************************
// SOUNDS
//**************************************************************
datablock EffectProfile(MPBEngineEffect)
{
   effectname = "vehicles/mpb_thrust";
   minDistance = 5.0;
   maxDistance = 10.0;
};

datablock EffectProfile(MPBThrustEffect)
{
   effectname = "vehicles/mpb_boost";
   minDistance = 5.0;
   maxDistance = 10.0;
};

datablock AudioProfile(MPBEngineSound)
{
   filename    = "fx/vehicles/mpb_thrust.wav";
   description = AudioDefaultLooping3d;
   preload = true;
   effect = MPBEngineEffect;
};

datablock AudioProfile(MPBThrustSound)
{
   filename    = "fx/vehicles/mpb_boost.wav";
   description = AudioDefaultLooping3d;
   preload = true;
   effect = MPBThrustEffect;
};

datablock AudioProfile(MobileBaseDeploySound)
{
   filename    = "fx/vehicles/MPB_deploy.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(MobileBaseUndeploySound)
{
   filename    = "fx/vehicles/MPB_undeploy_turret.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(MobileBaseTurretDeploySound)
{
   filename    = "fx/vehicles/MPB_deploy_turret.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(MobileBaseTurretUndeploySound)
{
   filename    = "fx/vehicles/MPB_undeploy_turret.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(MobileBaseStationDeploySound)
{
   filename    = "fx/vehicles/MPB_deploy_station.wav";
   description = AudioClose3d;
   preload = true;
};

datablock AudioProfile(MobileBaseStationUndeploySound)
{
   filename    = "fx/vehicles/MPB_close_lid.wav";
   description = AudioClose3d;
   preload = true;
};


//**************************************************************
// LIGHTS
//**************************************************************
datablock RunningLightData(MPBLight1)
{
   pointSize = 3.0;
   pointColor = "1.0 1.0 1.0 0.3";
   pointNodeName = "Headlight_node01";
   texture = "special/expFlare";
};

datablock RunningLightData(MPBLight2)
{
   pointSize = 3.0;
   pointColor = "1.0 1.0 1.0 0.3";
   pointNodeName = "Headlight_node02";
   texture = "special/expFlare";
};


//**************************************************************
// VEHICLE CHARACTERISTICS
//**************************************************************
datablock SensorData(MPBDeployedSensor) : VehiclePulseSensor
{
   jams = true;
   jamsOnlyGroup = true;
   jamsUsingLOS = false;
   jamRadius = 50;
};

datablock WheeledVehicleData(MobileBaseVehicle) : MPBDamageProfile
{
   spawnOffset = "0 0 1.0";
   renderWhenDestroyed = false;
   canControl = true;
   catagory = "Vehicles";
   shapeFile = "vehicle_land_mpbase.dts";
   multipassenger = false;
   computeCRC = true;

   debrisShapeName = "vehicle_land_mpbase_debris.dts";
   debris = ShapeDebris;

   drag = 0.0;
   density = 20.0;

   mountPose[0] = sitting;
   numMountPoints = 1;
   isProtectedMountPoint[0] = true;

   cantAbandon = 1;
   cantTeamSwitch = 1;

   cameraMaxDist = 20;
   cameraOffset = 6;
   cameraLag = 1.5;
   explosion = LargeGroundVehicleExplosion;
   explosionDamage = 0.5;
   explosionRadius = 5.0;

   maxSteeringAngle = 0.3;  // 20 deg.

   // Used to test if the station can deploy
   stationPoints[1] = "-2.3 -7.38703 -0.65";
   stationPoints[2] = "-2.3 -11.8 -0.65";
   stationPoints[3] = "0 -7.38703 -0.65";
   stationPoints[4] = "0 -11.8 -0.65";
   stationPoints[5] = "2.3 -7.38703 -0.65";
   stationPoints[6] = "2.3 -11.8 -0.65";

   // Rigid Body
   mass = 2000;
   bodyFriction = 0.8;
   bodyRestitution = 0.5;
   minRollSpeed = 3;
   gyroForce = 400;
   gyroDamping = 0.3;
   stabilizerForce = 10;
   minDrag = 10;
   softImpactSpeed = 15;       // Play SoftImpact Sound
   hardImpactSpeed = 25;      // Play HardImpact Sound

   // Ground Impact Damage (uses DamageType::Ground)
   minImpactSpeed = 12;
   speedDamageScale = 0.060;

   // Object Impact Damage (uses DamageType::Impact)
   collDamageThresholdVel = 18;
   collDamageMultiplier   = 0.070;

   // Engine
   engineTorque = 7.0 * 745;
   breakTorque = 7.0 * 745;
   maxWheelSpeed = 20;

   // Springs
   springForce = 8000;
   springDamping = 1300;
   antiSwayForce = 6000;
   staticLoadScale = 2;

   // Tires
   tireRadius = 1.6;
   tireFriction = 10.0;
   tireRestitution = 0.5;
   tireLateralForce = 3000;
   tireLateralDamping = 400;
   tireLateralRelaxation = 1;
   tireLongitudinalForce = 12000;
   tireLongitudinalDamping = 600;
   tireLongitudinalRelaxation = 1;
   tireEmitter = TireEmitter;

   //
   maxDamage = 3.85;
   destroyedLevel = 3.85;

   isShielded = true;
   energyPerDamagePoint = 125;
   maxEnergy = 600;
   jetForce = 2800;
   minJetEnergy = 60;
   jetEnergyDrain = 2.75;
   rechargeRate = 1.0;

   jetSound = MPBThrustSound;
   engineSound = MPBEngineSound;
   squeelSound = AssaultVehicleSkid;
   softImpactSound = GravSoftImpactSound;
   hardImpactSound = HardImpactSound;
   //wheelImpactSound = WheelImpactSound;

   //
   softSplashSoundVelocity = 5.0;
   mediumSplashSoundVelocity = 8.0;
   hardSplashSoundVelocity = 12.0;
   exitSplashSoundVelocity = 8.0;

   exitingWater      = VehicleExitWaterSoftSound;
   impactWaterEasy   = VehicleImpactWaterSoftSound;
   impactWaterMedium = VehicleImpactWaterMediumSound;
   impactWaterHard   = VehicleImpactWaterHardSound;
   waterWakeSound    = VehicleWakeMediumSplashSound;

   minMountDist = 3;

   damageEmitter[0] = LightDamageSmoke;
   damageEmitter[1] = HeavyDamageSmoke;
   damageEmitter[2] = DamageBubbles;
   damageEmitterOffset[0] = "3.0 0.5 0.0 ";
   damageEmitterOffset[1] = "-3.0 0.5 0.0 ";
   damageLevelTolerance[0] = 0.3;
   damageLevelTolerance[1] = 0.7;
   numDmgEmitterAreas = 2;

   splashEmitter[0] = VehicleFoamDropletsEmitter;
   splashEmitter[1] = VehicleFoamEmitter;

   shieldImpact = VehicleShieldImpact;

   cmdCategory = "Tactical";
   cmdIcon = CMDGroundMPBIcon;
   cmdMiniIconName = "commander/MiniIcons/com_mpb_grey";
   targetNameTag = 'Jericho';
   targetTypeTag = 'MPB';
   sensorData = VehiclePulseSensor;

   checkRadius = 7.5225;

   observeParameters = "1 12 12";

   runningLight[0] = MPBLight1;
   runningLight[1] = MPBLight2;

   shieldEffectScale = "0.85 1.2 0.7";
};

//**************************************************************
// WEAPONS
//**************************************************************

datablock SensorData(MPBTurretMissileSensor)
{
   detects = true;
   detectsUsingLOS = true;
   detectsPassiveJammed = false;
   detectsActiveJammed = false;
   detectsCloaked = false;
   detectionPings = true;
   detectRadius = 200;
};

datablock TurretData(MobileTurretBase)
{
   className      = VehicleTurret;
   catagory       = "Turrets";
   shapeFile      = "turret_base_mpb.dts";
   preload        = true;

   mass           = 1.0;  // Not really relevant

   maxDamage      = MobileBaseVehicle.maxDamage;
   destroyedLevel = MobileBaseVehicle.destroyedLevel;

   thetaMin      = 15;
   thetaMax      = 140;

   energyPerDamagePoint = 33;
   inheritEnergyFromMount = true;
   firstPersonOnly = true;

   sensorColor = "0 212 45";
   sensorData = MPBTurretMissileSensor;
   sensorRadius = MPBTurretMissileSensor.detectRadius;
   cmdCategory = "Tactical";
   cmdMiniIconName = "commander/MiniIcons/com_turret_grey";
   targetNameTag = 'Jericho';
   targetTypeTag = 'Turret';

   canControl = true;
};

function MobileBaseVehicle::onDamage(%this, %obj)
{
   if (isObject(%obj.getMountNodeObject(1)))
      (%obj.getMountNodeObject(1)).setDamagelevel(%obj.getDamageLevel());
   Parent::onDamage(%this, %obj);
}

function MobileBaseVehicle::onAdd(%this, %obj)
{
   Parent::onAdd(%this, %obj);
   %obj.station = "";
   %obj.turret = "";
   %obj.beacon = "";

   %obj.schedule(5000, "playThread", $AmbientThread, "ambient");
}

function MobileBaseVehicle::deleteAllMounted(%data, %obj)
{
   if (%obj.station !$= "")
   {
      %obj.station.getDataBlock().onLosePowerDisabled(%obj.station);
      %obj.unmountObject(%obj.station);
      %obj.station.trigger.schedule(2000, delete);
      %obj.station.schedule(2000, delete);
   }
   if (%obj.turret !$= "")
   {
      %obj.turret.getDataBlock().onLosePowerDisabled(%obj.turret);
      %obj.unmountObject(%obj.turret);
      %obj.turret.schedule(2000, delete);
   }
   //[most]
   if (%obj.nuke !$= "")
      {
      %obj.nuke.mpm_all_off(1);
      %obj.unmountObject(%obj.nuke);
      %obj.nuke.schedule(1500,"delete");
      }
   //[most]
   if (isObject(%obj.shield))
      %obj.shield.schedule(2000, delete);

   if (isObject(%obj.beacon))
   {
      %obj.beacon.schedule(0, delete);
   }
}

function MobileBaseVehicle::playerMounted(%data, %obj, %player, %node)
{
//[[CHANGE]]
   if (%obj.clientControl)
       serverCmdResetControlObject(%obj.clientControl);

   // MPB vehicle == SUV (single-user vehicle)
   commandToClient(%player.client, 'setHudMode', 'Pilot', "MPB", %node);
   if (%obj.deploySchedule)
   {
      %obj.deploySchedule.clear();
      %obj.deploySchedule = "";
   }

   if (%obj.deployed !$= "" && %obj.deployed == 1)
   {
      %obj.setThreadDir($DeployThread, false);
      %obj.playThread($DeployThread,"deploy");
      %obj.playAudio($DeploySound, MobileBaseUndeploySound);
      %obj.station.setThreadDir($DeployThread, false);
      %obj.station.getDataBlock().onLosePowerDisabled(%obj.station);
      %obj.station.clearSelfPowered();
      %obj.station.goingOut=false;
      %obj.station.notDeployed = 1;
      %obj.station.playAudio($DeploySound, MobileBaseStationUndeploySound);
      if (isObject(%obj.turret))
      {
      if ((%turretClient = %obj.turret.getControllingClient()) !$= "")
      {
         CommandToServer( 'resetControlObject', %turretClient );
      }

      %obj.turret.setThreadDir($DeployThread, false);
      %obj.turret.clearTarget();
      %obj.turret.setTargetObject(-1);

      %obj.turret.playAudio($DeploySound, MobileBaseTurretUndeploySound);
      }
       //[most]
      if (isObject(%obj.nuke))
	      %obj.nuke.mpm_all_off(0);
       //[most]
      %obj.shield.open();
      %obj.shield.schedule(1000,"delete");
      %obj.deploySchedule = "";

      %obj.fullyDeployed = 0;

      %obj.noEnemyControl = 0;
   }
   %obj.deployed = 0;

   // update observers who are following this guy...
   if ( %player.client.observeCount > 0 )
      resetObserveFollow( %player.client, false );
}

function MobileBaseVehicle::playerDismounted(%data, %obj, %player)
{
   %obj.schedule(500, "deployVehicle", %data, %player);
   Parent::playerDismounted( %data, %obj, %player );
}

function MobileBaseVehicle::vehicleDeploy(%data, %obj, %player, %force)
{

   if (VectorLen(%obj.getVelocity()) <= 0.1 || %force)
   {
      %deployMessage = "";
      if ( (%deployMessage = %data.checkTurretDistance(%obj)) $= "" || %force)
      {
         if (%obj.station $= "")
         {
            if ( (%deployMessage = %data.checkDeploy(%obj)) $= "" || %force)
            {
               %obj.station = new StaticShape() {
                  scale = "1 1 1";
                  dataBlock = "MobileInvStation";
                  lockCount = "0";
                  homingCount = "0";
                  team = %obj.team;
                  vehicle = %obj;
               };
               %obj.station.startFade(0,0,true);
               %obj.mountObject(%obj.station, 2);
               %obj.station.getDataBlock().createTrigger(%obj.station);
               %obj.station.setSelfPowered();
               %obj.station.playThread($PowerThread,"Power");
               %obj.station.playAudio($HumSound,StationHumSound);
               %obj.station.vehicle = %obj;

               //[most] Only give mpb's nukes when enabled in options
               if ($MPM::NukeMPB)
                  {
                  %obj.nuke=%obj.Mpm_Turret();
                  %obj.nuke.ammo = %obj.nukeammo;
                  }
               else //Otherwise give normal turret.
                  {
                   %obj.turret = new turret()
                        {
                  scale = "1 1 1";
                  dataBlock = "MobileTurretBase";
                  lockCount = "0";
                  homingCount = "0";
                  team = %obj.team;
               };
               %obj.turret.setDamageLevel(%obj.getDamageLevel());
               %obj.mountObject(%obj.turret, 1);
               %obj.turret.setSelfPowered();
               %obj.turret.playThread($PowerThread,"Power");
               %obj.turret.mountImage(MissileBarrelLarge, 0 ,false);
                   }


               %obj.beacon = new BeaconObject() {
                  dataBlock = "DeployedBeacon";
                  position = %obj.position;
                  rotation = %obj.rotation;
                  team = %obj.team;
               };
               %obj.beacon.setBeaconType(friend);
               %obj.beacon.setTarget(%obj.team);
               // ---------------------------------
               // z0dd - ZOD, 5/8/02. Invalid call.
               //checkSpawnPos(%obj, 20);
            }
         }
         else
         {
            %obj.station.setSelfPowered();
            %obj.station.playThread($PowerThread,"Power");
            //[most] //check if there "is" an turret
            if (isObject(%obj.turret))
               {
            %obj.turret.setSelfPowered();
            %obj.turret.playThread($PowerThread,"Power");
         }
            //[most]
         }
         if (%deployMessage $= "" || %force)
         {
         //[most]
         if (isObject(%obj.turret))
            {
            if (%obj.turret.getTarget() == -1)
            {
               %obj.turret.setTarget(%obj.turret.target);
            }
            %obj.turret.setThreadDir($DeployThread, true);
            %obj.turret.playThread($DeployThread,"deploy");
            %obj.turret.playAudio($DeploySound, MobileBaseTurretDeploySound);
	    }
            if (isObject(%obj.nuke))
	      %obj.nuke.mpm_all_on();
            //[most]
            %obj.station.notDeployed = 1;
            %obj.setThreadDir($DeployThread, true);
            %obj.playThread($DeployThread,"deploy");
            %obj.playAudio($DeploySound, MobileBaseDeploySound);
            %obj.deployed = 1;
            %obj.deploySchedule = "";
            %obj.disableMove = true;
            %obj.setFrozenState(true);
            if (isObject(%obj.shield))
               %obj.shield.delete();

            %obj.shield = new forceFieldBare()
            {
               scale = "1.22 1.8 1.1";
               dataBlock = "defaultTeamSlowFieldBare";
               team = %obj.team;
            };
            %obj.shield.open();
            setTargetSensorData(%obj.getTarget(), MPBDeployedSensor);
         }
      }
      if (%deployMessage !$= "")
         messageClient(%player.client, '', %deployMessage);

      return true;
   }
   else
   {
      return false;
   }
}

function MobileBaseVehicle::onEndSequence(%data, %obj, %thread)
{
   if (%thread == $DeployThread && !%obj.deployed)
   {
      %obj.unmountObject(%obj.station);
      %obj.station.trigger.delete();
      %obj.station.delete();
      %obj.station = "";

	  %obj.beacon.delete();
      //[most] Handles removal of nuke.
      if (isObject(%obj.nuke))
         {
         %obj.nukeammo = %obj.nuke.ammo;
         %obj.nuke.mpm_all_off(1);
         %obj.unmountObject(%obj.nuke);
         %obj.nuke.schedule(1500,"delete");
         }
      if (isObject(%obj.turret))
         {
      %obj.unmountObject(%obj.turret);
      %obj.turret.delete();
      %obj.turret = "";
         }
      //[most]
      if (!%obj.immobilized)
      {
         %obj.disableMove = false;
         %obj.setFrozenState(false);
      }
      setTargetSensorData(%obj.getTarget(), %data.sensorData);
   }
   else
   {
      %obj.station.startFade(0,0,false);
      %obj.station.setThreadDir($DeployThread, true);
      %obj.station.playThread($DeployThread,"deploy");
      %obj.station.playAudio($DeploySound, MobileBaseStationDeploySound);
      %obj.station.goingOut = true;
      %obj.shield.setTransform(%obj.getSlotTransform(3));
      %obj.shield.close();
      %obj.isDeployed = true;
      %obj.noEnemyControl = 1;
   }

   Parent::onEndSequence(%data, %obj, %thread);
}

function MobileInvStation::onEndSequence(%data, %obj, %thread)
{
   if (!%obj.goingOut)
      %obj.startFade(0,0,true);
   else
   {
      %obj.notDeployed = 0;
      %obj.vehicle.fullyDeployed = 1;
   }
   Parent::onEndSequence(%data, %obj, %thread);
}


function MobileBaseVehicle::checkDeploy(%data, %obj)
{

   %mask = $TypeMasks::VehicleObjectType | $TypeMasks::MoveableObjectType |
           $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType |
           $TypeMasks::ItemObjectType | $TypeMasks::PlayerObjectType |
           $TypeMasks::TurretObjectType | //$TypeMasks::StaticTSObjectType |
           $TypeMasks::InteriorObjectType;

   //%slot 1 = turret   %slot 2 = station
   %height[1] = 0;
   %height[2] = 0;
   %radius[1] = 2.4;
   %radius[2] = 2.4;
   %stationFailed = false;
   %turretFailed = false;

   for(%x = 1; %x < 3; %x++)
   {
      %posXY = getWords(%obj.getSlotTransform(%x), 0, 1);
      %posZ = (getWord(%obj.getSlotTransform(%x), 2) + %height[%x]);
      //InitContainerRadiusSearch(%posXY @ " " @ %posZ, %radius[%x], %mask);

      while ((%objFound = ContainerSearchNext()) != 0)
      {
         if (%objFound != %obj)
         {
            if (%x == 1)
               %turretFailed = true;
            else
               %stationFailed = true;
            break;
         }
      }
   }

   //If turret, station or both fail the send back the error message...
   if (%turretFailed &&  %stationFailed)
      return "Both Turret and Station are blocked and unable to deploy.";
   if (%turretFailed)
      return "Turret is blocked and unable to deploy.";
   if (%stationFailed)
      return "Station is blocked and unable to deploy.";

   //Check the station for collision with the Terrain
   %mat = %obj.getTransform();
   for(%x = 1; %x < 7; %x+=2)
   {
      %startPos = MatrixMulPoint(%mat, %data.stationPoints[%x]);
      %endPos = MatrixMulPoint(%mat, %data.stationPoints[%x+1]);

      //%rayCastObj = containerRayCast(%startPos, %endPos, $TypeMasks::TerrainObjectType, 0);
      if (%rayCastObj)
         return "Station is blocked by terrain and unable to deploy.";
   }

   return "";
}
function MobileBaseVehicle::checkTurretDistance(%data, %obj)
{
   %pos = getWords(%obj.getTransform(), 0, 2);
   //InitContainerRadiusSearch(%pos, 100, $TypeMasks::TurretObjectType | $TypeMasks::InteriorObjectType);
   while ((%objFound = ContainerSearchNext()) != 0)
   {
      if (%objFound.getType() & $TypeMasks::TurretObjectType)
      {
         if (%objFound.getDataBlock().ClassName $= "TurretBase")
            return "Turret Base is in the area. Unable to deploy.";
      }
      else
      {
         %subStr = getSubStr(%objFound.interiorFile, 1, 4);
         if (%subStr !$= "rock" && %subStr !$= "spir" && %subStr !$= "misc")
            return "Building is in the area. Unable to deploy.";
      }
   }
   return "";
}
