Files
spearhead/classes/capClasses/runwayBombing/RunwayBombingTracker.lua
T
dutchie031andGitHub a2f62d797b Feature/mission refactor (#26)
* Refactored Mission classes to add Missions other than trigger zone missions. (eg. Runway Strikes, Resupply etc.)
* Runway strike initial POC
Co-authored-by: dutchie032 <dutchie032>
2025-05-07 13:18:45 +02:00

129 lines
3.5 KiB
Lua

---@class RunwayBombingTracker : OnWeaponFiredListener
---@field trackedRunways table<Runway, RunwayStrikeMission>
---@field private _logger Logger
local RunwayBombingTracker = {}
RunwayBombingTracker.__index = RunwayBombingTracker
--- Constructor
--- @param logger Logger
--- @return RunwayBombingTracker
function RunwayBombingTracker.new(logger)
local self = setmetatable({}, RunwayBombingTracker)
self._logger = logger
Spearhead.Events.AddWeaponFiredListener(self)
return self
end
---comment
---@param weapon Weapon
function RunwayBombingTracker:OnWeaponFired(unit, weapon, target)
if weapon == nil then
return
end
self._logger:debug("Tracking weapon for runway impact onWeaponFired")
local desc = weapon:getDesc()
local isTrackable = desc.category == Weapon.Category.BOMB or (desc.category == Weapon.Category.MISSILE and desc.missileCategory == Weapon.MissileCategory.CRUISE)
if isTrackable == true then
---@type WeaponTrackingArgs
local weaponTrackingArgs = {
weapon = weapon,
self = self
}
timer.scheduleFunction(RunwayBombingTracker.trackWeaponTask, weaponTrackingArgs, timer.getTime() + 1)
end
end
function RunwayBombingTracker:RegisterRunway(runway, strikeMission)
if not self.trackedRunways then
self.trackedRunways = {}
end
if not self.trackedRunways[runway] then
self.trackedRunways[runway] = strikeMission
end
end
---@class WeaponTrackingArgs
---@field weapon Weapon
---@field self RunwayBombingTracker
---@private
---@param weaponTrackingArgs WeaponTrackingArgs
function RunwayBombingTracker.trackWeaponTask(weaponTrackingArgs, time)
local weapon = weaponTrackingArgs.weapon
local self = weaponTrackingArgs.self
if not weapon then return nil end
local pos = weapon:getPoint()
local velocity = weapon:getVelocity()
local ground = land.getHeight({ x = pos.x, y = pos.z })
local MpS = velocity.y -- increase the speed to make sure you don't miss it.
if MpS > 0 then
return time + 3
end
local nextInterval = (pos.y - ground) / math.abs(MpS)
if nextInterval < 1 then
-- Calculate the impact point of the weapon
---@type Vec2
local impactPoint = {
x = pos.x + velocity.x * nextInterval,
y = pos.z + velocity.z * nextInterval
}
self:OnWeaponImpact(weapon:getDesc(), impactPoint)
return nil
end
if nextInterval > 5 then
nextInterval = 5
end
return time + (nextInterval /2)
end
---comment
---@param weaponDesc table
---@param impactPoint Vec2
function RunwayBombingTracker:OnWeaponImpact(weaponDesc, impactPoint)
self._logger:debug("RunwayBombingTracker:OnWeaponImpact")
local warhead = weaponDesc.warhead
local explosiveMass = warhead.explosiveMass or warhead.shapedExplosiveMass
for runway, strikeMission in pairs(self.trackedRunways) do
local zone= strikeMission:GetRunwayZone()
if Spearhead.Util.is3dPointInZone({ x = impactPoint.x, z = impactPoint.y, y = 0 }, zone) then
strikeMission:RunwayHit(impactPoint, explosiveMass)
end
end
end
if not Spearhead then Spearhead = {} end
if not Spearhead.classes then Spearhead.classes = {} end
if not Spearhead.classes.capClasses then Spearhead.classes.capClasses = {} end
if not Spearhead.classes.capClasses.runwayBombing then Spearhead.classes.capClasses.runwayBombing = {} end
Spearhead.classes.capClasses.runwayBombing.RunwayBombingTracker = RunwayBombingTracker