Advertisement
Guest User

Untitled

a guest
Jan 20th, 2018
763
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.63 KB | None | 0 0
  1. -- Fighter AI v2.2
  2.  
  3. -- IF YOU USE AN AI CARD SET MIN ALTITUDE LOW ENOUGH TO ALLOW ATTACK RUNS
  4.  
  5. minAlt = 50   -- match at least this with the AI card
  6. maxAlt = 400
  7.  
  8. controllingMainframe = 0     --the mainframe with the target prioritization card
  9. restrictSlot = 0             --ai will only control these weapons, and will orient the craft along those
  10.  
  11. onlyBomberRun = 0            -- set to 1 for only doing target/break sequences.
  12. maneuverDistanceFactor = 2   -- increase this if your plane needs more distance between attack run
  13. minimumThrust = 0.05         -- used when behind the enemy to slow down and keep it in target longer
  14.  
  15. spaceWhenIdle = 0            --set to 1 if you don't have a AI Plane card
  16.  
  17. dampening = 8                -- derivative term - reduce wobbling
  18. multiplyer = 2               -- proportional term - stronger control response
  19. corrective = 0.1             -- integrative term - helps craft that fly with an offset
  20. falloff = 1.1                 -- tune sustained control response falloff
  21. neutralPitch = 0               -- fixed control offset to nose up
  22.  
  23.  
  24. pYaw = 0
  25. pPitch = 0
  26. pRoll = 0
  27.  
  28. iYaw = 0
  29. iPitch = 0
  30. iRoll = 0
  31.  
  32.  
  33.  
  34. function flyAlong(I, direction, normal, seed, thrust)
  35.     I:RequestThrustControl(0, thrust)
  36.    
  37.     I:RequestControl(2,8,thrust)
  38.     logstr = ""
  39.    
  40.     --I:RequestControl(mode,type,drive)
  41.     eYaw =  Vector3.Dot(
  42.             Vector3.ProjectOnPlane(direction, I:GetConstructUpVector() ).normalized,
  43.             I:GetConstructRightVector()
  44.             )
  45.     ePitch = Vector3.Dot(
  46.             Vector3.ProjectOnPlane(direction, I:GetConstructRightVector() ).normalized,
  47.             I:GetConstructUpVector()
  48.             )
  49.     eRoll = Vector3.Dot(
  50.             Vector3.ProjectOnPlane(normal, I:GetConstructForwardVector() ).normalized,
  51.             I:GetConstructRightVector()
  52.             )
  53.    
  54.     dPitch = ePitch - pPitch
  55.     dYaw = eYaw - pYaw
  56.     dRoll = eRoll - pRoll
  57.    
  58.     pYaw   = eYaw
  59.     pPitch = ePitch
  60.     pRoll  = eRoll
  61.  
  62.     iYaw   = (iYaw / (falloff) + eYaw)
  63.     iPitch  = (iPitch / (falloff) + ePitch)
  64.     iRoll  = (iRoll / (falloff) + eRoll)
  65.  
  66.     mul = multiplyer
  67.     damp = dampening
  68.    
  69.     CYaw   = mul * pYaw    + dYaw * damp + iYaw * corrective
  70.     CPitch = mul * pPitch  + dPitch * damp + iPitch * corrective + neutralPitch
  71.     CRoll  = mul * pRoll   + dRoll * damp + iRoll * corrective
  72.  
  73.     if ( CYaw < 0 ) then
  74.             --turn left
  75.             I:RequestControl(2,0,-CYaw)
  76.             I:RequestControl(2,1,0)
  77.             logstr = logstr .. " left " .. -CYaw
  78.     else
  79.             --turn right
  80.             I:RequestControl(2,1,CYaw)
  81.             I:RequestControl(2,0,0)
  82.             logstr = logstr .. " right " ..CYaw
  83.     end
  84.     if ( CPitch < 0 ) then
  85.             --pitch down
  86.             I:RequestControl(2,5,-CPitch)
  87.             I:RequestControl(2,4,0)
  88.             logstr = logstr .. " down " .. -CPitch
  89.     else
  90.             --pitch up
  91.             I:RequestControl(2,4,CPitch)
  92.             I:RequestControl(2,5,0)
  93.             logstr = logstr .. " up " .. CPitch
  94.     end    
  95.            
  96.     if ( CRoll < 0 ) then
  97.             --0. roll left
  98.             logstr = logstr .. " rccw " .. -CRoll
  99.             I:RequestControl(2,2,-CRoll)
  100.             I:RequestControl(2,3,0)
  101.     else
  102.             -- roll right  
  103.             I:RequestControl(2,3,CRoll)
  104.             I:RequestControl(2,2,0)
  105.             logstr = logstr .. " rcw " .. CRoll
  106.  
  107.     end
  108.     --I:LogToHud(logstr)
  109. end
  110.  
  111.  
  112.  
  113.  
  114. function killThatThing(I, weaponInfo, targetInfo, weaponIndex, turretSpinnerIndex)
  115.  
  116.     P = targetInfo.AimPointPosition
  117.     V = targetInfo.Velocity
  118.     WS = weaponInfo.Speed
  119.     G = I:GetGravityForAltitude(P.y).magnitude
  120.    
  121.     if (WS > 100000) then
  122.     AD =  P - weaponInfo.GlobalPosition
  123.     if(turretSpinnerIndex < 0) then
  124.            I:AimWeaponInDirection(weaponIndex, AD.x, AD.y, AD.z, weaponInfo.WeaponSlot)
  125.            I:FireWeapon(weaponIndex, weaponInfo.WeaponSlot)
  126.         else
  127.            I:AimWeaponInDirectionOnTurretOrSpinner(
  128.                  turretSpinnerIndex,weaponIndex, AD.x, AD.y, AD.z, weaponInfo.WeaponSlot)
  129.  
  130.          if (attackState == TARGET) then
  131.            I:FireWeaponOnTurretOrSpinner(
  132.                  turretSpinnerIndex,weaponIndex,weaponInfo.WeaponSlot)
  133.          end
  134.  
  135.         end
  136.         return AD
  137.     end
  138.  
  139.     T = (P - weaponInfo.GlobalPosition).magnitude / (WS*0.85) -- FIRST ESTIMATE OF FUTURE TARGET POSITION
  140.  
  141.  
  142.     FP = P + V*T  - I:GetVelocityVector()*T
  143.  -- position the target will be
  144.  
  145.     AD = FP - weaponInfo.GlobalPosition
  146.   -- direction direct to the target
  147.  
  148.  
  149.  
  150.     PJ = Mathf.Sqrt(AD.x*AD.x + AD.z*AD.z)
  151.  -- horizontal distance to the target
  152.  
  153.    
  154.     S2 = WS*WS
  155.   -- speed^2
  156.     S4 = S2*WS*WS
  157.   -- speed^4 (need these many times)
  158.     DELTA = S4 - G*(G*PJ*PJ + 2*AD.y * S2)
  159.  -- is there a solution to the parable?
  160.      
  161.  
  162.     if ( DELTA > 0 ) then
  163.         --ok we can reach it and now we have a better estimate
  164.        
  165.         AG = Mathf.Atan2(S2 - Mathf.Sqrt(DELTA),G*PJ)
  166.  --calculate angle
  167.        
  168.         --now we can calculate a better time to target using the horizontal speed
  169.         --as obtained from the firing angle
  170.        
  171. T = (P - weaponInfo.GlobalPosition).magnitude / (WS * Mathf.Cos(AG))
  172.        
  173.  
  174.         FP = P + V*T - I:GetVelocityVector()*T
  175.   --position target will be
  176.  
  177.         AD = FP - weaponInfo.GlobalPosition
  178.  -- line direct to the target position
  179.  
  180.  
  181.  
  182.         PJ = Mathf.Sqrt(AD.x*AD.x + AD.z*AD.z)
  183.   -- horizontal distance to the target
  184.  
  185.    
  186.      
  187.         DELTA = S4 - G*(G*PJ*PJ + 2*AD.y * S2)
  188.  -- check the parable solution
  189.  
  190.  
  191.         if ( DELTA > 0 ) then
  192.         --ok we can reach it and now we have a better estimate
  193.         PY = (S2 - Mathf.Sqrt(DELTA))/(G)
  194.  -- no need to calculate angle or tangent, just the elev
  195.  
  196.  
  197.  
  198.         AD.y = PY --assign new elevation to the firing direction
  199.  
  200.  
  201.         if(turretSpinnerIndex < 0) then
  202.            I:AimWeaponInDirection(weaponIndex, AD.x, AD.y, AD.z, weaponInfo.WeaponSlot)
  203.            I:FireWeapon(weaponIndex, weaponInfo.WeaponSlot)
  204.         else
  205.            I:AimWeaponInDirectionOnTurretOrSpinner(
  206.                  turretSpinnerIndex,weaponIndex, AD.x, AD.y, AD.z, weaponInfo.WeaponSlot)
  207.  
  208.          if (attackState == TARGET) then
  209.            I:FireWeaponOnTurretOrSpinner(
  210.                  turretSpinnerIndex,weaponIndex,weaponInfo.WeaponSlot)
  211.          end
  212.  
  213.         end
  214.  
  215.       end
  216.          
  217.     end
  218.    return AD
  219. end
  220.  
  221. function idleAround(I)
  222.     idlePosition = I:GetConstructCenterOfMass()
  223.     com = I:GetConstructCenterOfMass()
  224.     fcom = I:GetConstructCenterOfMass() + I:GetVelocityVector()
  225.     if (I:GetFriendlyCount() > 0) then
  226.         idlePosition = idlePosition / I:GetFriendlyCount()
  227.         for friendlyIndex=0, I:GetFriendlyCount() do
  228.             friendlyInfo = I:GetFriendlyInfo(friendlyIndex)
  229.             idlePosition = friendlyInfo.ReferencePosition / I:GetFriendlyCount()
  230.         end
  231.     end
  232.    
  233.     flyDirection = I:GetConstructCenterOfMass()-I:GetVelocityVector()-idlePosition
  234.         if (com.y < I:GetTerrainAltitudeForLocalPosition(com.x,0,com.z) + minAlt or
  235.          fcom.y < I:GetTerrainAltitudeForLocalPosition(fcom.x,0,fcom.z) + minAlt or
  236.          com.y < minAlt) then
  237.       flyDirection = Vector3(0,1,0)
  238.        
  239.     I:Component_SetBoolLogicAll(0, true)
  240.     else
  241.     I:Component_SetBoolLogicAll(0, false)
  242.     end
  243.     flyAlong(I, flyDirection, -I:GetGravityForAltitude(I:GetConstructCenterOfMass().y), 0 , thrust)
  244. end
  245.  
  246.  
  247.  
  248. BREAK = 0 -- close in to target at max altitude
  249. SPLIT = 1 -- match target direction rolling down/up according to start alt
  250. ROLL = 2 -- if enemy vector are parallel, roll into tail
  251. TARGET = 3 -- aim to a shoot solution
  252. RUN = 4 -- too close and enemy not fast enough
  253. LOOP = 5 --enemy is faster loop on it's tail
  254. YOYO = 6
  255. EVADE = 9
  256. TURNFIGHT = 8
  257. EC = 7
  258.  
  259. attackState = TARGET
  260.  
  261. function performManeuver(I,targetInfo,attackState, situation)
  262.     --some random defaults
  263.     flyDirection = -I:GetGravityForAltitude(situation.com.y)
  264.     flyNormal = -I:GetGravityForAltitude(situation.com.y)
  265.     thrust = 1
  266.     if (attackState == EC) then
  267.        
  268.         flyDirection = I:GetConstructForwardVector().normalized
  269.         flyDirection.y = 0.5
  270.        
  271.         flyNormal =  -I:GetGravityForAltitude(situation.com.y)
  272.         I:Component_SetBoolLogicAll(0, true)
  273.     else
  274.         I:Component_SetBoolLogicAll(0, false)
  275.     end
  276.  
  277.     if (attackState == TARGET) then
  278.        
  279.         flyNormal = (situation.attackDirection + Vector3(0,2,0)).normalized
  280.         flyNormal.y = 0.5
  281.         if (situation.forwardiness > 0.8) then
  282.             flyNormal = Vector3(0,1,0)
  283.         end
  284.        
  285.         if(situation.forwardiness < -0.3) then
  286.             flyDirection = Vector3.Cross(situation.targetDirection, I:GetGravityForAltitude(situation.com.y)).normalized
  287.             flyDirection.y = 0.1
  288.             flyNormal = - situation.targetDirection
  289.             flyDirection.y = 1-situation.operationAltitude
  290.         else
  291.             flyDirection = situation.attackDirection
  292.         end
  293.         if (situation.accordingness > 0 and situation.forwardiness > 0 and situation.separationFactor < 8) then
  294.             if (situation.speedFactor > 1 and I:GetHealthFraction() == 1) then
  295.                 thrust = minimumThrust
  296.             end
  297.         end
  298.     end
  299.    
  300.     if (attackState == BREAK or attackState == EVADE) then
  301.        
  302.         if(situation.forwardiness > 0.1) then
  303.             flyDirection = Vector3.Cross(situation.targetDirection, I:GetGravityForAltitude(situation.com.y)).normalized
  304.             flyDirection.y = 0.0
  305.             flyNormal = - situation.targetDirection
  306.             if (situation.targetAltitude > 0) then
  307.                 flyDirection.y = -0.5
  308.             end
  309.             if (situation.targetAltitude < 0) then
  310.                 flyDirection.y = 0.5
  311.             end
  312.         else
  313.             flyDirection = -situation.targetDirection
  314.             flyDirection.y = 1-situation.operationAltitude
  315.            
  316.  
  317.  
  318.             flyNormal = Vector3(0,1,0)
  319.         end
  320.     end
  321.     if (attackState == YOYO) then
  322.        
  323.         flyDirection = Vector3(0,-situation.operationAltitude,0)
  324.         flyNormal = situation.targetDirection
  325.     end
  326.     if (attackState == ROLL) then
  327.        
  328.         flyDirection =  situation.targetDirection + Vector3(0,-situation.operationAltitude,0) +  I:GetConstructRightVector() * situation.rightness
  329.         flyNormal = situation.targetDirection
  330.     end
  331.    
  332.     if (attackState == TURNFIGHT) then
  333.        
  334.         flyDirection =  Vector3.Cross(situation.targetDirection.normalized, -I:GetGravityForAltitude(situation.com.y))
  335.         flyNormal = situation.targetDirection
  336.     end
  337.    
  338.     if (attackState == LOOP) then
  339.        
  340.         flyDirection =  -situation.targetVelocity +  Vector3(0, -situation.operationAltitude,0)
  341.         flyNormal = situation.targetDirection
  342.     end
  343.    
  344.     flyNormal = flyNormal.normalized
  345.     if (onlyBomberRun > 0 and flyNormal.y  >0.1) then flyNormal.y = 0.1 end
  346.     if (onlyBomberRun > 0 and flyNormal.y  <-0.1) then flyNormal.y = -0.1 end
  347.     if (situation.futurecom.y < minAlt) then flyNormal.y = 0.4 end
  348.     if (situation.futurecom.y > maxAlt) then flyNormal.y = -0.4 end
  349.    
  350.     flyAlong(I, flyDirection, flyNormal, situation.decisionSeed, thrust)
  351. end
  352.  
  353.  
  354.  
  355. limit = 0
  356. function attackEnemy(I, AD, targetInfo)
  357.     situation = {}
  358.  
  359.     situation.com = I:GetConstructCenterOfMass()
  360.     situation.futurecom = situation.com + I:GetVelocityVector()
  361.     situation.attackDirection = AD
  362.     situation.targetPosition = targetInfo.AimPointPosition
  363.     situation.targetVelocity = targetInfo.Velocity
  364.     situation.targetDirection = situation.targetPosition - I:GetConstructCenterOfMass()
  365.    
  366.     situation.forwardiness = Vector3.Dot(situation.targetDirection.normalized, I:GetConstructForwardVector())
  367.     situation.uppiness = Vector3.Dot(situation.targetDirection.normalized, I:GetConstructUpVector())
  368.     situation.rightness = Vector3.Dot(situation.targetDirection.normalized, I:GetConstructRightVector())
  369.     situation.accordingness = Vector3.Dot(situation.targetVelocity.normalized, I:GetVelocityVector().normalized)
  370.    
  371.     situation.distance = situation.targetDirection.magnitude
  372.    
  373.     situation.separation = (situation.targetDirection + situation.targetVelocity  - I:GetVelocityVector()).magnitude
  374.    
  375.     situation.operationAltitude = 2*(situation.com.y - minAlt)/(maxAlt-minAlt) - 1   -- -1 .. 1
  376.     situation.targetAltitude = 2*(situation.targetPosition.y - minAlt)/(maxAlt-minAlt) - 1   -- -1 .. 1
  377.    
  378.     situation.speedFactor = I:GetVelocityVector().magnitude / (situation.targetVelocity.magnitude+0.01)
  379.  
  380.     situation.decisionSeed = ((I:GetConstructForwardVector().x + I:GetConstructForwardVector().y + I:GetConstructForwardVector().z)*534534545353.0)%100    
  381.  
  382.     situation.distanceFactor =  situation.distance / (maneuverDistanceFactor*I:GetVelocityVector().magnitude)
  383.     situation.separationFactor =  situation.separation /  (maneuverDistanceFactor *I:GetVelocityVector().magnitude )
  384.  
  385.  
  386.     -- break to recover after an emergency climb
  387.     if (attackState == EC and situation.operationAltitude > 0 ) then
  388.         attackState = BREAK
  389.     end
  390.    
  391.     -- target enemy if we're far enough
  392.     if (situation.distanceFactor >  4  ) then  
  393.         attackState = TARGET
  394.     end
  395.  
  396.     if (situation.forwardiness >  0 and situation.separationFactor > 2 ) then  
  397.         attackState = TARGET
  398.     end
  399.  
  400.    
  401.     if (attackState == TARGET and situation.separationFactor <  1 ) then  
  402.         if (onlyBomberRun == 1) then
  403.             attackState = BREAK
  404.         else
  405.             if (situation.decisionSeed < 33) then
  406.                 attackState = YOYO
  407.             end
  408.             if (situation.decisionSeed > 32 and situation.decisionSeed < 66) then
  409.                 attackState = ROLL
  410.             end
  411.             if (situation.decisionSeed > 65) then
  412.                 attackState = LOOP
  413.             end
  414.         end
  415.    
  416.     end
  417.    
  418.    
  419.     --emergency upcode
  420.     if (situation.com.y < I:GetTerrainAltitudeForLocalPosition(situation.com.x,0,situation.com.z) + minAlt or
  421.             situation.futurecom.y < I:GetTerrainAltitudeForLocalPosition(situation.futurecom.x,0,situation.futurecom.z) or
  422.             situation.com.y < minAlt) then
  423.        attackState = EC
  424.     end
  425.     --emergency evade
  426.     if (situation.distanceFactor < 1) then
  427.         attackState = EVADE
  428.     end
  429.  
  430.     performManeuver(I,targetInfo,attackState, situation)
  431.  
  432. end
  433.  
  434.  
  435. function Update(I)
  436.    
  437.     targetInfo = I:GetTargetInfo(controllingMainframe, 0)
  438.     AttackDirection = nil
  439.    
  440.     otherInfo = targetInfo
  441.     --check all other targets and break from any too close to comfort irregardless of priority
  442.     for targetIndex=0,I:GetNumberOfTargets(controllingMainframe) do
  443.         otherInfo = I:GetTargetInfo(controllingMainframe, targetIndex)
  444.         situation = {}
  445.         situation.com = I:GetConstructCenterOfMass()
  446.         situation.targetPosition = otherInfo.AimPointPosition
  447.         situation.targetVelocity = otherInfo.Velocity
  448.         situation.targetDirection = situation.targetPosition - situation.com
  449.        
  450.        
  451.         situation.separation = (situation.targetDirection + situation.targetVelocity  - I:GetVelocityVector()).magnitude
  452.            
  453.        
  454.         if (situation.separation < I:GetVelocityVector().magnitude) then
  455.             targetInfo = otherInfo
  456.         end
  457.     end
  458.    
  459.    
  460.     if(targetInfo.Valid) then
  461.         for weaponIndex=0,I:GetWeaponCount() do
  462.           weaponInfo = I:GetWeaponInfo(weaponIndex)
  463.      
  464.           if ((weaponInfo.WeaponType == 4 or weaponInfo.WeaponType == 0 or weaponInfo.WeaponType == 2)
  465.                and weaponInfo.Valid and weaponInfo.PlayerCurrentlyControllingIt == false
  466.                and weaponInfo.WeaponSlot == restrictSlot) then
  467.                AttackDirection = killThatThing(I, weaponInfo, targetInfo, weaponIndex, -1)
  468.           end
  469.         end
  470.        
  471.         for turretSpinnerIndex=0,I:GetTurretSpinnerCount() do
  472.             for weaponIndex=0,I:GetWeaponCountOnTurretOrSpinner(turretSpinnerIndex) do
  473.               weaponInfo = I:GetWeaponInfoOnTurretOrSpinner(turretSpinnerIndex, weaponIndex)
  474.                 if ((weaponInfo.WeaponType == 4 or weaponInfo.WeaponType == 0 or weaponInfo.WeaponType == 2)
  475.                 and weaponInfo.Valid and weaponInfo.PlayerCurrentlyControllingIt == false
  476.                 and weaponInfo.WeaponSlot == restrictSlot ) then
  477.                 AttackDirection = killThatThing(I, weaponInfo, targetInfo, weaponIndex, turretSpinnerIndex)
  478.                 end
  479.             end
  480.         end
  481.         if (AttackDirection == nil) then
  482.             P = targetInfo.AimPointPosition
  483.             V = targetInfo.Velocity
  484.        
  485.             FP = P + V
  486.        
  487.          
  488.              I:LogToHud("No weapon configured!!")
  489.             AttackDirection = FP - I:GetConstructCenterOfMass()
  490.         end
  491.         attackEnemy(I, AttackDirection, targetInfo)    
  492.         I:TellAiThatWeAreTakingControl()
  493.     end
  494.        
  495. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement