Advertisement
Guest User

Untitled

a guest
Nov 1st, 2015
198
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.06 KB | None | 0 0
  1. -- v0.8
  2.  
  3. controllingMainframe = 0  --the mainframe with the target prioritization card
  4. restrictSlot = 1          --ai will only control these weapons, and will orient the craft along those
  5. attackFromDistance = 750  -- distance at which do the attack run
  6. abortAttackDistance = 100 -- distance at which we disengage
  7. abortRunDistance = 300    -- distance at which we reengage
  8.  
  9. Kp = 10   --amount of control proportional to deviation
  10. Ki = 0.001  --amount of accumulation to contrast deviation (keep small!)
  11. Kd = 1   --amount of dampening proportional to oscillation
  12.  
  13. minAlt = 100
  14. maxAlt = 300
  15.  
  16.  
  17. function killThatThing(I, weaponInfo, targetInfo, weaponIndex, turretSpinnerIndex)
  18.  
  19.     P = targetInfo.AimPointPosition
  20.     V = targetInfo.Velocity
  21.     WS = weaponInfo.Speed
  22.     G = I:GetGravityForAltitude(P.y).magnitude
  23.  
  24.  
  25.     T = (P - weaponInfo.GlobalPosition).magnitude / (WS*0.85) -- FIRST ESTIMATE OF FUTURE TARGET POSITION
  26.  
  27.  
  28.     FP = P + V*T  - I:GetVelocityVector()*T
  29.  -- position the target will be
  30.  
  31.     AD = FP - weaponInfo.GlobalPosition
  32.   -- direction direct to the target
  33.  
  34.  
  35.  
  36.     PJ = Mathf.Sqrt(AD.x*AD.x + AD.z*AD.z)
  37.  -- horizontal distance to the target
  38.  
  39.    
  40.     S2 = WS*WS
  41.   -- speed^2
  42.     S4 = S2*WS*WS
  43.   -- speed^4 (need these many times)
  44.     DELTA = S4 - G*(G*PJ*PJ + 2*AD.y * S2)
  45.  -- is there a solution to the parable?
  46.      
  47.  
  48.     if ( DELTA > 0 ) then
  49.         --ok we can reach it and now we have a better estimate
  50.        
  51.         AG = Mathf.Atan2(S2 - Mathf.Sqrt(DELTA),G*PJ)
  52.  --calculate angle
  53.        
  54.         --now we can calculate a better time to target using the horizontal speed
  55.         --as obtained from the firing angle
  56.        
  57. T = (P - weaponInfo.GlobalPosition).magnitude / (WS * Mathf.Cos(AG))
  58.        
  59.  
  60.         FP = P + V*T - I:GetVelocityVector()*T
  61.   --position target will be
  62.  
  63.         AD = FP - weaponInfo.GlobalPosition
  64.  -- line direct to the target position
  65.  
  66.  
  67.  
  68.         PJ = Mathf.Sqrt(AD.x*AD.x + AD.z*AD.z)
  69.   -- horizontal distance to the target
  70.  
  71.    
  72.      
  73.         DELTA = S4 - G*(G*PJ*PJ + 2*AD.y * S2)
  74.  -- check the parable solution
  75.  
  76.  
  77.         if ( DELTA > 0 ) then
  78.         --ok we can reach it and now we have a better estimate
  79.         PY = (S2 - Mathf.Sqrt(DELTA))/(G)
  80.  -- no need to calculate angle or tangent, just the elev
  81.  
  82.  
  83.  
  84.         AD.y = PY --assign new elevation to the firing direction
  85.  
  86.  
  87.         if(turretSpinnerIndex < 0) then
  88.            I:AimWeaponInDirection(weaponIndex, AD.x, AD.y, AD.z, weaponInfo.WeaponSlot)
  89.            I:FireWeapon(weaponIndex, weaponInfo.WeaponSlot)
  90.         else
  91.            I:AimWeaponInDirectionOnTurretOrSpinner(
  92.                  turretSpinnerIndex,weaponIndex, AD.x, AD.y, AD.z, weaponInfo.WeaponSlot)
  93.  
  94.          
  95.            I:FireWeaponOnTurretOrSpinner(
  96.                  turretSpinnerIndex,weaponIndex,weaponInfo.WeaponSlot)
  97.  
  98.         end
  99.  
  100.       end
  101.          
  102.     end
  103.    return AD
  104. end
  105.  
  106.  
  107. lastRoll = 0
  108. lastPitch = 0
  109. lastYaw = 0
  110. IRoll = 0
  111. IPitch = 0
  112. IYaw = 0
  113. DRoll = 0
  114. DPitch = 0
  115. DYaw = 0
  116.  
  117. ePitch = 0
  118. eRoll = 0
  119. eYaw = 0
  120.  
  121.  
  122.  
  123. function flyAlong(I, direction, normal)
  124.     I:RequestThrustControl(0, 1)
  125.     logstr = ""
  126.      dt = 1
  127.     lastYaw = eYaw
  128.     lastPitch = ePitch
  129.     lastRoll = eRoll
  130.     --I:RequestControl(mode,type,drive)
  131.     eYaw =  Vector3.Dot(
  132.             Vector3.ProjectOnPlane(direction, I:GetConstructUpVector() ),
  133.             I:GetConstructRightVector()
  134.             )
  135.     ePitch = Vector3.Dot(
  136.             Vector3.ProjectOnPlane(direction, I:GetConstructRightVector() ),
  137.             I:GetConstructUpVector()
  138.             )
  139.     eRoll = Vector3.Dot(
  140.             Vector3.ProjectOnPlane(normal, I:GetConstructForwardVector() ),
  141.             I:GetConstructRightVector()
  142.             )
  143.    
  144.     IYaw = IYaw + eYaw * dt
  145.     DYaw = (eYaw - lastYaw)/dt
  146.     CYaw = Kp*eYaw + Ki*IYaw + Kd*DYaw
  147.  
  148.     IPitch = IPitch + ePitch * dt
  149.     DPitch = (ePitch - lastPitch)/dt
  150.     CPitch = Kp*ePitch + Ki*IPitch + Kd*DPitch
  151.  
  152.     IRoll = IRoll + eRoll * dt
  153.     DRoll = (eRoll - lastRoll)/dt
  154.     CRoll = Kp*eRoll + Ki*IRoll + Kd*DRoll 
  155.    
  156.     CYaw = 0.63661977*Mathf.Atan(CYaw)
  157.     CPitch = 0.63661977*Mathf.Atan(CPitch)
  158.     CRoll = 0.63661977*Mathf.Atan(CRoll)
  159.    
  160.     if ( CYaw < 0 ) then
  161.             --turn left
  162.             I:RequestControl(2,0,-CYaw)
  163.             logstr = logstr .. "left "
  164.     else
  165.             --turn right
  166.             I:RequestControl(2,1,CYaw)
  167.             logstr = logstr .. "right "
  168.     end
  169.     if ( CPitch < 0 ) then
  170.             --pitch down
  171.             I:RequestControl(2,5,-CPitch)
  172.             logstr = logstr .. "down "
  173.     else
  174.             --pitch up
  175.             I:RequestControl(2,4,CPitch)
  176.             logstr = logstr .. "up "
  177.     end    
  178.            
  179.     if ( CRoll < 0 ) then
  180.             -- roll left
  181.             logstr = logstr .. "rccw "
  182.             I:RequestControl(2,2,-CRoll)
  183.     else
  184.             -- roll right  
  185.             I:RequestControl(2,3,CRoll)
  186.             logstr = logstr .. "rcw "
  187.  
  188.     end
  189.    
  190. end
  191.  
  192.  
  193.  
  194. function idleAround(I)
  195.     idlePosition = I:GetConstructCenterOfMass()
  196.     if (I:GetFriendlyCount() > 0) then
  197.         idlePosition = idlePosition / I:GetFriendlyCount()
  198.         for friendlyIndex=0, I:GetFriendlyCount() do
  199.             friendlyInfo = I:GetFriendlyInfo(friendlyIndex)
  200.             idlePosition = friendlyInfo.ReferencePosition / I:GetFriendlyCount()
  201.         end
  202.     end
  203.    
  204.     flyDirection = I:GetConstructCenterOfMass()-I:GetVelocityVector()-idlePosition
  205.    
  206.     flyAlong(I, flyDirection, -I:GetGravityForAltitude(I:GetConstructCenterOfMass().y) )
  207. end
  208.  
  209.  
  210. GAIN = 0 -- close in to target at max altitude
  211. SPLIT = 1 -- match target direction rolling down/up according to start alt
  212. ROLL = 2 -- if enemy vector are parallel, roll into tail
  213. TARGET = 3 -- aim to a shoot solution
  214. RUN = 4 -- too close and enemy not fast enough
  215. LOOP = 5 --enemy is faster loop on it's tail
  216.  
  217. attackState = GAIN
  218.  
  219. function performManeuver(I,AD,targetInfo,attackState)
  220.     normal =  -I:GetGravityForAltitude(I:GetConstructCenterOfMass().y)
  221.     if(attackState == GAIN) then
  222.         I:LogToHud("GAINING")
  223.         y = I:GetConstructCenterOfMass().y
  224.         if ( y < maxAlt - 50 ) then
  225.              AD = AD.normalized
  226.              AD.y = 1
  227.         else
  228.             AD.y = 0
  229.         end
  230.     end
  231.     if(attackState == RUN) then
  232.         V = targetInfo.Velocity
  233.         I:LogToHud("RUNNING")
  234.         AD = V * -1
  235.         y = I:GetConstructCenterOfMass().y
  236.         if ( y < maxAlt - 50 ) then
  237.              AD = AD.normalized
  238.              AD.y = 4
  239.         else
  240.             if ( y > (maxAlt - minAlt / 2) ) then
  241.                 AD = AD.normalized
  242.                 AD.y = -4
  243.              else
  244.                 AD.y=0
  245.              end
  246.         end
  247.     end
  248.     if(attackState == TARGET) then
  249.         I:LogToHud("TARGETING")
  250.         normal = AD
  251.         normal = normal + Vector3(0,1,0)
  252.     end
  253.     if(attackState == LOOP) then
  254.         I:LogToHud("LOOP")
  255.         AD = V * -1
  256.         normal = AD
  257.     end
  258.     flyAlong(I, AD, normal)
  259. end
  260.  
  261.  
  262.  
  263. function attackEnemy(I, AD, targetInfo)
  264.     P = targetInfo.AimPointPosition
  265.     V = targetInfo.Velocity
  266.     FP = P + V
  267.     TD = FP - I:GetConstructCenterOfMass()
  268.     distance = TD.magnitude
  269.  
  270.     if (distance > attackFromDistance) then
  271.         attackState = GAIN
  272.     else
  273.       if (distance < abortAttackDistance) then
  274.           attackState = RUN
  275.       else
  276.           if (attackState == GAIN or distance > abortRunDistance) then
  277.               attackState = TARGET
  278.           end
  279.           if (attackState == RUN and distance < abortRunDistance and Vector3.Dot(V,I:GetConstructForwardVector() )> 0.7) then
  280.              attackState = LOOP
  281.           end
  282.           if (attackState == LOOP and distance > abortAttackDistance and Vector3.Dot(V,I:GetConstructForwardVector() ) < 0) then
  283.              attackState = TARGET
  284.           end
  285.           if (attackState == LOOP and distance < abortAttackDistance and Vector3.Dot(V,I:GetConstructForwardVector() ) < 0) then
  286.              attackState = RUN
  287.           end
  288.       end
  289.     end
  290.  
  291.     performManeuver(I,AD,targetInfo,attackState)
  292.  
  293. end
  294.  
  295. function Update(I)
  296.    
  297.     targetInfo = I:GetTargetInfo(controllingMainframe, 0)
  298.     AttackDirection = nil
  299.     if(targetInfo.Valid) then
  300.         for weaponIndex=0,I:GetWeaponCount() do
  301.           weaponInfo = I:GetWeaponInfo(weaponIndex)
  302.      
  303.           if ((weaponInfo.WeaponType == 4 or weaponInfo.WeaponType == 0 )
  304.                and weaponInfo.Valid and weaponInfo.PlayerCurrentlyControllingIt == false
  305.                and weaponInfo.WeaponSlot == restrictSlot) then
  306.                AttackDirection = killThatThing(I, weaponInfo, targetInfo, weaponIndex, -1)
  307.           end
  308.         end
  309.        
  310.         for turretSpinnerIndex=0,I:GetTurretSpinnerCount() do
  311.             for weaponIndex=0,I:GetWeaponCountOnTurretOrSpinner(turretSpinnerIndex) do
  312.               weaponInfo = I:GetWeaponInfoOnTurretOrSpinner(turretSpinnerIndex, weaponIndex)
  313.                 if ((weaponInfo.WeaponType == 4 or weaponInfo.WeaponType == 0 )
  314.                 and weaponInfo.Valid and weaponInfo.PlayerCurrentlyControllingIt == false
  315.                 and weaponInfo.WeaponSlot == restrictSlot ) then
  316.                 AttackDirection = killThatThing(I, weaponInfo, targetInfo, weaponIndex, turretSpinnerIndex)
  317.                 end
  318.             end
  319.         end
  320.         if (AttackDirection == nil) then
  321.             P = targetInfo.AimPointPosition
  322.             V = targetInfo.Velocity
  323.        
  324.             FP = P + V
  325.        
  326.          
  327.               I:LogToHud("No weapon configured!!")
  328.             AttackDirection = FP - I:GetConstructCenterOfMass()
  329.         end
  330.         attackEnemy(I, AttackDirection, targetInfo)
  331.     else
  332.    
  333.  
  334.        I:LogToHud("IDLING")
  335.    
  336.     end
  337.        
  338.  
  339.    
  340.    
  341. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement