Advertisement
6dwavenminer

FTD Smart Lua Missile System

Mar 6th, 2017
735
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 20.73 KB | None | 0 0
  1. --FTD Smart Missile Guidance System
  2. --Author: 6dwavenminer
  3. --Version: 1.4.0
  4.  
  5.  
  6. --User Config Variables
  7.  
  8. --Launcher vehicle variables
  9. MainFrameID = 0; --Which MainFrame to connect to
  10. WeaponID = 0;
  11. MaxDistanceBetweenLuaTranscieverAndMissileControl = 10; --The maximum distnace between a lua transciever and its corrisponding missile control block.
  12.  
  13. --Missile variables
  14. TargetDetonationRange = -10; --If the distance between target and missile is below this value, blow up.
  15.  
  16. --Target acquisition variables
  17. MaxRange = 4000; --Targets above this range from the missile launcher will be ignored.
  18. MaxTargetHeight = 10000; --Targets above this height will be ignored.
  19. MinTargetHeight = -20; --Targets below this range will be ignored.
  20.  
  21. --Safe detonation variables
  22. SafeDetonteAltitude = 500; --If there are no target, goto and detonte at this altitude.
  23.  
  24. --Missile boost variables
  25. BaseMissileThrust = 600; --Base thrust for missile.
  26. MissileThrustTargetSpeedMultiplier = 10.0; --Value is multiplied by target's speed then added to base thrust of missile, useful for fast targets.
  27. BoostIntecpetionTime = 7.0; --When the intercept time falls below this value,'BoostThrust' is added to missile thrust, useful for Thumpers.
  28. BoostThrust = 8000; --Value added to missile thrust once within boost range.
  29.  
  30. --Cruising variables
  31. BaseDirectEngagementGroundRange = 240; --Below this ground range to target, head directly to target.
  32. DirectEngagementGroundRangeSpeedMultipler = 0.6; --Added onto the engagment range after it has been multiplied by the target speed, used for fast targets.
  33. CruisingAltitude = 250; --While en route travel at this altitude.
  34. CruisingAltitudeAboveTerrain = 30; --If terrain nears cruising altitude, travel this heigh above the terrain.
  35. MaxAllowedCruisingAltitude = 10000; --Missile will try and aviod going above this altitude
  36. MinAllowedCruisingAltitude = 10; --Missile will try and aviod going below this altitude
  37.  
  38. --Anti ally collsion variables
  39. AntiAlliedCollisionPredictionTimeLimit = 8; --Used to prevent missile-allied vessel collisions, number is seconds into the future predicted.
  40. AntiAlliedCollisionPredictionTimeStep = 1; --The time step in seconds used to prevent missile-allied vessel collisions.
  41. AntiAlliedCollisionAdditionalSafetyRange = 5; --Additional range to border of allies to avoid.
  42.  
  43. --End of User Config Variables
  44.  
  45. --Global Variables
  46. TargetVelocityArray = {};
  47. PreviousTimeForTargets = 0;
  48. MissileVelocityArray = {};
  49. PreviousTimeForMissiles = 0;
  50. UseableLuaTransceiverList = {};
  51. UseableLuaTransceiverCount = 0;
  52. TickCount = 0;
  53.  
  54. function GetUseableLuaTranscivers(I)
  55.  local MissileLauncherPos = I:GetWeaponInfo(WeaponID).GlobalPosition;
  56.  local t;
  57.  UseableLuaTransceiverCount = 0;
  58.  for t=0, I:GetLuaTransceiverCount()-1 do
  59.   if Vector3.Distance(MissileLauncherPos,I:GetLuaTransceiverInfo(t).Position) < MaxDistanceBetweenLuaTranscieverAndMissileControl then
  60.    UseableLuaTransceiverList[UseableLuaTransceiverCount] = t;
  61.    UseableLuaTransceiverCount = UseableLuaTransceiverCount + 1;
  62.   end
  63.  end
  64. end
  65.  
  66. --Check that the WeaponID corrisponds to a missile launcher
  67. function WeaponsCheck(I)
  68.  if I:GetWeaponInfo(WeaponID).Valid == false then
  69.   I:LogToHud("Invalid WeaponID, change WeaponID in LUA code");
  70.  else
  71.   if I:GetWeaponInfo(WeaponID).WeaponType == 4 then --Turret check
  72.    if not I:GetWeaponInfoOnTurretOrSpinner(WeaponID, 0).WeaponType == 5 then --Weapons check, is it a missile launcher?
  73.     I:LogToHud("Weapon is not missile launcher, change WeaponID in LUA code, note this weapon is on a turret or spinner,further debugging maybe required");
  74.    else
  75.     GetUseableLuaTranscivers(I);
  76.    end
  77.   else
  78.    if not I:GetWeaponInfo(WeaponID).WeaponType == 5 then --Weapons check, is it a missile launcher?
  79.     I:LogToHud("Weapon is not missile launcher, change WeaponID in LUA code");
  80.    else
  81.     GetUseableLuaTranscivers(I);
  82.    end
  83.   end
  84.  end
  85. end
  86.  
  87. --Creates a list of all targets within range
  88. function GenerateTargetList(I)
  89.  local OutputBuffer = {};
  90.  local TargetIDList = {};
  91.  local NumTargets = 0;
  92.  local TargetPos;
  93.  local TargetRange;
  94.  local n;
  95.  for n=0,I:GetNumberOfTargets(MainFrameID)-1 do
  96.   TargetPos = I:GetTargetInfo(MainFrameID,n).AimPointPosition;
  97.   TargetRange = Vector3.Distance(I:GetWeaponInfo(WeaponID).GlobalPosition,TargetPos);
  98.   if (TargetRange < MaxRange) and (TargetPos.y < MaxTargetHeight) and (TargetPos.y > MinTargetHeight) then
  99.    TargetIDList[NumTargets] = n;
  100.    NumTargets = NumTargets + 1;
  101.   end
  102.  end
  103.  OutputBuffer[0] = NumTargets;
  104.  for n=1, NumTargets do
  105.   OutputBuffer[n] = TargetIDList[n -1];
  106.  end
  107.  return OutputBuffer;
  108. end
  109.  
  110. --If theres no targets go up to safe distance to detonte the missle
  111. function NoTargetSafelyDetonte(I)
  112.  local i;
  113.  local t;
  114.  local m;
  115.  local Missile;
  116.  local MissilePos;
  117.  local MissileSpeed;
  118.  for i=0, UseableLuaTransceiverCount-1 do
  119.   local t = UseableLuaTransceiverList[i];
  120.   for m=0, I:GetLuaControlledMissileCount(t)-1 do
  121.    Missile = I:GetLuaControlledMissileInfo(t,m);
  122.    MissilePos = Missile.Position;
  123.    MissileSpeed = Vector3.Magnitude(Missile.Velocity);
  124.    AimPoint = Vector3(MissilePos.x,SafeDetonteAltitude + 10,MissilePos.z);
  125.    AimPoint = AllyCollisionAviodance(I,MissileSpeed,MissilePos,AimPoint);
  126.    I:SetLuaControlledMissileAimPoint(t,m,AimPoint.x, AimPoint.y, AimPoint.z);
  127.    if ((MissilePos.y > SafeDetonteAltitude) and (SafeDetonteAltitude > 0)) or ((MissilePos.y < SafeDetonteAltitude) and (SafeDetonteAltitude <= 0)) then
  128.     I:DetonateLuaControlledMissile(t,m);
  129.    end
  130.   end
  131.  end
  132. end
  133.  
  134. function CountActiveMissiles(I)
  135.  local NumMissiles = 0;
  136.  local i;
  137.  local t;
  138.  local m;
  139.  for i=0, UseableLuaTransceiverCount-1 do
  140.  local t=UseableLuaTransceiverList[i];
  141.   for m=0, I:GetLuaControlledMissileCount(t)-1 do
  142.    NumMissiles = NumMissiles + 1;
  143.   end
  144.  end
  145.  return NumMissiles;
  146. end
  147.  
  148. --Calculate acceleration of active missiles
  149. function CalculateAccelerationOfMissiles(I,MissileVelocity,MissileID)
  150.  local PreviousMissileVelocity = MissileVelocityArray[MissileID];
  151.  local MissileAcceleration;
  152.  if PreviousMissileVelocity ~= nil then
  153.   MissileAcceleration = (MissileVelocity - PreviousMissileVelocity) / (I:GetTime() - PreviousTimeForMissiles);
  154.  else
  155.   MissileAcceleration = Vector3(0,0,0);
  156.  end
  157.  MissileVelocityArray[MissileID] = MissileVelocity;
  158.  PreviousTimeForMissiles = I:GetTime()
  159.  return MissileAcceleration;
  160. end
  161.  
  162. function CalculateEnemyFleetScore(I,NumTargets,TargetIDList)
  163.  --Find lowest enemy score
  164.  local EnemyFleetTotalScore = 0;
  165.  local LowestScore = 100000;
  166.  local ScoreOffset;
  167.  local n;
  168.  for n=0, NumTargets-1, 1 do
  169.   if (I:GetTargetInfo(MainFrameID,TargetIDList[n]).Score) < LowestScore then
  170.    LowestScore = I:GetTargetInfo(MainFrameID,TargetIDList[n]).Score;
  171.   end
  172.  end
  173.  
  174.  --Calculate score offset
  175.  ScoreOffset = -100000;
  176.  for n=0, NumTargets-1, 1 do
  177.   if (I:GetTargetInfo(MainFrameID,TargetIDList[n]).Score) > ScoreOffset then
  178.    ScoreOffset = I:GetTargetInfo(MainFrameID,TargetIDList[n]).Score;
  179.   end
  180.  end
  181.  ScoreOffset = ScoreOffset / 2;
  182.  ScoreOffset = ScoreOffset - LowestScore;
  183.  
  184.  --Calculate enemy fleet score
  185.  for n=0, NumTargets-1, 1 do
  186.   EnemyFleetTotalScore = EnemyFleetTotalScore + I:GetTargetInfo(MainFrameID,TargetIDList[n]).Score + ScoreOffset;
  187.  end
  188.  return EnemyFleetTotalScore,ScoreOffset;
  189. end
  190.  
  191.  
  192. --Calculate how many to missiles each target
  193. function CalculateMissilesPerTarget(I,NumTargets,TargetIDList,NumMissiles,EnemyFleetTotalScore,ScoreOffset)
  194.  local MissilesPerTarget = {};
  195.  local n;
  196.  for n=0, NumTargets-1, 1 do
  197.   if NumTargets == 1 then
  198.    MissilesPerTarget[n] = NumMissiles;
  199.   else
  200.    MissilesPerTarget[n] = ((I:GetTargetInfo(MainFrameID,TargetIDList[n]).Score + ScoreOffset) / EnemyFleetTotalScore) * NumMissiles;
  201.    MissilesPerTarget[n] = math.floor(MissilesPerTarget[n] + 0.5);
  202.   end
  203.  end
  204.  return MissilesPerTarget;
  205. end
  206.  
  207.  --Calculate acceleration of enemy targets
  208. function CalculateAccelerationOfTargets(I,NumTargets,TargetIDList)
  209.  local TargetAcceleration = {};
  210.  local Target;
  211.  local n;
  212.  for n=0, NumTargets-1 do
  213.   Target = I:GetTargetInfo(MainFrameID,TargetIDList[n]);
  214.   if TargetVelocityArray[TargetIDList[n]] ~= nil then
  215.    TargetAcceleration[n] = (Target.Velocity - TargetVelocityArray[TargetIDList[n]]) / (I:GetTime() - PreviousTimeForTargets);
  216.    TargetVelocityArray[TargetIDList[n]] = Target.Velocity;
  217.   else
  218.    TargetAcceleration[n] = Vector3(0,0,0);
  219.   end
  220.  end
  221.  PreviousTimeForTargets = I:GetTime()
  222.  return TargetAcceleration;
  223. end
  224.  
  225. function AssignTargetForMissile(I,NumTargets,TargetNum,MissileNum,MissilesPerTarget)
  226.  --Increment MissileID
  227.  MissileNum = MissileNum + 1;
  228.  if MissileNum > MissilesPerTarget[TargetNum] then
  229.   if TargetNum < NumTargets - 1 then
  230.    TargetNum = TargetNum + 1;
  231.    MissileNum = 0;
  232.   end
  233.  end
  234.  return TargetNum,MissileNum
  235. end
  236.  
  237. --Calculate distance ignoring vertical component
  238. function CalculateGroundDistanceToTarget(I,MissilePos,TargetPos)
  239.   local GroundDistanceToTarget;
  240.   local TwoDMissilePos = MissilePos * 1; --Multiply by one to only copy the data, not the reference!
  241.   local TwoDTargetPos = TargetPos * 1; --Multiply by one to only copy the data, not the reference!
  242.   TwoDMissilePos.y = 0;
  243.   TwoDTargetPos.y = 0;
  244.   GroundDistanceToTarget = Vector3.Distance(TwoDMissilePos,TwoDTargetPos);
  245.   return GroundDistanceToTarget;
  246. end
  247.  
  248. --En route go to attlitude till near target
  249. function TravelTowardsTarget(I,MissileHeightAboveTerrain,MissilePos,TargetPos)
  250.     local CruisingHeight = CruisingAltitude;
  251.     if MissileHeightAboveTerrain > CruisingAltitude - 20 then
  252.         CruisingHeight = MissileHeightAboveTerrain + CruisingAltitudeAboveTerrain;
  253.     end
  254.     --Now head to target
  255.     local GroundDistanceToTarget = CalculateGroundDistanceToTarget(I,MissilePos,TargetPos);     if GroundDistanceToTarget < BaseMissileThrust / 15 then
  256.         AimPoint = Vector3(TargetPos.x, CruisingHeight, TargetPos.z);
  257.     else
  258.         --Correct overshooting of height
  259.         local CoOrdinateMultiplier = (BaseMissileThrust / 15) / GroundDistanceToTarget;
  260.         local Missle_TargetDifferentialPosX = MissilePos.x - TargetPos.x;
  261.         local Missle_TargetDifferentialPosZ = MissilePos.z - TargetPos.z;
  262.         AimPoint = Vector3(MissilePos.x - (Missle_TargetDifferentialPosX * CoOrdinateMultiplier), CruisingHeight, MissilePos.z - (Missle_TargetDifferentialPosZ * CoOrdinateMultiplier));
  263.     end
  264.     return AimPoint;
  265. end
  266.  
  267.  
  268. --Changes the missile thrust every 20 ticks
  269. function SetMissileThrust(I,t,m,Thrust)
  270.     if TickCount < 20 then
  271.         TickCount = TickCount + 1;
  272.     else
  273.         TickCount = 0;
  274.         local Missile = I:GetLuaControlledMissileInfo(t, m);
  275.         if Missile.Valid == true then
  276.             local MissileInfo = I:GetMissileInfo(t,m);--Lagfest
  277.             if (MissileInfo ~= nil) then
  278.                 for i,part in pairs(MissileInfo.Parts) do
  279.                     if (string.find(part.Name, 'variable')) then
  280.                         MissileInfo.Parts[i]:SendRegister(2, Thrust);
  281.                     end
  282.                 end
  283.             end
  284.         end
  285.     end
  286. end
  287.  
  288. function ControlMissileThrust(I,t,m,IntecpetionTime,TargetSpeed)
  289.     local MissileThrust = BaseMissileThrust + (TargetSpeed * MissileThrustTargetSpeedMultiplier);
  290.     if IntecpetionTime < BoostIntecpetionTime then
  291.         MissileThrust = MissileThrust + BoostThrust;
  292.     end
  293.     SetMissileThrust(I,t,m,MissileThrust);
  294. end
  295.  
  296.  
  297. function PredictInterceptPosition(I,t,m,MissilePos,TargetPos,MissileSpeed,MissileAcceleration,TargetSpeed,TargetVelocity,TargetAcceleration,IntecpetionTime)
  298.  local IntecpetionRange;
  299.  local InterceptionAimPos;
  300.  local Range = Vector3.Distance(MissilePos,TargetPos);
  301.  local MinInterceptionTime = Range / (MissileSpeed + TargetSpeed);
  302.  local InterceptionAimPos = TargetPos + (TargetVelocity * MinInterceptionTime) + ((TargetAcceleration + MissileAcceleration) * 0.5 * math.pow(MinInterceptionTime,2));
  303.  for i=0, 12 do
  304.   IntecpetionRange = Vector3.Distance(MissilePos,InterceptionAimPos);
  305.   IntecpetionTime = IntecpetionRange / MissileSpeed;
  306.   InterceptionAimPos = TargetPos + (TargetVelocity * IntecpetionTime) + ((TargetAcceleration + MissileAcceleration) * 0.5 * math.pow(IntecpetionTime,2));
  307.  end
  308.  
  309.  AimPoint = Vector3(InterceptionAimPos.x,InterceptionAimPos.y,InterceptionAimPos.z);
  310.  return AimPoint,IntecpetionTime;
  311. end
  312.  
  313. --Checks missiles curret appoximate trajectory for any possible collisions with predicted allied postions and attempts to aviod them
  314. function AllyCollisionAviodance(I,MissileSpeed,MissilePos,AimPoint)
  315.  --Find all possible allied collsions
  316.  local n;
  317.  local t;
  318.  local MissileTimeToReachAimPos;
  319.  local MissileFuturePos;
  320.  local FutureAllyReferencePosition;
  321.  local FutureAllyReferencePositionPositiveSize;
  322.  local FutureAllyReferencePositionNegativeSize;
  323.  local PositiveAviodCoOrdinates;
  324.  local NegativeAviodCoOrdinates;
  325.  local MissileFutureCollisionPos;
  326.  local PositiveEvadeDistance;
  327.  local NegativeEvadeDistance;
  328.  local AlliedCollsionTimeArray = {};
  329.  local AlliedCollsionFriendlyIndexArray = {};
  330.  local NearestTimeCollsion = AntiAlliedCollisionPredictionTimeLimit;
  331.  local NumOfPossibleAlliedCollision = 0;
  332.  local NumOfFriendlies = I:GetFriendlyCount();
  333.  local FriendlyInfo;
  334.  for n=0, NumOfFriendlies-1 do
  335.   FriendlyInfo = I:GetFriendlyInfo(n);
  336.   if FriendlyInfo.Valid == true then
  337.    MissileTimeToReachAimPos = Vector3.Distance(MissilePos,AimPoint) / MissileSpeed;
  338.    for t=0, AntiAlliedCollisionPredictionTimeLimit-1,AntiAlliedCollisionPredictionTimeStep do
  339.     if MissileTimeToReachAimPos > t then --Don't care is the ally is behind the enemy target
  340.      MissileFuturePos = MissilePos + ((AimPoint - MissilePos) / t);
  341.      FutureAllyReferencePosition = FriendlyInfo.ReferencePosition + (FriendlyInfo.Velocity * t);
  342.      FutureAllyReferencePositionPositiveSize = FutureAllyReferencePosition + FriendlyInfo.PositiveSize + Vector3(AntiAlliedCollisionAdditionalSafetyRange,AntiAlliedCollisionAdditionalSafetyRange,AntiAlliedCollisionAdditionalSafetyRange);
  343.      FutureAllyReferencePositionNegativeSize = FutureAllyReferencePosition + FriendlyInfo.NegativeSize - Vector3(AntiAlliedCollisionAdditionalSafetyRange,AntiAlliedCollisionAdditionalSafetyRange,AntiAlliedCollisionAdditionalSafetyRange);
  344.      if  (MissileFuturePos.x <= FutureAllyReferencePositionPositiveSize.x)
  345.      and (MissileFuturePos.x >= FutureAllyReferencePositionNegativeSize.x)
  346.      and (MissileFuturePos.y <= FutureAllyReferencePositionPositiveSize.y)
  347.      and (MissileFuturePos.y >= FutureAllyReferencePositionNegativeSize.y)
  348.      and (MissileFuturePos.z <= FutureAllyReferencePositionPositiveSize.z)
  349.      and (MissileFuturePos.z >= FutureAllyReferencePositionNegativeSize.z)
  350.      then
  351.       --Will probably collide with ally, record time and friendly Index
  352.       if t < NearestTimeCollsion then
  353.        NearestTimeCollsion = t;
  354.       end
  355.       AlliedCollsionTimeArray[0] = t;
  356.       AlliedCollsionFriendlyIndexArray[0] = n;
  357.       NumOfPossibleAlliedCollision = NumOfPossibleAlliedCollision + 1;
  358.       break
  359.      end
  360.     end
  361.    end
  362.   end
  363.  end
  364.  
  365.  --Calculate where the missile can't go
  366.  PositiveAviodCoOrdinates = Vector3(-100000,100000,-100000);
  367.  NegativeAviodCoOrdinates = Vector3(100000,100000,100000);
  368.  for n=0, NumOfPossibleAlliedCollision-1 do
  369.   t = AlliedCollsionTimeArray[n];
  370.   if NearestTimeCollsion == t then --Only care about the nearest time possible collsions
  371.    FriendlyInfo = I:GetFriendlyInfo(n);
  372.  
  373.    FutureAllyReferencePosition = FriendlyInfo.ReferencePosition + (FriendlyInfo.Velocity * t);
  374.    FutureAllyReferencePositionPositiveSize = FutureAllyReferencePosition + FriendlyInfo.PositiveSize + Vector3(AntiAlliedCollisionAdditionalSafetyRange,AntiAlliedCollisionAdditionalSafetyRange,AntiAlliedCollisionAdditionalSafetyRange);
  375.    FutureAllyReferencePositionNegativeSize = FutureAllyReferencePosition + FriendlyInfo.NegativeSize - Vector3(AntiAlliedCollisionAdditionalSafetyRange,AntiAlliedCollisionAdditionalSafetyRange,AntiAlliedCollisionAdditionalSafetyRange);
  376.  
  377.    if (PositiveAviodCoOrdinates.x <= FutureAllyReferencePositionPositiveSize.x) then
  378.     PositiveAviodCoOrdinates.x = FutureAllyReferencePositionPositiveSize.x;
  379.    end
  380.    if (NegativeAviodCoOrdinates.x >= FutureAllyReferencePositionPositiveSize.x) then
  381.     NegativeAviodCoOrdinates.x = FutureAllyReferencePositionNegativeSize.x;
  382.    end
  383.    if (PositiveAviodCoOrdinates.y <= FutureAllyReferencePositionPositiveSize.y) then
  384.     PositiveAviodCoOrdinates.y = FutureAllyReferencePositionPositiveSize.y;
  385.    end
  386.    if (NegativeAviodCoOrdinates.y >= FutureAllyReferencePositionPositiveSize.y) then
  387.     NegativeAviodCoOrdinates.y = FutureAllyReferencePositionNegativeSize.y;
  388.    end
  389.    if (PositiveAviodCoOrdinates.z <= FutureAllyReferencePositionPositiveSize.z) then
  390.     PositiveAviodCoOrdinates.z = FutureAllyReferencePositionPositiveSize.z;
  391.    end
  392.    if (NegativeAviodCoOrdinates.z >= FutureAllyReferencePositionPositiveSize.z) then
  393.     NegativeAviodCoOrdinates.z = FutureAllyReferencePositionNegativeSize.z;
  394.    end
  395.   end
  396.  end
  397.  
  398.  --Find the nearest non-collsion point while trying to maintain route to target
  399.  if NumOfPossibleAlliedCollision > 0 then
  400.   MissileFutureCollisionPos = MissilePos + ((AimPoint - MissilePos) / NearestTimeCollsion);
  401.   PositiveEvadeDistance = Vector3.Magnitude(MissileFutureCollisionPos - PositiveAviodCoOrdinates);
  402.   NegativeEvadeDistance = Vector3.Magnitude(MissileFutureCollisionPos - NegativeAviodCoOrdinates);
  403.   --Now we try and steer the missile away from the possible collisions
  404.   if PositiveEvadeDistance < NegativeEvadeDistance  then
  405.    AimPoint = PositiveAviodCoOrdinates;
  406.    if PositiveEvadeDistance.y > MaxAllowedCruisingAltitude then
  407.     AimPoint.y = MaxAllowedCruisingAltitude.y;
  408.    end
  409.   else
  410.    AimPoint = NegativeAviodCoOrdinates;
  411.    if NegativeAviodCoOrdinates.y < MinAllowedCruisingAltitude then
  412.     AimPoint.y = MinAllowedCruisingAltitude;
  413.    else
  414.    end
  415.   end
  416.  end
  417.  return AimPoint;
  418. end
  419.  
  420. --Main
  421. function Update(I)
  422. --Startup
  423. WeaponsCheck(I);
  424. local TargetListBuffer = {};
  425. local TargetIDList = {};
  426. local TargetListBuffer = unpack{GenerateTargetList(I)};
  427. local TargetAcceleration = {};
  428. local NumTargets = TargetListBuffer[0];
  429.  
  430. local NumMissiles = 0;
  431. local EnemyFleetTotalScore = 0;
  432. local MissilesPerTarget = {};
  433. local ScoreOffset = 0;
  434.  
  435. local MissileNum = 0;
  436. local MissileID = 0;
  437. local TargetNum = 0;
  438.  
  439. local Target;
  440. local TargetPos;
  441. local TargetVelocity;
  442. local TargetSpeed;
  443.    
  444. local Missile;
  445. local MissilePos;
  446. local MissileVelocity;
  447. local MissileSpeed;
  448. local MissileAcceleration;
  449. local MissileHeightAboveTerrain;
  450.  
  451. --Counter variables
  452. local n;
  453. local i;
  454. local t;
  455. local m;
  456.  
  457.  
  458. if NumTargets > 0 then
  459.  for n=0, NumTargets-1 do
  460.   TargetIDList[n] = TargetListBuffer[n+1];
  461.  end
  462. end      
  463.  
  464. if NumTargets<=0 then
  465.  NoTargetSafelyDetonte(I);
  466. else
  467.  NumMissiles = CountActiveMissiles(I);
  468.  EnemyFleetTotalScore,ScoreOffset = unpack{CalculateEnemyFleetScore(I,NumTargets,TargetIDList)};
  469.  MissilesPerTarget = CalculateMissilesPerTarget(I,NumTargets,TargetIDList,NumMissiles,EnemyFleetTotalScore,ScoreOffset);
  470.  
  471.  TargetAcceleration = CalculateAccelerationOfTargets(I,NumTargets,TargetIDList);
  472.  
  473.   for i=0, UseableLuaTransceiverCount-1 do
  474.    t=UseableLuaTransceiverList[i];
  475.    for m=0, I:GetLuaControlledMissileCount(t)-1 do
  476.     TargetNum,MissileNum = unpack{AssignTargetForMissile(I,NumTargets,TargetNum,MissileNum,MissilesPerTarget)};
  477.     local Target = I:GetTargetInfo(MainFrameID,TargetIDList[TargetNum]);
  478.     local TargetPos = Target.AimPointPosition;
  479.     local TargetVelocity = Target.Velocity;
  480.     local TargetSpeed = Vector3.Magnitude(TargetVelocity);
  481.    
  482.     local Missile = I:GetLuaControlledMissileInfo(t,m);
  483.     local MissilePos = Missile.Position;
  484.     local MissileVelocity = Missile.Velocity;
  485.     local MissileSpeed = Vector3.Magnitude(MissileVelocity);
  486.     MissileID = MissileID + 1;
  487.     local MissileAcceleration = CalculateAccelerationOfMissiles(I,MissileVelocity,MissileID);
  488.     MissileAcceleration = Vector3(0,0,0);
  489.     local MissileHeightAboveTerrain = I:GetTerrainAltitudeForPosition(MissilePos);
  490.    
  491.     if Vector3.Distance(MissilePos,TargetPos) < TargetDetonationRange then
  492.      I:DetonateLuaControlledMissile(t,m);
  493.     end
  494.    
  495.     if MissileHeightAboveTerrain < 0 then
  496.      MissileHeightAboveTerrain = 0;
  497.     end
  498.     GroundDistanceToTarget = CalculateGroundDistanceToTarget(I,MissilePos,TargetPos);
  499.     if GroundDistanceToTarget > BaseDirectEngagementGroundRange + (DirectEngagementGroundRangeSpeedMultipler * TargetSpeed) then
  500.      AimPoint = TravelTowardsTarget(I,MissileHeightAboveTerrain,MissilePos,TargetPos);
  501.      --Set missle thrust
  502.     ControlMissileThrust(I,t,m,500,TargetSpeed);
  503.     else
  504.     local IntecpetionTime = 0;
  505.      AimPoint,IntecpetionTime = unpack{PredictInterceptPosition(I,t,m,MissilePos,TargetPos,MissileSpeed,MissileAcceleration,TargetSpeed,TargetVelocity,TargetAcceleration[TargetIDList[TargetNum]])};
  506.      --Set missle
  507.     ControlMissileThrust(I,t,m,IntecpetionTime,TargetSpeed);
  508.     end
  509.     --Check to make sure we don't blow up any allies
  510.     AimPoint = AllyCollisionAviodance(I,MissileSpeed,MissilePos,AimPoint);
  511.     --Now aim at target
  512.     I:SetLuaControlledMissileAimPoint(t,m,AimPoint.x,AimPoint.y,AimPoint.z);
  513.    end
  514.   end
  515.  end
  516. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement