mirror of
https://github.com/iTracerFacer/Moose_CTLD_Pure.git
synced 2025-12-03 04:11:57 +00:00
Bug fixes.
This commit is contained in:
parent
ff8cbd9a33
commit
70842b241d
@ -10712,7 +10712,8 @@ function CTLD:SpawnFARPStatics(zoneName, stage, centerPoint, coalition)
|
|||||||
_logInfo(string.format('Spawning FARP Stage %d statics for zone %s (coalition %d)', stage, zoneName, coalition))
|
_logInfo(string.format('Spawning FARP Stage %d statics for zone %s (coalition %d)', stage, zoneName, coalition))
|
||||||
|
|
||||||
-- Get coalition name for DCS
|
-- Get coalition name for DCS
|
||||||
local coalitionName = (coalition == coalition.side.BLUE) and 'blue' or 'red'
|
-- Note: 'coalition' parameter is a number (1=red, 2=blue), not the coalition table
|
||||||
|
local coalitionName = (coalition == 2) and 'blue' or 'red'
|
||||||
|
|
||||||
for _, obj in ipairs(layout) do
|
for _, obj in ipairs(layout) do
|
||||||
-- Calculate world position from relative offset
|
-- Calculate world position from relative offset
|
||||||
|
|||||||
@ -80,8 +80,8 @@ THREAT_CHECK_INTERVAL = 3 -- Faster sweeps so we tag threats before co
|
|||||||
-- Distance Thresholds (in meters)
|
-- Distance Thresholds (in meters)
|
||||||
DESTINATION_REACHED_DISTANCE = 100 -- Distance to consider destination reached
|
DESTINATION_REACHED_DISTANCE = 100 -- Distance to consider destination reached
|
||||||
MINIMUM_ROUTE_DISTANCE = 5000 -- Minimum distance from spawn to destination (prevents exploits)
|
MINIMUM_ROUTE_DISTANCE = 5000 -- Minimum distance from spawn to destination (prevents exploits)
|
||||||
THREAT_DETECTION_RANGE = 10000 -- Detect armor ahead of effective weapon range
|
THREAT_DETECTION_RANGE = 5000 -- Detect armor ahead of effective weapon range
|
||||||
THREAT_CLEARED_RANGE = 11000 -- Give a little buffer before calling area safe
|
THREAT_CLEARED_RANGE = 6000 -- Give a little buffer before calling area safe
|
||||||
|
|
||||||
ROUTE_CHECK_INTERVAL = 3 -- Seconds between route integrity scans
|
ROUTE_CHECK_INTERVAL = 3 -- Seconds between route integrity scans
|
||||||
ROUTE_DEVIATION_THRESHOLD = 750 -- Meters away from mission destination before re-routing
|
ROUTE_DEVIATION_THRESHOLD = 750 -- Meters away from mission destination before re-routing
|
||||||
@ -129,6 +129,7 @@ MOOSE_CONVOY = {
|
|||||||
IntelMarkLookup = {}, -- Fast lookup for intel mark IDs
|
IntelMarkLookup = {}, -- Fast lookup for intel mark IDs
|
||||||
MarkIdCounter = 0, -- Sequential mark IDs for intel marks
|
MarkIdCounter = 0, -- Sequential mark IDs for intel marks
|
||||||
LastSmokeTime = {}, -- Per-convoy last smoke timestamp
|
LastSmokeTime = {}, -- Per-convoy last smoke timestamp
|
||||||
|
ThreatScanSets = {}, -- Cached SET_GROUP objects for threat detection (per coalition)
|
||||||
}
|
}
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
@ -763,6 +764,21 @@ function MOOSE_CONVOY:GetConvoyByUnitName(unitName)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get or create cached threat scan SET_GROUP for a coalition
|
||||||
|
-- @param #string enemyCoalition Coalition string ("red" or "blue")
|
||||||
|
-- @return #SET_GROUP Cached or new scan set
|
||||||
|
function MOOSE_CONVOY:GetThreatScanSet(enemyCoalition)
|
||||||
|
if not self.ThreatScanSets[enemyCoalition] then
|
||||||
|
self:Log("DEBUG", string.format("Creating cached threat scan set for %s coalition", enemyCoalition))
|
||||||
|
self.ThreatScanSets[enemyCoalition] = SET_GROUP:New()
|
||||||
|
:FilterCoalitions(enemyCoalition)
|
||||||
|
:FilterCategoryGround()
|
||||||
|
:FilterActive(true)
|
||||||
|
:FilterStart()
|
||||||
|
end
|
||||||
|
return self.ThreatScanSets[enemyCoalition]
|
||||||
|
end
|
||||||
|
|
||||||
--- Determine current speed of the convoy in km/h (first alive unit sample)
|
--- Determine current speed of the convoy in km/h (first alive unit sample)
|
||||||
-- @return #number Speed in km/h
|
-- @return #number Speed in km/h
|
||||||
function MOOSE_CONVOY:GetCurrentSpeedKmh()
|
function MOOSE_CONVOY:GetCurrentSpeedKmh()
|
||||||
@ -1007,6 +1023,21 @@ function MOOSE_CONVOY:MonitorRouteIntegrity(forceOverride)
|
|||||||
local distance = math.sqrt(dx * dx + dy * dy)
|
local distance = math.sqrt(dx * dx + dy * dy)
|
||||||
|
|
||||||
if distance > ROUTE_DEVIATION_THRESHOLD then
|
if distance > ROUTE_DEVIATION_THRESHOLD then
|
||||||
|
-- Edge case: If convoy is far from destination and possibly backtracking to reach
|
||||||
|
-- the road network, allow more tolerance before declaring a deviation
|
||||||
|
local currentPos = self.Group:GetCoordinate()
|
||||||
|
if currentPos and self.DestPoint then
|
||||||
|
local distToDestination = currentPos:Get2DDistance(self.DestPoint)
|
||||||
|
local speed = self:GetCurrentSpeedKmh()
|
||||||
|
|
||||||
|
-- If we're moving and still far from destination, convoy might be taking
|
||||||
|
-- an indirect route to reach roads. Give it time unless deviation is extreme.
|
||||||
|
if speed > 0.5 and distToDestination > (self.InitialDistance * 0.8) and distance < (ROUTE_DEVIATION_THRESHOLD * 2) then
|
||||||
|
self:Log("DEBUG", string.format("%s route deviation %.0fm during initial navigation - allowing indirect path", self.Name, distance))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if lastCommand > 0 and (now - lastCommand) < ROUTE_REISSUE_MIN_INTERVAL then
|
if lastCommand > 0 and (now - lastCommand) < ROUTE_REISSUE_MIN_INTERVAL then
|
||||||
self.RouteNeedsRefresh = true
|
self.RouteNeedsRefresh = true
|
||||||
return
|
return
|
||||||
@ -1201,6 +1232,9 @@ function MOOSE_CONVOY:HandleUnitHit(EventData)
|
|||||||
local convoy = self:GetConvoyByUnitName(unitName)
|
local convoy = self:GetConvoyByUnitName(unitName)
|
||||||
if not convoy then return end
|
if not convoy then return end
|
||||||
|
|
||||||
|
-- Ensure cache is current for accurate tracking
|
||||||
|
convoy:CacheUnitNames()
|
||||||
|
|
||||||
local attacker = EventData.IniUnit or EventData.IniDCSUnit or EventData.WeaponOwner
|
local attacker = EventData.IniUnit or EventData.IniDCSUnit or EventData.WeaponOwner
|
||||||
convoy:OnUnderFire(attacker, targetUnit, EventData)
|
convoy:OnUnderFire(attacker, targetUnit, EventData)
|
||||||
end
|
end
|
||||||
@ -1218,6 +1252,7 @@ function MOOSE_CONVOY:HandleUnitDead(EventData)
|
|||||||
if not convoy then return end
|
if not convoy then return end
|
||||||
|
|
||||||
convoy.UnitNames[unitName] = nil
|
convoy.UnitNames[unitName] = nil
|
||||||
|
convoy.UnitNamesDirty = true -- Mark for rebuild on next check
|
||||||
convoy:CacheUnitNames()
|
convoy:CacheUnitNames()
|
||||||
|
|
||||||
local attacker = EventData.TgtUnit or EventData.WeaponOwner
|
local attacker = EventData.TgtUnit or EventData.WeaponOwner
|
||||||
@ -1263,6 +1298,7 @@ function MOOSE_CONVOY:NewConvoy(templateName, spawnPoint, destPoint, convoyCoali
|
|||||||
SchedulerID = nil,
|
SchedulerID = nil,
|
||||||
ContactReason = nil,
|
ContactReason = nil,
|
||||||
UnitNames = {},
|
UnitNames = {},
|
||||||
|
UnitNamesDirty = true, -- Flag to rebuild unit name cache when needed
|
||||||
LastUnderFireAlert = 0,
|
LastUnderFireAlert = 0,
|
||||||
LastHoldEnforce = 0,
|
LastHoldEnforce = 0,
|
||||||
LastRouteReissue = 0,
|
LastRouteReissue = 0,
|
||||||
@ -1315,7 +1351,12 @@ function MOOSE_CONVOY:Spawn()
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Refresh cached unit name lookups for this convoy
|
--- Refresh cached unit name lookups for this convoy
|
||||||
function MOOSE_CONVOY:CacheUnitNames()
|
-- @param #boolean force Force rebuild even if not dirty
|
||||||
|
function MOOSE_CONVOY:CacheUnitNames(force)
|
||||||
|
if not force and not self.UnitNamesDirty then
|
||||||
|
return -- Cache is still valid
|
||||||
|
end
|
||||||
|
|
||||||
self.UnitNames = {}
|
self.UnitNames = {}
|
||||||
if not self.Group then return end
|
if not self.Group then return end
|
||||||
local units = self.Group:GetUnits()
|
local units = self.Group:GetUnits()
|
||||||
@ -1328,6 +1369,7 @@ function MOOSE_CONVOY:CacheUnitNames()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
self.UnitNamesDirty = false
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Called when convoy is spawned
|
--- Called when convoy is spawned
|
||||||
@ -1497,11 +1539,8 @@ function MOOSE_CONVOY:CheckForThreats()
|
|||||||
|
|
||||||
local enemyCoalition = (self.Coalition == coalition.side.RED) and "blue" or "red"
|
local enemyCoalition = (self.Coalition == coalition.side.RED) and "blue" or "red"
|
||||||
|
|
||||||
local scanSet = SET_GROUP:New()
|
-- Use cached SET_GROUP for better performance
|
||||||
:FilterCoalitions(enemyCoalition)
|
local scanSet = MOOSE_CONVOY:GetThreatScanSet(enemyCoalition)
|
||||||
:FilterCategoryGround()
|
|
||||||
:FilterActive(true)
|
|
||||||
:FilterOnce()
|
|
||||||
|
|
||||||
local threatsFound = false
|
local threatsFound = false
|
||||||
local closestThreat = nil
|
local closestThreat = nil
|
||||||
@ -1672,11 +1711,8 @@ function MOOSE_CONVOY:CheckThreatsCleared()
|
|||||||
|
|
||||||
local enemyCoalition = (self.Coalition == coalition.side.RED) and "blue" or "red"
|
local enemyCoalition = (self.Coalition == coalition.side.RED) and "blue" or "red"
|
||||||
|
|
||||||
local scanSet = SET_GROUP:New()
|
-- Use cached SET_GROUP for better performance
|
||||||
:FilterCoalitions(enemyCoalition)
|
local scanSet = MOOSE_CONVOY:GetThreatScanSet(enemyCoalition)
|
||||||
:FilterCategoryGround()
|
|
||||||
:FilterActive(true)
|
|
||||||
:FilterOnce()
|
|
||||||
|
|
||||||
local threatsRemain = false
|
local threatsRemain = false
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user