mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
New sophisticated FindParkingSpot routine.
AIRBASE: - Added new find parking spot routine. Taking into accound dimension of AC etc. - Added more termial type combinations. COORDINATE: - minor changes in scanobjects() function. RAT and SPAWN - improved modifyspawntemplate() function ==> new find routine, helos
This commit is contained in:
parent
bfbdb37b65
commit
08ea3cd219
@ -302,7 +302,7 @@ do -- COORDINATE
|
|||||||
-- @return Static objects found.
|
-- @return Static objects found.
|
||||||
-- @return Scenery objects found.
|
-- @return Scenery objects found.
|
||||||
function COORDINATE:ScanObjects(radius)
|
function COORDINATE:ScanObjects(radius)
|
||||||
env.info(string.format("FF Scanning in radius %.1f m.", radius))
|
self:T(string.format("Scanning in radius %.1f m.", radius))
|
||||||
|
|
||||||
local SphereSearch = {
|
local SphereSearch = {
|
||||||
id = world.VolumeType.SPHERE,
|
id = world.VolumeType.SPHERE,
|
||||||
@ -328,7 +328,8 @@ do -- COORDINATE
|
|||||||
local ObjectCategory = ZoneObject:getCategory()
|
local ObjectCategory = ZoneObject:getCategory()
|
||||||
|
|
||||||
-- Check for unit or static objects
|
-- Check for unit or static objects
|
||||||
if (ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive()) then
|
--if (ObjectCategory == Object.Category.UNIT and ZoneObject:isExist() and ZoneObject:isActive()) then
|
||||||
|
if (ObjectCategory == Object.Category.UNIT and ZoneObject:isExist()) then
|
||||||
|
|
||||||
table.insert(Units, ZoneObject)
|
table.insert(Units, ZoneObject)
|
||||||
gotunits=true
|
gotunits=true
|
||||||
@ -354,14 +355,18 @@ do -- COORDINATE
|
|||||||
world.searchObjects({Object.Category.UNIT, Object.Category.STATIC, Object.Category.SCENERY}, SphereSearch, EvaluateZone)
|
world.searchObjects({Object.Category.UNIT, Object.Category.STATIC, Object.Category.SCENERY}, SphereSearch, EvaluateZone)
|
||||||
|
|
||||||
for _,unit in pairs(Units) do
|
for _,unit in pairs(Units) do
|
||||||
env.info(string.format("FF found unit %s", unit:getName()))
|
self:T(string.format("Scan found unit %s", unit:getName()))
|
||||||
end
|
end
|
||||||
for _,static in pairs(Statics) do
|
for _,static in pairs(Statics) do
|
||||||
env.info(string.format("FF found unit %s", static:getName()))
|
self:T(string.format("Scan found static %s", static:getName()))
|
||||||
|
end
|
||||||
|
for _,scenery in pairs(Scenery) do
|
||||||
|
self:T(string.format("Scan found scenery %s", scenery:getName()))
|
||||||
end
|
end
|
||||||
|
|
||||||
return gotunits, gotstatics, gotscenery, Units, Statics, Scenery
|
return gotunits, gotstatics, gotscenery, Units, Statics, Scenery
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Calculate the distance from a reference @{#COORDINATE}.
|
--- Calculate the distance from a reference @{#COORDINATE}.
|
||||||
-- @param #COORDINATE self
|
-- @param #COORDINATE self
|
||||||
-- @param #COORDINATE PointVec2Reference The reference @{#COORDINATE}.
|
-- @param #COORDINATE PointVec2Reference The reference @{#COORDINATE}.
|
||||||
|
|||||||
@ -1219,8 +1219,7 @@ end
|
|||||||
-- @param #SPAWN.Takeoff Takeoff (optional) The location and takeoff method. Default is Hot.
|
-- @param #SPAWN.Takeoff Takeoff (optional) The location and takeoff method. Default is Hot.
|
||||||
-- @param #number TakeoffAltitude (optional) The altitude above the ground.
|
-- @param #number TakeoffAltitude (optional) The altitude above the ground.
|
||||||
-- @param #number TerminalType (optional) The terminal type the aircraft should be spawned at.
|
-- @param #number TerminalType (optional) The terminal type the aircraft should be spawned at.
|
||||||
-- @return Wrapper.Group#GROUP that was spawned.
|
-- @return Wrapper.Group#GROUP that was spawned or nil when nothing was spawned.
|
||||||
-- @return #nil Nothing was spawned.
|
|
||||||
-- @usage
|
-- @usage
|
||||||
-- Spawn_Plane = SPAWN:New( "Plane" )
|
-- Spawn_Plane = SPAWN:New( "Plane" )
|
||||||
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold )
|
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold )
|
||||||
@ -1237,9 +1236,11 @@ end
|
|||||||
-- Spawn_Heli:SpawnAtAirbase( AIRBASE:FindByName( "FARP Air" ), SPAWN.Takeoff.Air )
|
-- Spawn_Heli:SpawnAtAirbase( AIRBASE:FindByName( "FARP Air" ), SPAWN.Takeoff.Air )
|
||||||
--
|
--
|
||||||
-- Spawn_Heli:SpawnAtAirbase( AIRBASE:FindByName( "Carrier" ), SPAWN.Takeoff.Cold )
|
-- Spawn_Heli:SpawnAtAirbase( AIRBASE:FindByName( "Carrier" ), SPAWN.Takeoff.Cold )
|
||||||
|
--
|
||||||
|
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold, nil, AIRBASE.TerminalType.OpenBig )
|
||||||
--
|
--
|
||||||
function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType ) -- R2.2, R2.4
|
function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType ) -- R2.2, R2.4
|
||||||
self:F( { self.SpawnTemplatePrefix, SpawnAirbase, Takeoff, TakeoffAltitude } )
|
self:F( { self.SpawnTemplatePrefix, SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType } )
|
||||||
|
|
||||||
-- Get position of airbase.
|
-- Get position of airbase.
|
||||||
local PointVec3 = SpawnAirbase:GetCoordinate()
|
local PointVec3 = SpawnAirbase:GetCoordinate()
|
||||||
@ -1257,6 +1258,10 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
-- Debug output
|
-- Debug output
|
||||||
self:T( { "Current point of ", self.SpawnTemplatePrefix, SpawnAirbase } )
|
self:T( { "Current point of ", self.SpawnTemplatePrefix, SpawnAirbase } )
|
||||||
|
|
||||||
|
-- Template group and unit.
|
||||||
|
local TemplateGroup = GROUP:FindByName(self.SpawnTemplatePrefix)
|
||||||
|
local ishelo=TemplateGroup:GetUnit(1):HasAttribute("Helicopters")
|
||||||
|
|
||||||
-- First waypoint of the group.
|
-- First waypoint of the group.
|
||||||
local SpawnPoint = SpawnTemplate.route.points[1]
|
local SpawnPoint = SpawnTemplate.route.points[1]
|
||||||
@ -1282,36 +1287,31 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
SpawnPoint.airdromeId = AirbaseID
|
SpawnPoint.airdromeId = AirbaseID
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Set waypoint type/action.
|
||||||
SpawnPoint.alt = 0
|
SpawnPoint.alt = 0
|
||||||
SpawnPoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
SpawnPoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
||||||
SpawnPoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
SpawnPoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
||||||
|
|
||||||
|
|
||||||
-- Check if we spawn on ground.
|
-- Check if we spawn on ground.
|
||||||
local spawnonground=not (Takeoff==SPAWN.Takeoff.Air)
|
local spawnonground=not (Takeoff==SPAWN.Takeoff.Air)
|
||||||
self:E({spawnonground=spawnonground, takeoff=Takeoff, toair=Takeoff==SPAWN.Takeoff.Air})
|
self:T({spawnonground=spawnonground, TOtype=Takeoff, TOair=Takeoff==SPAWN.Takeoff.Air})
|
||||||
|
|
||||||
-- Check where we actually spawn if we spawn on ground.
|
-- Check where we actually spawn if we spawn on ground.
|
||||||
local spawnonship=false
|
local spawnonship=false
|
||||||
local spawnonfarp=false
|
local spawnonfarp=false
|
||||||
local spawnonrunway=false
|
local spawnonrunway=false
|
||||||
local spawnonairport=false
|
local spawnonairport=false
|
||||||
if spawnonground then
|
if spawnonground then
|
||||||
|
if AirbaseCategory == Airbase.Category.SHIP then
|
||||||
-- Spawning at a ship
|
spawnonship=true
|
||||||
spawnonship=SpawnAirbase:GetCategory()==1 -- Catetory 1 are ships.
|
elseif AirbaseCategory == Airbase.Category.HELIPAD then
|
||||||
|
spawnonfarp=true
|
||||||
-- Spawning at a FARP. Catetory 4 are airbases so we need to check that type is FARP as well.
|
elseif AirbaseCategory == Airbase.Category.AIRDROME then
|
||||||
spawnonfarp=SpawnAirbase:GetCategory()==4 and SpawnAirbase:GetTypeName()=="FARP"
|
spawnonairport=true
|
||||||
|
end
|
||||||
-- Spawning at an airport.
|
|
||||||
spawnonairport=SpawnAirbase:GetCategory()==4 and SpawnAirbase:GetTypeName()~="FARP"
|
|
||||||
|
|
||||||
-- Spawning on the runway.
|
|
||||||
spawnonrunway=Takeoff==SPAWN.Takeoff.Runway
|
spawnonrunway=Takeoff==SPAWN.Takeoff.Runway
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Array with parking spots coordinates.
|
-- Array with parking spots coordinates.
|
||||||
local parkingspots={}
|
local parkingspots={}
|
||||||
local parkingindex={}
|
local parkingindex={}
|
||||||
@ -1330,20 +1330,39 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Number of free parking spots at the airbase.
|
-- Number of free parking spots at the airbase.
|
||||||
nfree=SpawnAirbase:GetFreeParkingSpotsNumber(termtype, spawnonship or spawnonfarp or spawnonrunway)
|
if spawnonship or spawnonfarp or spawnonrunway then
|
||||||
spots=SpawnAirbase:GetFreeParkingSpotsTable(termtype, spawnonship or spawnonfarp or spawnonrunway)
|
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||||
|
nfree=SpawnAirbase:GetFreeParkingSpotsNumber(termtype, spawnonship or spawnonfarp or spawnonrunway)
|
||||||
|
spots=SpawnAirbase:GetFreeParkingSpotsTable(termtype, spawnonship or spawnonfarp or spawnonrunway)
|
||||||
|
else
|
||||||
|
if ishelo and termtype==nil then
|
||||||
|
-- Helo is spawned.
|
||||||
|
-- Try helo spots first.
|
||||||
|
spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup, AIRBASE.TerminalType.HelicopterOnly)
|
||||||
|
nfree=#spots
|
||||||
|
if nfree<#SpawnTemplate.units then
|
||||||
|
-- Not enough helo ports. Let's try all terminal types.
|
||||||
|
spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup, AIRBASE.TerminalType.HelicopterUsable)
|
||||||
|
nfree=#spots
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Fixed wing aircraft is spawned.
|
||||||
|
--TODO: Add some default cases for transport, bombers etc. if no explicit terminal type is provided.
|
||||||
|
spots=SpawnAirbase:FindFreeParkingSpotForAircraft(TemplateGroup, termtype)
|
||||||
|
nfree=#spots
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Get parking data.
|
-- Get parking data.
|
||||||
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
||||||
|
self:T(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
||||||
self:E(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
self:E(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
self:T(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
||||||
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
||||||
end
|
end
|
||||||
self:E(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, #SpawnTemplate.units))
|
self:T(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, #SpawnTemplate.units))
|
||||||
|
|
||||||
-- Put parking spots in table. These spots are only used if
|
-- Put parking spots in table. These spots are only used if spawing at an airbase.
|
||||||
if nfree >= #SpawnTemplate.units or (spawnonrunway and nfree>0) then
|
if nfree >= #SpawnTemplate.units or (spawnonrunway and nfree>0) then
|
||||||
|
|
||||||
for i=1,#SpawnTemplate.units do
|
for i=1,#SpawnTemplate.units do
|
||||||
@ -1352,22 +1371,34 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E(string.format("Group %s has no parking spots at %s ==> air start!", self.SpawnTemplatePrefix, SpawnAirbase:GetName()))
|
if not self.SpawnUnControlled then
|
||||||
|
self:E(string.format("WARNING: Group %s has no parking spots at %s ==> air start!", self.SpawnTemplatePrefix, SpawnAirbase:GetName()))
|
||||||
-- Not enough parking spots at the airport ==> Spawn in air.
|
|
||||||
spawnonground=false
|
|
||||||
spawnonship=false
|
|
||||||
spawnonfarp=false
|
|
||||||
spawnonrunway=false
|
|
||||||
|
|
||||||
-- Set waypoint type/action to turning point.
|
-- Not enough parking spots at the airport ==> Spawn in air.
|
||||||
SpawnPoint.type = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][1] -- type = Turning Point
|
spawnonground=false
|
||||||
SpawnPoint.action = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][2] -- action = Turning Point
|
spawnonship=false
|
||||||
|
spawnonfarp=false
|
||||||
-- Adjust altitude to be 500-1000 m above the airbase.
|
spawnonrunway=false
|
||||||
PointVec3.y=PointVec3:GetLandHeight()+math.random(200,1200)
|
|
||||||
|
-- Set waypoint type/action to turning point.
|
||||||
Takeoff=GROUP.Takeoff.Air
|
SpawnPoint.type = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][1] -- type = Turning Point
|
||||||
|
SpawnPoint.action = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][2] -- action = Turning Point
|
||||||
|
|
||||||
|
-- Adjust altitude to be 500-1000 m above the airbase.
|
||||||
|
PointVec3.x=PointVec3.x+math.random(-500,500)
|
||||||
|
PointVec3.z=PointVec3.z+math.random(-500,500)
|
||||||
|
if ishelo then
|
||||||
|
PointVec3.y=PointVec3:GetLandHeight()+math.random(200,1200)
|
||||||
|
else
|
||||||
|
-- Randomize position so that multiple AC wont be spawned on top even in air.
|
||||||
|
PointVec3.y=PointVec3:GetLandHeight()+math.random(500,5000)
|
||||||
|
end
|
||||||
|
|
||||||
|
Takeoff=GROUP.Takeoff.Air
|
||||||
|
else
|
||||||
|
self:E(string.format("WARNING: Group %s has no parking spots at %s ==> Uncontrolled spawning ==> No spawn!", self.SpawnTemplatePrefix, SpawnAirbase:GetName()))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1428,16 +1459,9 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
UnitTemplate.parking = parkingindex[UnitID]
|
UnitTemplate.parking = parkingindex[UnitID]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Debug output.
|
||||||
-- Place marker at spawn position.
|
|
||||||
--if self.Debug then
|
|
||||||
local unitspawn=COORDINATE:New(SpawnTemplate.units[UnitID].x, SpawnTemplate.units[UnitID].alt, SpawnTemplate.units[UnitID].y)
|
|
||||||
unitspawn:MarkToAll(string.format("%s Spawnplace unit #%d, terminal %s", self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking)))
|
|
||||||
--end
|
|
||||||
|
|
||||||
self:T2(string.format("Group %s unit number %d: Parking = %s",self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking)))
|
self:T2(string.format("Group %s unit number %d: Parking = %s",self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking)))
|
||||||
self:T2(string.format("Group %s unit number %d: Parking ID = %s",self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking_id)))
|
self:T2(string.format("Group %s unit number %d: Parking ID = %s",self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking_id)))
|
||||||
|
|
||||||
self:T2('After Translation SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
|
self:T2('After Translation SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -1831,7 +1831,10 @@ function RAT:_SpawnWithRoute(_departure, _destination, _takeoff, _landing, _live
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Modify the spawn template to follow the flight plan.
|
-- Modify the spawn template to follow the flight plan.
|
||||||
self:_ModifySpawnTemplate(waypoints, livery, _spawnpos, departure, takeoff)
|
local successful=self:_ModifySpawnTemplate(waypoints, livery, _spawnpos, departure, takeoff)
|
||||||
|
if not successful then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
-- Actually spawn the group.
|
-- Actually spawn the group.
|
||||||
local group=self:SpawnWithIndex(self.SpawnIndex) -- Wrapper.Group#GROUP
|
local group=self:SpawnWithIndex(self.SpawnIndex) -- Wrapper.Group#GROUP
|
||||||
@ -4925,30 +4928,30 @@ function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, take
|
|||||||
if spawnplace then
|
if spawnplace then
|
||||||
PointVec3 = COORDINATE:NewFromCoordinate(spawnplace)
|
PointVec3 = COORDINATE:NewFromCoordinate(spawnplace)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Template group and unit.
|
||||||
|
local TemplateGroup = GROUP:FindByName(self.SpawnTemplatePrefix)
|
||||||
|
|
||||||
-- Check if we spawn on ground.
|
-- Check if we spawn on ground.
|
||||||
local spawnonground=takeoff==RAT.wp.cold or takeoff==RAT.wp.hot or takeoff==RAT.wp.runway
|
local spawnonground=takeoff==RAT.wp.cold or takeoff==RAT.wp.hot or takeoff==RAT.wp.runway
|
||||||
|
|
||||||
-- Check where we actually spawn if we spawn on ground.
|
-- Check where we actually spawn if we spawn on ground.
|
||||||
local spawnonship=false
|
local spawnonship=false
|
||||||
local spawnonfarp=false
|
local spawnonfarp=false
|
||||||
local spawnonrunway=false
|
local spawnonrunway=false
|
||||||
local spawnonairport=false
|
local spawnonairport=false
|
||||||
if spawnonground then
|
if spawnonground then
|
||||||
|
local AirbaseCategory = departure:GetDesc().category
|
||||||
-- Spawning at a ship
|
if AirbaseCategory == Airbase.Category.SHIP then
|
||||||
spawnonship=departure:GetCategory()==1 -- Catetory 1 are ships.
|
spawnonship=true
|
||||||
|
elseif AirbaseCategory == Airbase.Category.HELIPAD then
|
||||||
-- Spawning at a FARP. Catetory 4 are airbases so we need to check that type is FARP as well.
|
spawnonfarp=true
|
||||||
spawnonfarp=departure:GetCategory()==4 and departure:GetTypeName()=="FARP"
|
elseif AirbaseCategory == Airbase.Category.AIRDROME then
|
||||||
|
spawnonairport=true
|
||||||
-- Spawning at an airport.
|
end
|
||||||
spawnonairport=departure:GetCategory()==4 and departure:GetTypeName()~="FARP"
|
|
||||||
|
|
||||||
-- Spawning on the runway.
|
|
||||||
spawnonrunway=takeoff==RAT.wp.runway
|
spawnonrunway=takeoff==RAT.wp.runway
|
||||||
end
|
end
|
||||||
|
|
||||||
local automatic=false
|
local automatic=false
|
||||||
if automatic and spawnonground then
|
if automatic and spawnonground then
|
||||||
PointVec3=PointVec3:GetClosestParkingSpot(true, departure)
|
PointVec3=PointVec3:GetClosestParkingSpot(true, departure)
|
||||||
@ -4990,19 +4993,37 @@ function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, take
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Number of free parking spots at the airbase.
|
-- Number of free parking spots at the airbase.
|
||||||
nfree=departure:GetFreeParkingSpotsNumber(termtype, spawnonship or spawnonfarp or spawnonrunway)
|
if spawnonship or spawnonfarp or spawnonrunway then
|
||||||
spots=departure:GetFreeParkingSpotsTable(termtype, spawnonship or spawnonfarp or spawnonrunway)
|
-- These places work procedural and have some kind of build in queue ==> Less effort.
|
||||||
|
nfree=departure:GetFreeParkingSpotsNumber(termtype, spawnonship or spawnonfarp or spawnonrunway)
|
||||||
|
spots=departure:GetFreeParkingSpotsTable(termtype, spawnonship or spawnonfarp or spawnonrunway)
|
||||||
|
else
|
||||||
|
if self.category==RAT.cat.heli and termtype==nil then
|
||||||
|
-- Helo is spawned.
|
||||||
|
-- Try helo spots first.
|
||||||
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup, AIRBASE.TerminalType.HelicopterOnly)
|
||||||
|
nfree=#spots
|
||||||
|
if nfree<#SpawnTemplate.units then
|
||||||
|
-- Not enough helo ports. Let's try all terminal types.
|
||||||
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup, AIRBASE.TerminalType.HelicopterUsable)
|
||||||
|
nfree=#spots
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Fixed wing aircraft is spawned.
|
||||||
|
--TODO: Add some default cases for transport, bombers etc. if no explicit terminal type is provided.
|
||||||
|
spots=departure:FindFreeParkingSpotForAircraft(TemplateGroup, termtype)
|
||||||
|
nfree=#spots
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Get parking data.
|
-- Get parking data.
|
||||||
local parkingdata=departure:GetParkingSpotsTable(termtype)
|
local parkingdata=departure:GetParkingSpotsTable(termtype)
|
||||||
|
self:T(RAT.id..string.format("Parking at %s, terminal type %s:", departure:GetName(), tostring(termtype)))
|
||||||
self:E(RAT.id..string.format("Parking at %s, terminal type %s:", departure:GetName(), tostring(termtype)))
|
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
self:E(RAT.id..string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
self:T(RAT.id..string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
||||||
departure:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
departure:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
||||||
end
|
end
|
||||||
self:E(RAT.id..string.format("%s at %s: free parking spots = %d - number of units = %d", self.alias, departure:GetName(), nfree, #SpawnTemplate.units))
|
self:T(RAT.id..string.format("%s at %s: free parking spots = %d - number of units = %d", self.alias, departure:GetName(), nfree, #SpawnTemplate.units))
|
||||||
|
|
||||||
|
|
||||||
-- Put parking spots in table. These spots are only used if
|
-- Put parking spots in table. These spots are only used if
|
||||||
if nfree >= #SpawnTemplate.units or (spawnonrunway and nfree>0) then
|
if nfree >= #SpawnTemplate.units or (spawnonrunway and nfree>0) then
|
||||||
@ -5011,28 +5032,31 @@ function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, take
|
|||||||
table.insert(parkingspots, spots[i].Coordinate)
|
table.insert(parkingspots, spots[i].Coordinate)
|
||||||
table.insert(parkingindex, spots[i].TerminalID)
|
table.insert(parkingindex, spots[i].TerminalID)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if spawnonrunway then
|
if spawnonrunway then
|
||||||
--PointVec3=spots[1]
|
--PointVec3=spots[1]
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E(RAT.id..string.format("RAT group %s has no parking spots at %s ==> air start!", self.alias, departure:GetName()))
|
if self.respawn_inair or self.uncontrolled then
|
||||||
|
self:E(RAT.id..string.format("WARNING: RAT group %s has no parking spots at %s ==> air start!", self.alias, departure:GetName()))
|
||||||
-- Not enough parking spots at the airport ==> Spawn in air.
|
|
||||||
spawnonground=false
|
|
||||||
spawnonship=false
|
|
||||||
spawnonfarp=false
|
|
||||||
spawnonrunway=false
|
|
||||||
|
|
||||||
-- Set waypoint type/action to turning point.
|
|
||||||
waypoints[1].type = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][1] -- type = Turning Point
|
|
||||||
waypoints[1].action = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][2] -- action = Turning Point
|
|
||||||
|
|
||||||
-- Adjust altitude to be 500-1000 m above the airbase.
|
|
||||||
PointVec3.y=PointVec3:GetLandHeight()+math.random(500,1000)
|
|
||||||
|
|
||||||
|
-- Not enough parking spots at the airport ==> Spawn in air.
|
||||||
|
spawnonground=false
|
||||||
|
spawnonship=false
|
||||||
|
spawnonfarp=false
|
||||||
|
spawnonrunway=false
|
||||||
|
|
||||||
|
-- Set waypoint type/action to turning point.
|
||||||
|
waypoints[1].type = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][1] -- type = Turning Point
|
||||||
|
waypoints[1].action = GROUPTEMPLATE.Takeoff[GROUP.Takeoff.Air][2] -- action = Turning Point
|
||||||
|
|
||||||
|
-- Adjust altitude to be 500-1000 m above the airbase.
|
||||||
|
PointVec3.y=PointVec3:GetLandHeight()+math.random(500,1000)
|
||||||
|
else
|
||||||
|
self:E(RAT.id..string.format("WARNING: RAT group %s has no parking spots at %s. Air start deactivated or uncontrolled AC!", self.alias, departure:GetName()))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -5160,6 +5184,8 @@ function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, take
|
|||||||
self:T(SpawnTemplate)
|
self:T(SpawnTemplate)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -106,10 +106,8 @@ AIRBASE.Caucasus = {
|
|||||||
["Mozdok"] = "Mozdok",
|
["Mozdok"] = "Mozdok",
|
||||||
["Beslan"] = "Beslan",
|
["Beslan"] = "Beslan",
|
||||||
}
|
}
|
||||||
--
|
|
||||||
--- @field Nevada
|
--- These are all airbases of Nevada:
|
||||||
--
|
|
||||||
-- These are all airbases of Nevada:
|
|
||||||
--
|
--
|
||||||
-- * AIRBASE.Nevada.Creech_AFB
|
-- * AIRBASE.Nevada.Creech_AFB
|
||||||
-- * AIRBASE.Nevada.Groom_Lake_AFB
|
-- * AIRBASE.Nevada.Groom_Lake_AFB
|
||||||
@ -129,7 +127,7 @@ AIRBASE.Caucasus = {
|
|||||||
-- * AIRBASE.Nevada.Pahute_Mesa_Airstrip
|
-- * AIRBASE.Nevada.Pahute_Mesa_Airstrip
|
||||||
-- * AIRBASE.Nevada.Tonopah_Airport
|
-- * AIRBASE.Nevada.Tonopah_Airport
|
||||||
-- * AIRBASE.Nevada.Tonopah_Test_Range_Airfield
|
-- * AIRBASE.Nevada.Tonopah_Test_Range_Airfield
|
||||||
--
|
-- @field Nevada
|
||||||
AIRBASE.Nevada = {
|
AIRBASE.Nevada = {
|
||||||
["Creech_AFB"] = "Creech AFB",
|
["Creech_AFB"] = "Creech AFB",
|
||||||
["Groom_Lake_AFB"] = "Groom Lake AFB",
|
["Groom_Lake_AFB"] = "Groom Lake AFB",
|
||||||
@ -150,10 +148,8 @@ AIRBASE.Nevada = {
|
|||||||
["Tonopah_Airport"] = "Tonopah Airport",
|
["Tonopah_Airport"] = "Tonopah Airport",
|
||||||
["Tonopah_Test_Range_Airfield"] = "Tonopah Test Range Airfield",
|
["Tonopah_Test_Range_Airfield"] = "Tonopah Test Range Airfield",
|
||||||
}
|
}
|
||||||
--
|
|
||||||
--- @field Normandy
|
--- These are all airbases of Normandy:
|
||||||
--
|
|
||||||
-- These are all airbases of Normandy:
|
|
||||||
--
|
--
|
||||||
-- * AIRBASE.Normandy.Saint_Pierre_du_Mont
|
-- * AIRBASE.Normandy.Saint_Pierre_du_Mont
|
||||||
-- * AIRBASE.Normandy.Lignerolles
|
-- * AIRBASE.Normandy.Lignerolles
|
||||||
@ -186,6 +182,7 @@ AIRBASE.Nevada = {
|
|||||||
-- * AIRBASE.Normandy.Funtington
|
-- * AIRBASE.Normandy.Funtington
|
||||||
-- * AIRBASE.Normandy.Tangmere
|
-- * AIRBASE.Normandy.Tangmere
|
||||||
-- * AIRBASE.Normandy.Ford
|
-- * AIRBASE.Normandy.Ford
|
||||||
|
-- @field Normandy
|
||||||
AIRBASE.Normandy = {
|
AIRBASE.Normandy = {
|
||||||
["Saint_Pierre_du_Mont"] = "Saint Pierre du Mont",
|
["Saint_Pierre_du_Mont"] = "Saint Pierre du Mont",
|
||||||
["Lignerolles"] = "Lignerolles",
|
["Lignerolles"] = "Lignerolles",
|
||||||
@ -219,28 +216,27 @@ AIRBASE.Normandy = {
|
|||||||
["Tangmere"] = "Tangmere",
|
["Tangmere"] = "Tangmere",
|
||||||
["Ford"] = "Ford",
|
["Ford"] = "Ford",
|
||||||
}
|
}
|
||||||
--
|
|
||||||
--- @field PersianGulf
|
--- These are all airbases of the Persion Gulf Map:
|
||||||
--
|
--
|
||||||
-- These are all airbases of the Persion Gulf Map:
|
-- * AIRBASE.PersianGulf.Fujairah_Intl
|
||||||
--
|
-- * AIRBASE.PersianGulf.Qeshm_Island
|
||||||
-- * AIRBASE.PersianGulf.Fujairah_Intl
|
-- * AIRBASE.PersianGulf.Sir_Abu_Nuayr
|
||||||
-- * AIRBASE.PersianGulf.Qeshm_Island
|
-- * AIRBASE.PersianGulf.Abu_Musa_Island_Airport
|
||||||
-- * AIRBASE.PersianGulf.Sir_Abu_Nuayr
|
-- * AIRBASE.PersianGulf.Bandar_Abbas_Intl
|
||||||
-- * AIRBASE.PersianGulf.Abu_Musa_Island_Airport
|
-- * AIRBASE.PersianGulf.Bandar_Lengeh
|
||||||
-- * AIRBASE.PersianGulf.Bandar_Abbas_Intl
|
-- * AIRBASE.PersianGulf.Tunb_Island_AFB
|
||||||
-- * AIRBASE.PersianGulf.Bandar_Lengeh
|
-- * AIRBASE.PersianGulf.Havadarya
|
||||||
-- * AIRBASE.PersianGulf.Tunb_Island_AFB
|
-- * AIRBASE.PersianGulf.Lar_Airbase
|
||||||
-- * AIRBASE.PersianGulf.Havadarya
|
-- * AIRBASE.PersianGulf.Sirri_Island
|
||||||
-- * AIRBASE.PersianGulf.Lar_Airbase
|
-- * AIRBASE.PersianGulf.Tunb_Kochak
|
||||||
-- * AIRBASE.PersianGulf.Sirri_Island
|
-- * AIRBASE.PersianGulf.Al_Dhafra_AB
|
||||||
-- * AIRBASE.PersianGulf.Tunb_Kochak
|
-- * AIRBASE.PersianGulf.Dubai_Intl
|
||||||
-- * AIRBASE.PersianGulf.Al_Dhafra_AB
|
-- * AIRBASE.PersianGulf.Al_Maktoum_Intl
|
||||||
-- * AIRBASE.PersianGulf.Dubai_Intl
|
-- * AIRBASE.PersianGulf.Khasab
|
||||||
-- * AIRBASE.PersianGulf.Al_Maktoum_Intl
|
-- * AIRBASE.PersianGulf.Al_Minhad_AB
|
||||||
-- * AIRBASE.PersianGulf.Khasab
|
-- * AIRBASE.PersianGulf.Sharjah_Intl
|
||||||
-- * AIRBASE.PersianGulf.Al_Minhad_AB
|
-- @field PersianGulf
|
||||||
-- * AIRBASE.PersianGulf.Sharjah_Intl
|
|
||||||
AIRBASE.PersianGulf = {
|
AIRBASE.PersianGulf = {
|
||||||
["Fujairah_Intl"] = "Fujairah Intl",
|
["Fujairah_Intl"] = "Fujairah Intl",
|
||||||
["Qeshm_Island"] = "Qeshm Island",
|
["Qeshm_Island"] = "Qeshm Island",
|
||||||
@ -260,14 +256,29 @@ AIRBASE.PersianGulf = {
|
|||||||
["Al_Minhad_AB"] = "Al Minhad AB",
|
["Al_Minhad_AB"] = "Al Minhad AB",
|
||||||
["Sharjah_Intl"] = "Sharjah Intl",
|
["Sharjah_Intl"] = "Sharjah Intl",
|
||||||
}
|
}
|
||||||
--
|
|
||||||
--- @field Terminal Types of parking spots.
|
--- Terminal Types of parking spots. See also https://wiki.hoggitworld.com/view/DCS_func_getParking
|
||||||
|
--
|
||||||
|
-- Supported types are:
|
||||||
|
--
|
||||||
|
-- * AIRBASE.TerminalType.Runway: Valid spawn points on runway.
|
||||||
|
-- * AIRBASE.TerminalType.HelicopterOnly: Special spots for Helicopers.
|
||||||
|
-- * AIRBASE.TerminalType.Shelter: Hardened Air Shelter. Currently only on Caucaus map.
|
||||||
|
-- * AIRBASE.TerminalType.OpenMed: Open/Shelter air airplane only.
|
||||||
|
-- * AIRBASE.TerminalType.OpenBig: Open air spawn points. Generally larger but does not guarantee large aircraft are capable of spawning there.
|
||||||
|
-- * AIRBASE.TerminalType.OpenMedOrBig: Combines OpenMed and OpenBig spots.
|
||||||
|
-- * AIRBASE.TerminalType.HelicopterUnsable: Combines HelicopterOnly, OpenMed and OpenBig.
|
||||||
|
-- * AIRBASE.TerminalType.FighterAircraft: Combines Shelter. OpenMed and OpenBig spots.
|
||||||
|
-- @field TerminalType
|
||||||
AIRBASE.TerminalType = {
|
AIRBASE.TerminalType = {
|
||||||
Runway=16,
|
Runway=16,
|
||||||
Helicopter=40,
|
HelicopterOnly=40,
|
||||||
HardenedShelter=68,
|
Shelter=68,
|
||||||
OpenOrShelter=72,
|
OpenMed=72,
|
||||||
OpenAir=104,
|
OpenBig=104,
|
||||||
|
OpenMedOrBig=176,
|
||||||
|
HelicopterUsable=216,
|
||||||
|
FighterAircraft=244,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Registration.
|
-- Registration.
|
||||||
@ -343,6 +354,7 @@ function AIRBASE:GetAllAirbases(coalition)
|
|||||||
return airbases
|
return airbases
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Returns a table of parking data for a given airbase. If the optional parameter *available* is true only available parking will be returned, otherwise all parking at the base is returned. Term types have the following enumerated values:
|
--- Returns a table of parking data for a given airbase. If the optional parameter *available* is true only available parking will be returned, otherwise all parking at the base is returned. Term types have the following enumerated values:
|
||||||
--
|
--
|
||||||
-- * 16 : Valid spawn points on runway
|
-- * 16 : Valid spawn points on runway
|
||||||
@ -364,6 +376,7 @@ end
|
|||||||
-- @param #boolean available If true, only available parking spots will be returned.
|
-- @param #boolean available If true, only available parking spots will be returned.
|
||||||
-- @return #table Table with parking data. See https://wiki.hoggitworld.com/view/DCS_func_getParking
|
-- @return #table Table with parking data. See https://wiki.hoggitworld.com/view/DCS_func_getParking
|
||||||
function AIRBASE:GetParkingData(available)
|
function AIRBASE:GetParkingData(available)
|
||||||
|
self:F2(available)
|
||||||
|
|
||||||
-- Get DCS airbase object.
|
-- Get DCS airbase object.
|
||||||
local DCSAirbase=self:GetDCSObject()
|
local DCSAirbase=self:GetDCSObject()
|
||||||
@ -374,27 +387,27 @@ function AIRBASE:GetParkingData(available)
|
|||||||
parkingdata=DCSAirbase:getParking(available)
|
parkingdata=DCSAirbase:getParking(available)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:T2({parkingdata=parkingdata})
|
||||||
return parkingdata
|
return parkingdata
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get number parking spots at an airbase. Optionally, for a specific terminal type. Spots on runway are exculded if not explicitly requested by terminal type
|
--- Get number of parking spots at an airbase. Optionally, a specific terminal type can be requested.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @param #number termtype Terminal type.
|
-- @param #number termtype Terminal type of which the number of spots is counted. Default all spots but spawn points on runway.
|
||||||
-- @return #number Number of free parking spots at this airbase.
|
-- @return #number Number of parking spots at this airbase.
|
||||||
function AIRBASE:GetParkingSpotsNumber(termtype)
|
function AIRBASE:GetParkingSpotsNumber(termtype)
|
||||||
|
|
||||||
-- Get free parking spots data.
|
-- Get free parking spots data.
|
||||||
local parkingdata=self:GetParkingData(false)
|
local parkingdata=self:GetParkingData(false)
|
||||||
|
|
||||||
local nfree=0
|
local nspots=0
|
||||||
for _,parkingspot in pairs(parkingdata) do
|
for _,parkingspot in pairs(parkingdata) do
|
||||||
-- Spots on runway are not counted unless explicitly requested.
|
if self:_CheckTerminalType(parkingspot.Term_Type, termtype) then
|
||||||
if (termtype~=nil and parkingspot.Term_Type==termtype) or (termtype==nil and parkingspot.Term_Type~=AIRBASE.TerminalType.Runway) then
|
nspots=nspots+1
|
||||||
nfree=nfree+1
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return nfree
|
return nspots
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get number of free parking spots at an airbase.
|
--- Get number of free parking spots at an airbase.
|
||||||
@ -410,7 +423,7 @@ function AIRBASE:GetFreeParkingSpotsNumber(termtype, allowTOAC)
|
|||||||
local nfree=0
|
local nfree=0
|
||||||
for _,parkingspot in pairs(parkingdata) do
|
for _,parkingspot in pairs(parkingdata) do
|
||||||
-- Spots on runway are not counted unless explicitly requested.
|
-- Spots on runway are not counted unless explicitly requested.
|
||||||
if (termtype~=nil and parkingspot.Term_Type==termtype) or (termtype==nil and parkingspot.Term_Type~=AIRBASE.TerminalType.Runway) then
|
if self:_CheckTerminalType(parkingspot.Term_Type, termtype) then
|
||||||
if (allowTOAC and allowTOAC==true) or parkingspot.TO_AC==false then
|
if (allowTOAC and allowTOAC==true) or parkingspot.TO_AC==false then
|
||||||
nfree=nfree+1
|
nfree=nfree+1
|
||||||
end
|
end
|
||||||
@ -434,7 +447,7 @@ function AIRBASE:GetFreeParkingSpotsCoordinates(termtype, allowTOAC)
|
|||||||
local spots={}
|
local spots={}
|
||||||
for _,parkingspot in pairs(parkingdata) do
|
for _,parkingspot in pairs(parkingdata) do
|
||||||
-- Coordinates on runway are not returned unless explicitly requested.
|
-- Coordinates on runway are not returned unless explicitly requested.
|
||||||
if (termtype and parkingspot.Term_Type==termtype) or (termtype==nil and parkingspot.Term_Type~=AIRBASE.TerminalType.Runway) then
|
if self:_CheckTerminalType(parkingspot.Term_Type, termtype) then
|
||||||
if (allowTOAC and allowTOAC==true) or parkingspot.TO_AC==false then
|
if (allowTOAC and allowTOAC==true) or parkingspot.TO_AC==false then
|
||||||
table.insert(spots, COORDINATE:NewFromVec3(parkingspot.vTerminalPos))
|
table.insert(spots, COORDINATE:NewFromVec3(parkingspot.vTerminalPos))
|
||||||
end
|
end
|
||||||
@ -456,18 +469,17 @@ function AIRBASE:GetParkingSpotsCoordinates(termtype)
|
|||||||
-- Put coordinates of free spots into table.
|
-- Put coordinates of free spots into table.
|
||||||
local spots={}
|
local spots={}
|
||||||
for _,parkingspot in pairs(parkingdata) do
|
for _,parkingspot in pairs(parkingdata) do
|
||||||
|
|
||||||
-- Coordinates on runway are not returned unless explicitly requested.
|
-- Coordinates on runway are not returned unless explicitly requested.
|
||||||
if (termtype and parkingspot.Term_Type==termtype) or (termtype==nil and parkingspot.Term_Type~=AIRBASE.TerminalType.Runway) then
|
if self:_CheckTerminalType(parkingspot.Term_Type, termtype) then
|
||||||
|
|
||||||
|
-- Get coordinate from Vec3 terminal position.
|
||||||
local _coord=COORDINATE:NewFromVec3(parkingspot.vTerminalPos)
|
local _coord=COORDINATE:NewFromVec3(parkingspot.vTerminalPos)
|
||||||
local gotunits,gotstatics,gotscenery,_,statics,_=_coord:ScanObjects(.5)
|
|
||||||
env.info(string.format("FF scan: terminal index %03d, type = %03d, gotunits=%s, gotstatics=%s, gotscenery=%s", parkingspot.Term_Index+1, parkingspot.Term_Type, tostring(gotunits), tostring(gotstatics), tostring(gotscenery)))
|
-- Add to table.
|
||||||
if gotstatics then
|
|
||||||
for _,static in pairs(statics) do
|
|
||||||
env.info(string.format("FF Static name= %s", tostring(static:getName())))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
table.insert(spots, _coord)
|
table.insert(spots, _coord)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return spots
|
return spots
|
||||||
@ -495,17 +507,17 @@ function AIRBASE:GetParkingSpotsTable(termtype)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Put coordinates of free spots into table.
|
-- Put coordinates of parking spots into table.
|
||||||
local freespots={}
|
local spots={}
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
if (termtype and _spot.Term_Type==termtype) or (termtype==nil and _spot.Term_Type~=AIRBASE.TerminalType.Runway) then
|
if self:_CheckTerminalType(_spot.Term_Type, termtype) then
|
||||||
local _free=_isfree(_spot)
|
local _free=_isfree(_spot)
|
||||||
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
|
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
|
||||||
table.insert(freespots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=_free, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
|
table.insert(spots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=_free, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return freespots
|
return spots
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
|
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
|
||||||
@ -521,7 +533,7 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC)
|
|||||||
-- Put coordinates of free spots into table.
|
-- Put coordinates of free spots into table.
|
||||||
local freespots={}
|
local freespots={}
|
||||||
for _,_spot in pairs(parkingfree) do
|
for _,_spot in pairs(parkingfree) do
|
||||||
if (termtype and _spot.Term_Type==termtype) or (termtype==nil and _spot.Term_Type~=AIRBASE.TerminalType.Runway) then
|
if self:_CheckTerminalType(_spot.Term_Type, termtype) then
|
||||||
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
|
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
|
||||||
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
|
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
|
||||||
table.insert(freespots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=true, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
|
table.insert(freespots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=true, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
|
||||||
@ -537,21 +549,223 @@ end
|
|||||||
-- @param #number termtype Terminal type for which marks should be placed.
|
-- @param #number termtype Terminal type for which marks should be placed.
|
||||||
function AIRBASE:MarkParkingSpots(termtype)
|
function AIRBASE:MarkParkingSpots(termtype)
|
||||||
|
|
||||||
|
-- Get parking data from getParking() wrapper function.
|
||||||
local parkingdata=self:GetParkingSpotsTable(termtype)
|
local parkingdata=self:GetParkingSpotsTable(termtype)
|
||||||
|
|
||||||
|
-- Get airbase name.
|
||||||
local airbasename=self:GetName()
|
local airbasename=self:GetName()
|
||||||
self:E(string.format("Parking spots at %s for termial type %s:", airbasename, tostring(termtype)))
|
self:E(string.format("Parking spots at %s for termial type %s:", airbasename, tostring(termtype)))
|
||||||
|
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
|
|
||||||
-- Mark text.
|
-- Mark text.
|
||||||
local _text=string.format("%s, Term Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %.1f",
|
local _text=string.format("Term Index=%d, Term Type=%d, Free=%s, TOAC=%s, Term ID0=%d, Dist2Rwy=%.1f m",
|
||||||
airbasename, _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy)
|
_spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy)
|
||||||
|
|
||||||
-- Create mark on the F10 map.
|
-- Create mark on the F10 map.
|
||||||
_spot.Coordinate:MarkToAll(_text)
|
_spot.Coordinate:MarkToAll(_text)
|
||||||
|
|
||||||
-- Info to DCS.log file.
|
-- Info to DCS.log file.
|
||||||
|
local _text=string.format("%s, Term Index=%3d, Term Type=%03d, Free=%5s, TOAC=%5s, Term ID0=%3d, Dist2Rwy=%.1f m",
|
||||||
|
airbasename, _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy)
|
||||||
self:E(_text)
|
self:E(_text)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Helper function to check for the correct terminal type including "artificial" ones.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param #number Term_Type Termial type from getParking routine.
|
||||||
|
-- @param #number termtype Terminal type from AIRBASE.TerminalType enumerator.
|
||||||
|
-- @return True if terminal types match.
|
||||||
|
function AIRBASE:_CheckTerminalType(Term_Type, termtype)
|
||||||
|
|
||||||
|
-- Nill check for Term_Type.
|
||||||
|
if Term_Type==nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- If no terminal type is requested, we return true. BUT runways are excluded unless explicitly requested.
|
||||||
|
if termtype==nil then
|
||||||
|
if Term_Type==AIRBASE.TerminalType.Runway then
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Init no match.
|
||||||
|
local match=false
|
||||||
|
|
||||||
|
-- Standar case.
|
||||||
|
if Term_Type==termtype then
|
||||||
|
match=true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Artificial cases. Combination of terminal types.
|
||||||
|
if termtype==AIRBASE.TerminalType.OpenMedOrBig then
|
||||||
|
if Term_Type==AIRBASE.TerminalType.OpenMed or Term_Type==AIRBASE.TerminalType.OpenBig then
|
||||||
|
match=true
|
||||||
|
end
|
||||||
|
elseif termtype==AIRBASE.TerminalType.HelicopterUsable then
|
||||||
|
if Term_Type==AIRBASE.TerminalType.OpenMed or Term_Type==AIRBASE.TerminalType.OpenBig or Term_Type==AIRBASE.TerminalType.HelicopterOnly then
|
||||||
|
match=true
|
||||||
|
end
|
||||||
|
elseif termtype==AIRBASE.TerminalType.FighterAircraft then
|
||||||
|
if Term_Type==AIRBASE.TerminalType.OpenMed or Term_Type==AIRBASE.TerminalType.OpenBig or Term_Type==AIRBASE.TerminalType.Shelter then
|
||||||
|
match=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return match
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Seach an unoccupied parking spot at a specific airport and for a specific aircraft.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param Wrapper.Group#GROUP group Aircraft group for which the parking spots are requested.
|
||||||
|
-- @param #number terminaltype (Optional) Only search spots at a specific terminal type. Default is all types execpt on runway.
|
||||||
|
-- @param #number scanradius (Optional) Radius in meters around parking spot to scan for obstacles. Default 30 m.
|
||||||
|
-- @param #boolean scanunits (Optional) Scan for units as obstacles. Default true.
|
||||||
|
-- @param #boolean scanstatics (Optional) Scan for statics as obstacles. Default true.
|
||||||
|
-- @param #boolean scanscenery (Optional) Scan for scenery as obstacles. Default false. Can cause problems with e.g. shelters.
|
||||||
|
-- @return #table Table of coordinates and terminal IDs of the parking spots or nil, if no valid parking spots for the whole group could be found.
|
||||||
|
function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius, scanunits, scanstatics, scanscenery)
|
||||||
|
|
||||||
|
-- Init default
|
||||||
|
scanradius=scanradius or 30
|
||||||
|
if scanunits==nil then
|
||||||
|
scanunits=true
|
||||||
|
end
|
||||||
|
if scanstatics==nil then
|
||||||
|
scanstatics=true
|
||||||
|
end
|
||||||
|
if scanscenery==nil then
|
||||||
|
scanscenery=false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get the size of an object.
|
||||||
|
local function _GetObjectSize(unit,mooseobject)
|
||||||
|
if mooseobject then
|
||||||
|
unit=unit:GetDCSObject()
|
||||||
|
end
|
||||||
|
if unit and unit:isExist() then
|
||||||
|
local DCSdesc=unit:getDesc()
|
||||||
|
local x=DCSdesc.box.max.x+math.abs(DCSdesc.box.min.x)
|
||||||
|
local y=DCSdesc.box.max.y+math.abs(DCSdesc.box.min.y) --height
|
||||||
|
local z=DCSdesc.box.max.z+math.abs(DCSdesc.box.min.z)
|
||||||
|
return math.max(x,z), x , y, z
|
||||||
|
end
|
||||||
|
return 0,0,0,0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Function calculating the overlap of two (square) objects.
|
||||||
|
local function _overlap(mooseobject, dcsobject, dist)
|
||||||
|
local l1=_GetObjectSize(mooseobject, true)
|
||||||
|
local l2=_GetObjectSize(dcsobject)
|
||||||
|
local safedist=(l1/2+l2/2)*1.1
|
||||||
|
local safe = (dist > safedist)
|
||||||
|
self:T3(string.format("l1=%.1f l2=%.1f s=%.1f d=%.1f ==> safe=%s", l1,l2,safedist,dist,tostring(safe)))
|
||||||
|
return safe
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get airport name.
|
||||||
|
local airport=self:GetName()
|
||||||
|
|
||||||
|
-- Get free parking spot data table.
|
||||||
|
--local parkingdata=self:GetFreeParkingSpotsTable(terminaltype, true)
|
||||||
|
local parkingdata=self:GetParkingSpotsTable(terminaltype)
|
||||||
|
|
||||||
|
-- Get the aircraft size, i.e. it's longest side of x,z.
|
||||||
|
local aircraft=group:GetUnit(1)
|
||||||
|
local nspots=group:GetSize()
|
||||||
|
local _aircraftsize, ax,ay,az=_GetObjectSize(aircraft, true)
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(string.format("Looking for %d parking spot(s) at %s for aircraft of size %.1f m (x=%.1f,y=%.1f,z=%.1f) at termial type %s.", nspots, airport, _aircraftsize, ax,ay,az, tostring(terminaltype)))
|
||||||
|
|
||||||
|
-- Table of valid spots.
|
||||||
|
local validspots={}
|
||||||
|
local nvalid=0
|
||||||
|
|
||||||
|
-- Loop over all known parking spots
|
||||||
|
for _,parkingspot in pairs(parkingdata) do
|
||||||
|
|
||||||
|
-- Check for requested terminal type if any.
|
||||||
|
if self:_CheckTerminalType(parkingspot.TerminalType, terminaltype) then
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Coordinate of the parking spot.
|
||||||
|
local _spot=parkingspot.Coordinate --Core.Point#COORDINATE
|
||||||
|
|
||||||
|
-- Scan a radius of 50 meters around the spot.
|
||||||
|
local _,_,_,_units,_statics,_sceneries=_spot:ScanObjects(scanradius)
|
||||||
|
|
||||||
|
|
||||||
|
-- Loop over objects within scan radius.
|
||||||
|
local occupied=false
|
||||||
|
|
||||||
|
-- Check all units.
|
||||||
|
for _,unit in pairs(_units) do
|
||||||
|
|
||||||
|
local _vec3=unit:getPoint()
|
||||||
|
local _coord=COORDINATE:NewFromVec3(_vec3)
|
||||||
|
local _dist=_coord:Get2DDistance(_spot)
|
||||||
|
local _safe=_overlap(aircraft, unit, _dist)
|
||||||
|
|
||||||
|
--local l,x,y,z=_GetObjectSize(unit)
|
||||||
|
--_coord:MarkToAll(string.format("scan found unit %s\nx=%.2f y=%.2f z=%.2f\nl=%.2f d=%.2f safe=%s", unit:getName(), x, y, z, l, _dist, tostring(_safe)))
|
||||||
|
|
||||||
|
if scanunits and not _safe then
|
||||||
|
occupied=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check all statics.
|
||||||
|
for _,static in pairs(_statics) do
|
||||||
|
local _vec3=static:getPoint()
|
||||||
|
local _coord=COORDINATE:NewFromVec3(_vec3)
|
||||||
|
local _dist=_coord:Get2DDistance(_spot)
|
||||||
|
local _safe=_overlap(aircraft, static, _dist)
|
||||||
|
|
||||||
|
--local l,x,y,z=_GetObjectSize(static)
|
||||||
|
--_coord:MarkToAll(string.format("scan found static %s\nx=%.2f y=%.2f z=%.2f\nl=%.2f d=%.2f safe=%s", static:getName(),x,y,z,l,_dist, tostring(_safe)))
|
||||||
|
|
||||||
|
if scanstatics and not _safe then
|
||||||
|
occupied=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Check all scenery.
|
||||||
|
for _,scenery in pairs(_sceneries) do
|
||||||
|
local _vec3=scenery:getPoint()
|
||||||
|
local _coord=COORDINATE:NewFromVec3(_vec3)
|
||||||
|
local _dist=_coord:Get2DDistance(_spot)
|
||||||
|
local _safe=_overlap(aircraft, scenery, _dist)
|
||||||
|
|
||||||
|
--local l,x,y,z=_GetObjectSize(scenery)
|
||||||
|
--_coord:MarkToAll(string.format("scan found scenery %s\nx=%.2f y=%.2f z=%.2f\nl=%.2f d=%.2f", scenery:getName(),x,y,z,l,_dist))
|
||||||
|
|
||||||
|
if scanscenery and not _safe then
|
||||||
|
occupied=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--_spot:MarkToAll(string.format("Parking spot %d free=%s", parkingspot.TerminalID, tostring(not occupied)))
|
||||||
|
if occupied then
|
||||||
|
self:T(string.format("%s: Parking spot id %d occupied.", airport, parkingspot.TerminalID))
|
||||||
|
else
|
||||||
|
self:T(string.format("%s: Parking spot id %d free.", airport, parkingspot.TerminalID))
|
||||||
|
if nvalid<nspots then
|
||||||
|
table.insert(validspots, {Coordinate=_spot, TerminalID=parkingspot.TerminalID})
|
||||||
|
end
|
||||||
|
nvalid=nvalid+1
|
||||||
|
end
|
||||||
|
|
||||||
|
-- We found enough spots.
|
||||||
|
if nvalid==nspots then
|
||||||
|
return validspots
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return validspots
|
||||||
|
end
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user