Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- LAUNCHER_NAME = nil -- "<NAME>"
- MISSILE_CRUISE_ALTITUDE = 500
- MISSILE_TERMINAL_DISTANCE = 500
- MISSILE_TERMINAL_THRUST = nil -- 1000
- missiles = {}
- targets = {}
- function Update(I)
- I:ClearLogs()
- UpdateTargets(I)
- if(HasTarget()) then
- I:Log("Has Target")
- else
- I:Log("No Target")
- return
- end
- local count = I:GetLuaTransceiverCount()
- for i = 0, count -1 do
- UpdateTransceiver(I, i)
- end
- end
- function UpdateTransceiver(I, TI)
- local t = I:GetLuaTransceiverInfo(TI)
- if LAUNCHER_NAME and t.CustomName ~= LAUNCHER_NAME then
- return
- end
- local missile_count = I:GetLuaControlledMissileCount(TI)
- for m = 0, missile_count - 1 do
- local missile_id = UpdateMissile(I, TI, m)
- SetMissileMode(I, missile_id)
- SetAimpoint(I, missile_id)
- end
- end
- function SetMissileMode(I, missile_id)
- local pos = missiles[missile_id].pos
- local aimpoint = I:GetTargetInfo(0, targets[1]).AimPointPosition
- if not missiles[missile_id] then
- missiles[missile_id] = "climb"
- return
- end
- if missiles[missile_id].mode == "climb" and missiles[missile_id].pos.y > MISSILE_CRUISE_ALTITUDE then
- missiles[missile_id].mode = "cruise"
- return
- end
- local surface_distance = XZDistance(pos, aimpoint)
- if missiles[missile_id].mode == "cruise" and surface_distance < MISSILE_TERMINAL_DISTANCE then
- missiles[missile_id].mode = "terminal"
- return
- end
- end
- function SetAimpoint(I, missile_id)
- local target = I:GetTargetInfo(0, targets[1])
- local aimpoint = target.AimPointPosition
- local pos = missiles[missile_id].pos
- local vel = missiles[missile_id].vel
- if missiles[missile_id].mode == "climb" then
- aimpoint = pos + (vel.normalized * 30)
- aimpoint.y = aimpoint.y + 30
- end
- if missiles[missile_id].mode == "cruise" then
- aimpoint = CalcPredictiveAimpoint(target.AimPointPosition, target.Velocity, pos, vel)
- aimpoint.y = pos.y
- end
- if missiles[missile_id].mode == "terminal" then
- aimpoint = CalcPredictiveAimpoint(target.AimPointPosition, target.Velocity, pos, vel)
- if HasVariableThruster(I, missile_id) and MISSILE_TERMINAL_THRUST then
- SetThrust(I, missile_id, MISSILE_TERMINAL_THRUST)
- end
- end
- I:SetLuaControlledMissileAimPoint(missiles[missile_id].transceiver_index, missiles[missile_id].index, aimpoint.x, aimpoint.y, aimpoint.z)
- end
- --TI: Transceiver Index
- --MI: Missile Index
- function UpdateMissile(I, TI, MI)
- I:Log("UpdateMissile")
- local missile = I:GetLuaControlledMissileInfo(TI,MI)
- local missile_id = missile.Id
- if missile.Valid == false then
- missiles[missile_id] = nil
- return
- end
- if not contains(missiles, missile_id) then
- missiles[missile_id] = {}
- missiles[missile_id].mode = "climb"
- I:Log("New Missile")
- end
- missiles[missile_id].transceiver_index = TI
- missiles[missile_id].index = MI
- missiles[missile_id].pos = missile.Position
- missiles[missile_id].vel = missile.Velocity
- local message = string.format("Missile %d %s", missile_id, missiles[missile_id].mode)
- I:LogToHud(message)
- I:Log(message)
- return missile_id
- end
- function UpdateTargets(I)
- targets = {} -- Clear the array
- local nr_targets = I:GetNumberOfTargets(0)
- if nr_targets == 0 then
- return
- end
- for i = 0, nr_targets - 1 do
- local target = I:GetTargetInfo(0, i)
- if target.Valid then
- table.insert(targets, i) -- Use table.insert to add to the array
- end
- end
- table.sort(targets, function(a, b)
- return a.Priority < b.Priority
- end)
- end
- function HasTarget()
- return #targets > 0
- end
- function CalcPredictiveAimpoint(target_position, target_velocity, missile_position, missile_velocity)
- local missile_speed = Vector3.Magnitude(missile_velocity)
- local target_distance = Vector3.Distance(target_position, missile_position)
- local target_vector = Vector3.Normalize(target_position - missile_position)
- local relative_speed = missile_speed - Vector3.Dot(target_vector, target_velocity)
- local prediction = target_velocity*target_distance/relative_speed
- local intercept = target_position + prediction
- local intercept_vector = Vector3.Normalize(intercept - missile_position)
- local aimpoint = missile_position + intercept_vector*missile_speed
- return aimpoint
- end
- function HasVariableThruster(I, missile_id)
- local parts = I:GetMissileInfo(missiles[missile_id].transceiver_index, missiles[missile_id].index).Parts
- if string.find(parts[1].Name,'Variable thruster') then
- return true
- end
- return false
- end
- function SetThrust(I, missile_id, thrust)
- local parts = I:GetMissileInfo(missiles[missile_id].transceiver_index, missiles[missile_id].index).Parts
- local thruster = parts[1]
- thruster:SendRegister(2, thrust)
- end
- function GetFuel()
- local parts = I:GetMissileInfo(missiles[missile_id].transceiver_index, missiles[missile_id].index).Parts
- local fuel = 0
- for k=1, #parts do
- if string.find(parts[k].Name,'Fuel tank') then
- fuel = reservefuel + 5000
- end
- end
- end
- function contains(table, item)
- for key, value in pairs(table) do
- if key == item then
- return true
- end
- end
- return false
- end
- function XZDistance(p1, p2)
- return math.sqrt((p1.x - p2.x)^2 + (p1.z - p2.z)^2)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement