Skip to content

Commit

Permalink
Improvements to ScanManager's code
Browse files Browse the repository at this point in the history
Fixes for this problems:
1. ScanManager: StartScanCallback had no way to determine if the current ScanManager was loaded from save when it needed to set up a callback;
2. The orbital scanning stopped when the frame of reference changed.
  • Loading branch information
Max5377 committed Sep 29, 2023
1 parent a6c5722 commit 00bdecc
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 16 deletions.
5 changes: 3 additions & 2 deletions data/modules/Scout/ScanDisplay.lua
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,9 @@ function scanDisplay:drawDebug()
minRes = ui.dragFloat("MinRes", minRes, 1.0, 0.1, 100, "%f")
coverage = ui.dragFloat("Coverage", coverage, 0.5, 0.5, 100, "%fkm^2")

if scanMgr:GetActiveScan() then
local altitude, resolution = scanMgr:GetBodyState(self.ship.frameBody)
local activeScan = scanMgr:GetActiveScan()
if activeScan then
local altitude, resolution = scanMgr:GetBodyState(scanMgr:GetScanBodyByType())

ui.text("Current Alt: " .. altitude)
ui.text("Current Res: " .. resolution)
Expand Down
59 changes: 45 additions & 14 deletions data/modules/Scout/ScanManager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -221,17 +221,27 @@ function ScanManager:UpdateSensorEquipInfo()

end

---@param ScanData scan
---@return Body
function ScanManager:GetScanBodyByType(scan)
scan = scan or self.activeScan
assert(self.scanMap[scan.id])
return scan.orbital and scan.bodyPath:GetSystemBody().body or self.ship.frameBody
end

---@param body Body
---@param ScanData scan
---@return number altitude
---@return number resolution
function ScanManager:GetBodyState(body)
assert(self.activeScan)
function ScanManager:GetBodyState(body, scan)
scan = scan or self.activeScan
assert(self.scanMap[scan.id])

local altitude
local radius = body:GetSystemBody().radius
local sensor = self.activeSensor

if self.activeScan.orbital then
if scan.orbital then
-- altitude above sea-level
altitude = self.ship:GetPositionRelTo(body):length() - radius
else
Expand Down Expand Up @@ -261,7 +271,8 @@ function ScanManager:GetState()
end

if self.activeScan then
local altitude, resolution = self:GetBodyState(self.ship.frameBody)
local body = self:GetScanBodyByType()
local altitude, resolution = self:GetBodyState(body)
local isInRange = resolution <= self.activeScan.minResolution

if altitude > self.activeSensor.minAltitude then
Expand Down Expand Up @@ -425,12 +436,19 @@ function ScanManager:CanScanBeActivated(id)

if scan.complete then return false end

local frameBody = self.ship.frameBody
if not frameBody then return false end
local body = self:GetScanBodyByType(scan)
if not body then return false end

if frameBody.path ~= scan.bodyPath then
if body.path ~= scan.bodyPath then
return false
end

if scan.orbital then
local altitude, resolution = self:GetBodyState(body, scan)
if(resolution > (scan.minResolution * 1.10)) then
return false
end
end

if scan.orbital ~= self.activeSensor.orbital then
return false
Expand Down Expand Up @@ -490,7 +508,9 @@ end
---@package
function ScanManager:OnEnteredFrame(body)
if self.activeScan then

if self.activeScan.orbital then
return
end
local frameBody = body.frameBody

if not frameBody or frameBody.path ~= self.activeScan.bodyPath then
Expand All @@ -501,22 +521,24 @@ function ScanManager:OnEnteredFrame(body)
end

-- Start the scanner callback
---@param force boolean
---@package
function ScanManager:StartScanCallback()
function ScanManager:StartScanCallback(force)
local updateRate = self.activeScan.orbital and ORBITAL_SCAN_UPDATE_RATE or SURFACE_SCAN_UPDATE_RATE

-- Immediately trigger a scan update for responsiveness
self:OnUpdateScan(self.activeScan)

-- Don't queue a new scan callback if we're already running one at the right frequency
if updateRate == self.activeCallback then
-- Force this check if this function was called from ScanManager:Unserialize() because
-- callback is not yet setted up
if updateRate == self.activeCallback and not force then
return
end

self.activeCallback = updateRate

Timer:CallEvery(updateRate, function()

-- cancel this callback if the parameters have changed (it's been orphaned)
if not self.activeScan or not self.activeSensor or self.activeCallback ~= updateRate then
return true
Expand All @@ -532,21 +554,30 @@ end
---@return boolean cancel
---@package
function ScanManager:OnUpdateScan(scan)
local body = self.ship.frameBody
local body = self:GetScanBodyByType(scan)

-- Somehow we don't have a valid body to be scanning
if not body then
logWarning("ScanManager: owning ship does not have a frameBody to scan!")
logWarning("ScanManager: owning ship does not have a system body to scan!")
self:ClearActiveScan()
return true
end

local radius = body:GetSystemBody().radius
local altitude, resolution = self:GetBodyState(body)
local currentScanPos = self.ship:GetPositionRelTo(body):normalized()

if scan.orbital then
if(resolution > (scan.minResolution * 1.10)) then
self:ClearActiveScan()
return true
end
end

-- Determine if we're currently in range to record scan data
local withinParams = resolution <= scan.minResolution and altitude > self.activeSensor.minAltitude



-- Use great-arc distance to calculate the amount of scan coverage in square meters
-- distance = Δσ * radius = arctan( |n1 ⨯ n2| / n1 · n2 ) * radius
Expand Down Expand Up @@ -610,7 +641,7 @@ function ScanManager:Unserialize()

-- Restore the scanning callback on loading a saved game
if self.activeCallback then
self:StartScanCallback()
self:StartScanCallback(true)
end

return self
Expand Down

0 comments on commit 00bdecc

Please sign in to comment.