Guest User

Untitled

a guest
May 19th, 2024
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.46 KB | None | 0 0
  1. --Turret Aimer
  2.  
  3. ----------
  4. --Config--
  5. ----------
  6.  
  7. --Max position derivation degree to use for prediction
  8. maxderive = 6
  9. --Rate to smooth interpolated derivation degree information, exponential by degree
  10. smoothrate = 1/2
  11. --Gravity settings by weapon type, if not listed, gravity is 1.0
  12. gravtable = {[6]=0}
  13. --The angle at which a missile has passed its target that it will be detonated
  14. missiledetang = 120
  15.  
  16. ----------
  17. --Config--
  18. ----------
  19.  
  20. --Maximum number of targets to store data for
  21. maxbuffered = 50
  22.  
  23. --Position derivation info for all tracked targets
  24. targposinf = {}
  25. targposinfsz = 0
  26.  
  27. --Smoothed aim point offsets for all targets
  28. targaimpoints = {}
  29. targaimpointsz = 0
  30. targaimsmoothing = 1/80
  31.  
  32. ticklen = 1
  33.  
  34. ----------
  35.  
  36. --Calculates target position derivation values for given target 't'
  37. function CalcTargetPosInf(I,t)
  38. if not targposinf[t.Id] then
  39. if targposinfsz >= maxbuffered then targposinf = {}; targposinfsz = 0 end
  40. targposinf[t.Id] = {}
  41. targposinfsz = targposinfsz+1
  42. end
  43. arr = {}
  44. arr[0] = t.Position
  45. arr[1] = t.Velocity
  46. smoothamt = 1
  47. for i=1,maxderive,1 do
  48. oldval = targposinf[t.Id][i-1]
  49. if oldval == nil then break end
  50. arr[i] = (arr[i-1]-oldval)*(1/ticklen)
  51. arr[i] = arr[i]*smoothamt + (targposinf[t.Id][i] or Vector3(0,0,0))*(1-smoothamt)
  52.  
  53. smoothamt = smoothamt*smoothrate
  54. end
  55. targposinf[t.Id]=arr
  56. return targposinf[t.Id]
  57. end
  58.  
  59. function SmoothTargetAimPoint(I,t)
  60. if not targaimpoints[t.Id] then
  61. if targaimpointsz >= maxbuffered then targaimpoints = {}; targaimpointsz = 0 end
  62. targaimpoints[t.Id] = Vector3(0,0,0)
  63. end
  64. targaimpoints[t.Id] = (t.AimPointPosition-t.Position)*targaimsmoothing + targaimpoints[t.Id]*(1-targaimsmoothing)
  65. end
  66.  
  67. --Performs per-tick processing on all targets
  68. function UpdateTargets(I)
  69. for i=0,I:GetNumberOfMainframes(),1 do
  70. for j=0,I:GetNumberOfTargets(i),1 do
  71. tmp = I:GetTargetInfo(i,j)
  72. if tmp.Valid then
  73. CalcTargetPosInf(I,tmp)
  74. SmoothTargetAimPoint(I,tmp)
  75. end
  76. end
  77. end
  78. end
  79.  
  80. --Predicts TargetInf 't's predicted location in 'time' seconds
  81. function PredictTargetVel(I,t,time)
  82. arr = targposinf[t.Id]
  83. res = Vector3(0,0,0)
  84. nom = 1
  85. denom = 1
  86. for i=1,maxderive,1 do
  87. if arr[i] == nil then break end
  88. denom = denom*(i)
  89. nom = nom*(time+ticklen*i)
  90. res = res + nom/denom*arr[i]
  91. tmp = nom/denom*arr[i]
  92. end
  93. return res/time
  94. end
  95.  
  96. --Calculates a predicted world position in which a weapon at position 'curpos' with projectile speed 'speed' would hit target 'targ' with gravity multiplier 'gravity'
  97. function CalcAimPos(I,curpos,targ,speed,gravity)
  98. --TODO: Can recalculate Gravity for each iteration to improve accuracy more
  99. aimpos = targaimpoints[targ.Id]+targ.Position
  100.  
  101. diff = aimpos-curpos
  102. tvel = targ.Velocity
  103. --More iterations improves accuracy
  104. for i=1,4,1 do
  105. veldif = diff.normalized*speed-tvel
  106. timetohit = diff.magnitude/math.max(Vector3.Dot(veldif,diff.normalized),0.1)
  107. tvel = PredictTargetVel(I,targ,timetohit)
  108. grav = I:GetGravityForAltitude(curpos.y+diff.y/2.0)*gravity
  109. gravloss = grav*timetohit*(timetohit)*0.5
  110. diff = aimpos-gravloss-curpos
  111. end
  112. timetohit = timetohit
  113. return diff+tvel*timetohit+curpos
  114.  
  115. end
  116.  
  117. --Aims weapon 'wep' at predicted location of target 'targ' and fires if aligned
  118. function FireWeapon(I,wep,targ)
  119. if not targ.Valid then return end
  120. inf = I:GetWeaponInfo(wep)
  121. if not inf.Valid then return end
  122.  
  123. --grav = gravtable[inf.WeaponType] or 1.0
  124. grav = 1.0 --TODO: gravtable is not working, weapon type is turret for each
  125. speed = inf.Speed
  126. res = CalcAimPos(I,inf.GlobalFirePoint,targ,speed,grav)-inf.GlobalFirePoint
  127.  
  128. I:AimWeaponInDirection(wep,res.x,res.y,res.z,0)
  129. --TODO: Move next line to its own function that finds target painters based on weapon entity's sub-block
  130. --I:Component_SetFloatLogic(13,0,timetohit)
  131. --TODO: Only fire if inf.CurrentDirection is within acceptable limits
  132. I:FireWeapon(wep,0)
  133. end
  134.  
  135. ----------
  136.  
  137. function Update(I)
  138. curtime = I:GetGameTime()
  139. ticklen = curtime - (lasttick or curtime-1)
  140. lasttick = curtime
  141.  
  142. UpdateTargets(I)
  143.  
  144. --Select a target to fire at
  145. --TODO: Implement a system to assign weapon system to certain mainframes, probably requires using block names
  146. targ = nil
  147. for i=0,I:GetNumberOfMainframes(),1 do
  148. for j=0,I:GetNumberOfTargets(i),1 do
  149. targ = I:GetTargetInfo(i,j)
  150. if targ.Valid then break end
  151. end
  152. if targ.Valid then break end
  153. end
  154. --Fire weapons
  155. if targ.Valid then
  156. for i=1,I:GetWeaponCount(),1 do
  157. FireWeapon(I,i,targ)
  158. end
  159. end
  160. if not targ.Valid then return end
  161.  
  162. trans = I:GetLuaTransceiverCount()
  163. for i=0,trans,1 do
  164. missiles = I:GetLuaControlledMissileCount(i)
  165. for j=0,missiles,1 do
  166. inf = I:GetLuaControlledMissileInfo(i,j)
  167. aim = CalcAimPos(I,inf.Position,targ,381,1)
  168. if inf.TimeSinceLaunch >= 3 and Vector3.Angle(aim-inf.Position,inf.Velocity)>=missiledetang then
  169. I:DetonateLuaControlledMissile(i,j)
  170. end
  171. I:SetLuaControlledMissileAimPoint(i,j,aim.x,aim.y,aim.z)
  172. end
  173. end
  174. end
  175.  
Advertisement
Add Comment
Please, Sign In to add comment