Skip to content

Commit

Permalink
Merge pull request #5635 from Max5377/Scanner-and-ship's-cargo-fixes
Browse files Browse the repository at this point in the history
ScanManager improvements and ship properties fixes
  • Loading branch information
Webster Sheets authored Oct 8, 2023
2 parents f07bbc1 + bc4f1c5 commit a15429a
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 26 deletions.
13 changes: 10 additions & 3 deletions data/libs/CargoManager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,14 @@ function CargoManager:Constructor(ship)
self.usedCargoMass = 0

-- Initialize property variables on owning ship for backwards compatibility
ship:setprop("totalCargo", self:GetTotalSpace())
ship:setprop("usedCargo", 0)
-- don't initialize them if they're already created after first save
if not self.ship:hasprop("totalCargo") then
ship:setprop("totalCargo", self:GetTotalSpace())
end

if not self.ship:hasprop("usedCargo") then
ship:setprop("usedCargo", 0)
end

-- TODO: stored commodities should be represented as array of { name, count, meta } entries
-- to allow for e.g. tracking stolen/scooped cargo, or special mission-related cargoes
Expand Down Expand Up @@ -99,7 +105,7 @@ end
function CargoManager:AddCommodity(type, count)
-- TODO: use a cargo volume metric with variable mass instead of fixed 1m^3 == 1t
local required_space = (type.mass or 1) * (count or 1)

if self:GetFreeSpace() < required_space then
return false
end
Expand Down Expand Up @@ -245,6 +251,7 @@ end
function CargoManager:Unserialize()
setmetatable(self, CargoManager.meta)
self.listeners = {}

return self
end

Expand Down
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
61 changes: 47 additions & 14 deletions data/modules/Scout/ScanManager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -221,17 +221,29 @@ function ScanManager:UpdateSensorEquipInfo()

end

---@param ScanData scan
---@return Body
function ScanManager:GetScanBodyByType(scan)
scan = scan or self.activeScan
assert(scan, "ScanManager:GetScanBodyByType: Error: scan was nil")
assert(self.scanMap[scan.id], "ScanManager:GetScanBodyByType: Error: scan doesn't belong to current ScanManager")
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(scan, "ScanManager:GetBodyState: Error: scan was nil")
assert(self.scanMap[scan.id], "ScanManager:GetBodyState: Error: scan doesn't belong to current ScanManager")

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 +273,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 +438,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 +510,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 +523,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 +556,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 +643,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
8 changes: 4 additions & 4 deletions src/Game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,17 +375,17 @@ bool Game::UpdateTimeAccel()

vector3d toBody = m_player->GetPosition() - b->GetPositionRelTo(m_player->GetFrame());
double dist = toBody.Length();
double rad = b->GetPhysRadius();
double rad = std::max(b->GetPhysRadius(), 10000.0);

if (dist < 1000.0) {
newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1X);
} else if (dist < std::min(rad + 0.0001 * AU, rad * 1.1)) {
newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10X);
} else if (dist < std::min(rad + 0.001 * AU, rad * 5.0)) {
} else if (dist < std::min(rad + 0.001 * AU, rad * 2.5)) {
newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_100X);
} else if (dist < std::min(rad + 0.01 * AU, rad * 10.0)) {
} else if (dist < std::min(rad + 0.01 * AU, rad * 5.0)) {
newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_1000X);
} else if (dist < std::min(rad + 0.1 * AU, rad * 1000.0)) {
} else if (dist < std::min(rad + 0.1 * AU, rad * 500.0)) {
newTimeAccel = std::min(newTimeAccel, Game::TIMEACCEL_10000X);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ void Ship::UpdateLuaStats()
m_stats.hyperspace_range = m_stats.hyperspace_range_max = 0;
int hyperclass = p.Get("hyperclass_cap");
if (hyperclass) {
std::tie(m_stats.hyperspace_range_max, m_stats.hyperspace_range) =
std::tie(m_stats.hyperspace_range, m_stats.hyperspace_range_max) =
LuaObject<Ship>::CallMethod<double, double>(this, "GetHyperspaceRange");
}

Expand Down
6 changes: 4 additions & 2 deletions src/Space.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -756,9 +756,11 @@ static FrameId MakeFramesFor(const double at_time, SystemBody *sbody, Body *b, F

if ((supertype == SystemBody::SUPERTYPE_GAS_GIANT) ||
(supertype == SystemBody::SUPERTYPE_ROCKY_PLANET)) {
// for planets we want an non-rotating frame for a few radii
// for planets we want an non-rotating frame covering its Hill radius
// and a rotating frame with no radius to contain attached objects
double frameRadius = std::max(4.0 * sbody->GetRadius(), sbody->GetMaxChildOrbitalDistance() * 1.05);
double hillRadius = sbody->GetSemiMajorAxis() * (1.0 - sbody->GetEccentricity()) * pow(sbody->GetMass() / (3.0 * sbody->GetParent()->GetMass()), 1.0 / 3.0);
double frameRadius = std::max(hillRadius, sbody->GetMaxChildOrbitalDistance() * 1.05);
frameRadius = std::max(sbody->GetRadius() * 4.0, frameRadius);
FrameId orbFrameId = Frame::CreateFrame(fId,
sbody->GetName().c_str(),
Frame::FLAG_HAS_ROT,
Expand Down

0 comments on commit a15429a

Please sign in to comment.