mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge pull request #986 from FlightControl-Master/FF/Develop
WAREHOUSE v0.5.1
This commit is contained in:
commit
f655e7e652
@ -239,7 +239,6 @@ function AI_CARGO_AIRPLANE:onafterLanded( Airplane, From, Event, To )
|
||||
|
||||
-- Aircraft was sent to this airbase to pickup troops. Initiate loadling.
|
||||
if self.RoutePickup == true then
|
||||
env.info("FF load airplane "..Airplane:GetName())
|
||||
self:Load( self.PickupZone )
|
||||
end
|
||||
|
||||
@ -265,15 +264,15 @@ end
|
||||
-- @param Core.Zone#ZONE_AIRBASE PickupZone
|
||||
function AI_CARGO_AIRPLANE:onafterPickup( Airplane, From, Event, To, Coordinate, Speed, PickupZone )
|
||||
|
||||
if Airplane and Airplane:IsAlive()~=nil then
|
||||
env.info("FF onafterpick aircraft alive")
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
--env.info("FF onafterpick aircraft alive")
|
||||
|
||||
self.PickupZone = PickupZone
|
||||
|
||||
-- Get closest airbase of current position.
|
||||
local ClosestAirbase, DistToAirbase=Airplane:GetCoordinate():GetClosestAirbase()
|
||||
|
||||
env.info("FF onafterpickup closest airbase "..ClosestAirbase:GetName())
|
||||
--env.info("FF onafterpickup closest airbase "..ClosestAirbase:GetName())
|
||||
|
||||
-- Two cases. Aircraft spawned in air or at an airbase.
|
||||
if Airplane:InAir() then
|
||||
@ -282,15 +281,16 @@ function AI_CARGO_AIRPLANE:onafterPickup( Airplane, From, Event, To, Coordinate,
|
||||
self.Airbase=ClosestAirbase
|
||||
end
|
||||
|
||||
-- Set pickup airbase.
|
||||
local Airbase = PickupZone:GetAirbase()
|
||||
|
||||
-- Distance from closest to pickup airbase ==> we need to know if we are already at the pickup airbase.
|
||||
local Dist = Airbase:GetCoordinate():Get2DDistance(ClosestAirbase:GetCoordinate())
|
||||
env.info("Distance closest to pickup airbase = "..Dist)
|
||||
--env.info("Distance closest to pickup airbase = "..Dist)
|
||||
|
||||
if Airplane:InAir() or Dist>500 then
|
||||
|
||||
env.info("FF onafterpickup routing to airbase "..ClosestAirbase:GetName())
|
||||
--env.info("FF onafterpickup routing to airbase "..ClosestAirbase:GetName())
|
||||
|
||||
-- Route aircraft to pickup airbase.
|
||||
self:Route( Airplane, Airbase, Speed )
|
||||
@ -302,7 +302,7 @@ function AI_CARGO_AIRPLANE:onafterPickup( Airplane, From, Event, To, Coordinate,
|
||||
self.RoutePickup = true
|
||||
|
||||
else
|
||||
env.info("FF onafterpick calling landed")
|
||||
--env.info("FF onafterpick calling landed")
|
||||
|
||||
-- We are already at the right airbase ==> Landed ==> triggers loading of troops. Is usually called at engine shutdown event.
|
||||
self.RoutePickup=true
|
||||
@ -312,7 +312,7 @@ function AI_CARGO_AIRPLANE:onafterPickup( Airplane, From, Event, To, Coordinate,
|
||||
|
||||
self:GetParent( self, AI_CARGO_AIRPLANE ).onafterPickup( self, Airplane, From, Event, To, Coordinate, Speed, PickupZone )
|
||||
else
|
||||
env.info("FF onafterpick aircraft not alive")
|
||||
--env.info("FF onafterpick aircraft not alive")
|
||||
end
|
||||
|
||||
|
||||
@ -396,7 +396,7 @@ end
|
||||
-- @param #boolean Uncontrolled If true, spawn group in uncontrolled state.
|
||||
function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed, Uncontrolled )
|
||||
|
||||
if Airplane and Airplane:IsAlive()~=nil then
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
-- Set takeoff type.
|
||||
local Takeoff = SPAWN.Takeoff.Cold
|
||||
|
||||
@ -471,9 +471,9 @@ end
|
||||
-- DeployZoneSet = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
||||
-- AICargoDispatcher = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo, SetDeployZone )
|
||||
--
|
||||
function AI_CARGO_DISPATCHER:NewWithZones( SetCarriers, SetCargos, PickupZoneSet, DeployZoneSet )
|
||||
function AI_CARGO_DISPATCHER:NewWithZones( SetCarrier, SetCargo, PickupZoneSet, DeployZoneSet )
|
||||
|
||||
local self = AI_CARGO_DISPATCHER:New( SetCarriers, SetCargos ) -- #AI_CARGO_DISPATCHER
|
||||
local self = AI_CARGO_DISPATCHER:New( SetCarrier, SetCargo ) -- #AI_CARGO_DISPATCHER
|
||||
|
||||
self.PickupZoneSet = PickupZoneSet
|
||||
self.DeployZoneSet = DeployZoneSet
|
||||
|
||||
@ -109,14 +109,14 @@ AI_CARGO_DISPATCHER_APC = {
|
||||
-- APCSet = SET_GROUP:New():FilterPrefixes( "APC" ):FilterStart()
|
||||
-- CargoSet = SET_CARGO:New():FilterTypes( "Infantry" ):FilterStart()
|
||||
-- DeployZoneSet = SET_ZONE:New():FilterPrefixes( "Deploy" ):FilterStart()
|
||||
-- AICargoDispatcher = AI_CARGO_DISPATCHER_APC:New( APCSet, SCargoSet, nil, DeployZoneSet, 500 )
|
||||
-- AICargoDispatcher = AI_CARGO_DISPATCHER_APC:New( APCSet, CargoSet, nil, DeployZoneSet, 500 )
|
||||
--
|
||||
function AI_CARGO_DISPATCHER_APC:New( APCSet, CargoSet, PickupZoneSet, DeployZoneSet, CombatRadius )
|
||||
|
||||
local self = BASE:Inherit( self, AI_CARGO_DISPATCHER:NewWithZones( APCSet, CargoSet, PickupZoneSet, DeployZoneSet ) ) -- #AI_CARGO_DISPATCHER_APC
|
||||
|
||||
self:SetDeploySpeed( 70, 120 )
|
||||
self:SetPickupSpeed( 70, 120 )
|
||||
self:SetDeploySpeed( 120, 70 )
|
||||
self:SetPickupSpeed( 120, 70 )
|
||||
self:SetPickupRadius( 0, 0 )
|
||||
self:SetDeployRadius( 0, 0 )
|
||||
|
||||
|
||||
@ -650,7 +650,7 @@ function AI_FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, X
|
||||
|
||||
local FollowSet = FollowGroupSet:GetSet()
|
||||
|
||||
local i = 0
|
||||
local i = 1 --FF i=0 caused first unit to have no XSpace! Probably needs further adjustments. This is just a quick work around.
|
||||
|
||||
for FollowID, FollowGroup in pairs( FollowSet ) do
|
||||
|
||||
|
||||
@ -664,11 +664,12 @@ do -- CARGO_GROUP
|
||||
CargoCoordinate = Cargo.CargoObject:GetCoordinate()
|
||||
end
|
||||
|
||||
-- if CargoCoordinate then
|
||||
-- FF check if coordinate could be obtained. This was commented out for some (unknown) reason. But the check seems valid!
|
||||
if CargoCoordinate then
|
||||
Distance = Coordinate:Get2DDistance( CargoCoordinate )
|
||||
-- else
|
||||
-- return false
|
||||
-- end
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
self:F( { Distance = Distance, LoadRadius = self.LoadRadius } )
|
||||
if Distance <= self.LoadRadius then
|
||||
|
||||
@ -538,8 +538,8 @@ end
|
||||
-- SpawnCountryID, SpawnCategoryID
|
||||
-- This method is used by the SPAWN class.
|
||||
-- @param #DATABASE self
|
||||
-- @param #table SpawnTemplate
|
||||
-- @return #DATABASE self
|
||||
-- @param #table SpawnTemplate Template of the group to spawn.
|
||||
-- @return Wrapper.Group#GROUP Spawned group.
|
||||
function DATABASE:Spawn( SpawnTemplate )
|
||||
self:F( SpawnTemplate.name )
|
||||
|
||||
|
||||
@ -260,6 +260,10 @@ EVENTS = {
|
||||
-- @field DCS#Unit.Category TgtCategory (UNIT) The category of the target.
|
||||
-- @field #string TgtTypeName (UNIT) The type name of the target.
|
||||
--
|
||||
-- @field DCS#Airbase place The @{DCS#Airbase}
|
||||
-- @field Wrapper.Airbase#AIRBASE Place The MOOSE airbase object.
|
||||
-- @field #string PlaceName The name of the airbase.
|
||||
--
|
||||
-- @field weapon The weapon used during the event.
|
||||
-- @field Weapon
|
||||
-- @field WeaponName
|
||||
@ -941,6 +945,12 @@ function EVENT:onEvent( Event )
|
||||
--Event.WeaponTgtDCSUnit = Event.Weapon:getTarget()
|
||||
end
|
||||
|
||||
-- Place should be given for takeoff and landing events as well as base captured. It should be a DCS airbase.
|
||||
if Event.place then
|
||||
Event.Place=AIRBASE:Find(Event.place)
|
||||
Event.PlaceName=Event.Place:GetName()
|
||||
end
|
||||
|
||||
-- @FC: something like this should be added.
|
||||
--[[
|
||||
if Event.idx then
|
||||
@ -968,7 +978,7 @@ function EVENT:onEvent( Event )
|
||||
local PriorityEnd = PriorityOrder == -1 and 1 or 5
|
||||
|
||||
if Event.IniObjectCategory ~= Object.Category.STATIC then
|
||||
self:E( { EventMeta.Text, Event, Event.IniDCSUnitName, Event.TgtDCSUnitName, PriorityOrder } )
|
||||
self:T( { EventMeta.Text, Event, Event.IniDCSUnitName, Event.TgtDCSUnitName, PriorityOrder } )
|
||||
end
|
||||
|
||||
for EventPriority = PriorityBegin, PriorityEnd, PriorityOrder do
|
||||
|
||||
@ -295,7 +295,8 @@ end
|
||||
--- Sends a MESSAGE to a Coalition if the given Condition is true.
|
||||
-- @param #MESSAGE self
|
||||
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}.
|
||||
-- @return #MESSAGE
|
||||
-- @param #boolean Condition Sends the message only if the condition is true.
|
||||
-- @return #MESSAGE self
|
||||
function MESSAGE:ToCoalitionIf( CoalitionSide, Condition )
|
||||
self:F( CoalitionSide )
|
||||
|
||||
|
||||
@ -408,7 +408,7 @@ do -- COORDINATE
|
||||
--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, UNIT:Find(ZoneObject))
|
||||
gotunits=true
|
||||
|
||||
elseif (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then
|
||||
@ -432,7 +432,7 @@ do -- COORDINATE
|
||||
world.searchObjects(scanobjects, SphereSearch, EvaluateZone)
|
||||
|
||||
for _,unit in pairs(Units) do
|
||||
self:T(string.format("Scan found unit %s", unit:getName()))
|
||||
self:T(string.format("Scan found unit %s", unit:GetName()))
|
||||
end
|
||||
for _,static in pairs(Statics) do
|
||||
self:T(string.format("Scan found static %s", static:getName()))
|
||||
@ -729,6 +729,20 @@ do -- COORDINATE
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the heading from this to another coordinate.
|
||||
-- @param #COORDINATE self
|
||||
-- @param #COORDINATE ToCoordinate
|
||||
-- @return #number Heading in degrees.
|
||||
function COORDINATE:HeadingTo(ToCoordinate)
|
||||
local dz=ToCoordinate.z-self.z
|
||||
local dx=ToCoordinate.x-self.x
|
||||
local heading=math.deg(math.atan2(dz, dx))
|
||||
if heading < 0 then
|
||||
heading = 360 + heading
|
||||
end
|
||||
return heading
|
||||
end
|
||||
|
||||
--- Returns the wind direction (from) and strength.
|
||||
-- @param #COORDINATE self
|
||||
-- @param height (Optional) parameter specifying the height ASL. The minimum height will be always be the land height since the wind is zero below the ground.
|
||||
@ -949,21 +963,53 @@ do -- COORDINATE
|
||||
-- @param #COORDINATE.WaypointAction Action The route point action.
|
||||
-- @param DCS#Speed Speed Airspeed in km/h. Default is 500 km/h.
|
||||
-- @param #boolean SpeedLocked true means the speed is locked.
|
||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase for takeoff and landing points.
|
||||
-- @param #table DCSTasks A table of @{DCS#Task} items which are executed at the waypoint.
|
||||
-- @param #string description A text description of the waypoint, which will be shown on the F10 map.
|
||||
-- @return #table The route point.
|
||||
function COORDINATE:WaypointAir( AltType, Type, Action, Speed, SpeedLocked )
|
||||
function COORDINATE:WaypointAir( AltType, Type, Action, Speed, SpeedLocked, airbase, DCSTasks, description )
|
||||
self:F2( { AltType, Type, Action, Speed, SpeedLocked } )
|
||||
|
||||
-- Defaults
|
||||
AltType=AltType or "RADIO"
|
||||
if SpeedLocked==nil then
|
||||
SpeedLocked=true
|
||||
end
|
||||
Speed=Speed or 500
|
||||
|
||||
-- Waypoint array.
|
||||
local RoutePoint = {}
|
||||
|
||||
-- Coordinates.
|
||||
RoutePoint.x = self.x
|
||||
RoutePoint.y = self.z
|
||||
-- Altitude.
|
||||
RoutePoint.alt = self.y
|
||||
RoutePoint.alt_type = AltType or "RADIO"
|
||||
|
||||
RoutePoint.alt_type = AltType
|
||||
-- Waypoint type.
|
||||
RoutePoint.type = Type or nil
|
||||
RoutePoint.action = Action or nil
|
||||
-- Set speed/ETA.
|
||||
RoutePoint.speed = Speed/3.6
|
||||
RoutePoint.speed_locked = SpeedLocked
|
||||
RoutePoint.ETA=nil
|
||||
RoutePoint.ETA_locked = false
|
||||
-- Waypoint description.
|
||||
RoutePoint.name=description
|
||||
-- Airbase parameters for takeoff and landing points.
|
||||
if airbase then
|
||||
local AirbaseID = airbase:GetID()
|
||||
local AirbaseCategory = airbase:GetDesc().category
|
||||
if AirbaseCategory == Airbase.Category.SHIP or AirbaseCategory == Airbase.Category.HELIPAD then
|
||||
RoutePoint.linkUnit = AirbaseID
|
||||
RoutePoint.helipadId = AirbaseID
|
||||
elseif AirbaseCategory == Airbase.Category.AIRDROME then
|
||||
RoutePoint.airdromeId = AirbaseID
|
||||
else
|
||||
self:T("ERROR: Unknown airbase category in COORDINATE:WaypointAir()!")
|
||||
end
|
||||
end
|
||||
|
||||
RoutePoint.speed = ( Speed and Speed / 3.6 ) or ( 500 / 3.6 )
|
||||
RoutePoint.speed_locked = true
|
||||
|
||||
-- ["task"] =
|
||||
-- {
|
||||
@ -976,13 +1022,13 @@ do -- COORDINATE
|
||||
-- }, -- end of ["params"]
|
||||
-- }, -- end of ["task"]
|
||||
|
||||
|
||||
-- Waypoint tasks.
|
||||
RoutePoint.task = {}
|
||||
RoutePoint.task.id = "ComboTask"
|
||||
RoutePoint.task.params = {}
|
||||
RoutePoint.task.params.tasks = {}
|
||||
|
||||
RoutePoint.task.params.tasks = DCSTasks or {}
|
||||
|
||||
self:T({RoutePoint=RoutePoint})
|
||||
return RoutePoint
|
||||
end
|
||||
|
||||
@ -991,9 +1037,11 @@ do -- COORDINATE
|
||||
-- @param #COORDINATE self
|
||||
-- @param #COORDINATE.WaypointAltType AltType The altitude type.
|
||||
-- @param DCS#Speed Speed Airspeed in km/h.
|
||||
-- @param #table DCSTasks (Optional) A table of @{DCS#Task} items which are executed at the waypoint.
|
||||
-- @param #string description (Optional) A text description of the waypoint, which will be shown on the F10 map.
|
||||
-- @return #table The route point.
|
||||
function COORDINATE:WaypointAirTurningPoint( AltType, Speed )
|
||||
return self:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed )
|
||||
function COORDINATE:WaypointAirTurningPoint( AltType, Speed, DCSTasks, description )
|
||||
return self:WaypointAir( AltType, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, Speed, true, nil, DCSTasks, description )
|
||||
end
|
||||
|
||||
|
||||
@ -1098,11 +1146,14 @@ do -- COORDINATE
|
||||
|
||||
--- Gets the nearest airbase with respect to the current coordinates.
|
||||
-- @param #COORDINATE self
|
||||
-- @param #number AirbaseCategory Category of the airbase.
|
||||
-- @param #number Category (Optional) Category of the airbase. Enumerator of @{Wrapper.Airbase#AIRBASE.Category}.
|
||||
-- @param #number Coalition (Optional) Coalition of the airbase.
|
||||
-- @return Wrapper.Airbase#AIRBASE Closest Airbase to the given coordinate.
|
||||
-- @return #number Distance to the closest airbase in meters.
|
||||
function COORDINATE:GetClosestAirbase(AirbaseCategory)
|
||||
local airbases=AIRBASE.GetAllAirbases()
|
||||
function COORDINATE:GetClosestAirbase(Category, Coalition)
|
||||
|
||||
-- Get all airbases of the map.
|
||||
local airbases=AIRBASE.GetAllAirbases(Coalition)
|
||||
|
||||
local closest=nil
|
||||
local distmin=nil
|
||||
@ -1110,7 +1161,7 @@ do -- COORDINATE
|
||||
for _,_airbase in pairs(airbases) do
|
||||
local airbase=_airbase --Wrapper.Airbase#AIRBASE
|
||||
local category=airbase:GetDesc().category
|
||||
if AirbaseCategory and AirbaseCategory==category or AirbaseCategory==nil then
|
||||
if Category and Category==category or Category==nil then
|
||||
local dist=self:Get2DDistance(airbase:GetCoordinate())
|
||||
if closest==nil then
|
||||
distmin=dist
|
||||
@ -1205,11 +1256,16 @@ do -- COORDINATE
|
||||
return self:GetClosestParkingSpot(airbase, terminaltype, false)
|
||||
end
|
||||
|
||||
--- Gets the nearest coordinate to a road.
|
||||
--- Gets the nearest coordinate to a road (or railroad).
|
||||
-- @param #COORDINATE self
|
||||
-- @param #boolean Railroad (Optional) If true, closest point to railroad is returned rather than closest point to conventional road. Default false.
|
||||
-- @return #COORDINATE Coordinate of the nearest road.
|
||||
function COORDINATE:GetClosestPointToRoad()
|
||||
local x,y = land.getClosestPointOnRoads("roads", self.x, self.z)
|
||||
function COORDINATE:GetClosestPointToRoad(Railroad)
|
||||
local roadtype="roads"
|
||||
if Railroad==true then
|
||||
roadtype="railroads"
|
||||
end
|
||||
local x,y = land.getClosestPointOnRoads(roadtype, self.x, self.z)
|
||||
local vec2={ x = x, y = y }
|
||||
return COORDINATE:NewFromVec2(vec2)
|
||||
end
|
||||
@ -1222,9 +1278,12 @@ do -- COORDINATE
|
||||
-- @param #COORDINATE ToCoord Coordinate of destination.
|
||||
-- @param #boolean IncludeEndpoints (Optional) Include the coordinate itself and the ToCoordinate in the path.
|
||||
-- @param #boolean Railroad (Optional) If true, path on railroad is returned. Default false.
|
||||
-- @param #boolean MarkPath (Optional) If true, place markers on F10 map along the path.
|
||||
-- @param #boolean SmokePath (Optional) If true, put (green) smoke along the
|
||||
-- @return #table Table of coordinates on road. If no path on road can be found, nil is returned or just the endpoints.
|
||||
-- @return #number The length of the total path.
|
||||
function COORDINATE:GetPathOnRoad(ToCoord, IncludeEndpoints, Railroad)
|
||||
-- @return #number Tonal length of path.
|
||||
-- @return #boolean If true a valid path on road/rail was found. If false, only the direct way is possible.
|
||||
function COORDINATE:GetPathOnRoad(ToCoord, IncludeEndpoints, Railroad, MarkPath, SmokePath)
|
||||
|
||||
-- Set road type.
|
||||
local RoadType="roads"
|
||||
@ -1244,17 +1303,42 @@ do -- COORDINATE
|
||||
Path[1]=self
|
||||
end
|
||||
|
||||
-- Assume we could get a valid path.
|
||||
local GotPath=true
|
||||
|
||||
-- Check that DCS routine actually returned a path. There are situations where this is not the case.
|
||||
if path then
|
||||
|
||||
-- Include all points on road.
|
||||
for _,_vec2 in ipairs(path) do
|
||||
Path[#Path+1]=COORDINATE:NewFromVec2(_vec2)
|
||||
--COORDINATE:NewFromVec2(_vec2):SmokeGreen()
|
||||
for _i,_vec2 in ipairs(path) do
|
||||
|
||||
local coord=COORDINATE:NewFromVec2(_vec2)
|
||||
|
||||
Path[#Path+1]=coord
|
||||
|
||||
if MarkPath then
|
||||
coord:MarkToAll(string.format("Path segment %d.", _i))
|
||||
end
|
||||
if SmokePath then
|
||||
coord:SmokeGreen()
|
||||
end
|
||||
end
|
||||
|
||||
-- Mark/smoke endpoints
|
||||
if IncludeEndpoints then
|
||||
if MarkPath then
|
||||
COORDINATE:NewFromVec2(path[1]):MarkToAll("Path Initinal Point")
|
||||
COORDINATE:NewFromVec2(path[1]):MarkToAll("Path Final Point")
|
||||
end
|
||||
if SmokePath then
|
||||
COORDINATE:NewFromVec2(path[1]):SmokeBlue()
|
||||
COORDINATE:NewFromVec2(path[#path]):SmokeBlue()
|
||||
end
|
||||
end
|
||||
|
||||
else
|
||||
self:E("Path is nil. No valid path on road could be found.")
|
||||
GotPath=false
|
||||
end
|
||||
|
||||
-- Include end point, which might not be on road.
|
||||
@ -1272,7 +1356,7 @@ do -- COORDINATE
|
||||
return nil,nil
|
||||
end
|
||||
|
||||
return Path, Way
|
||||
return Path, Way, GotPath
|
||||
end
|
||||
|
||||
--- Gets the surface type at the coordinate.
|
||||
@ -1429,7 +1513,7 @@ do -- COORDINATE
|
||||
--- Flares the point in a color.
|
||||
-- @param #COORDINATE self
|
||||
-- @param Utilities.Utils#FLARECOLOR FlareColor
|
||||
-- @param DCS#Azimuth (optional) Azimuth The azimuth of the flare direction. The default azimuth is 0.
|
||||
-- @param DCS#Azimuth Azimuth (optional) The azimuth of the flare direction. The default azimuth is 0.
|
||||
function COORDINATE:Flare( FlareColor, Azimuth )
|
||||
self:F2( { FlareColor } )
|
||||
trigger.action.signalFlare( self:GetVec3(), FlareColor, Azimuth and Azimuth or 0 )
|
||||
@ -1437,7 +1521,7 @@ do -- COORDINATE
|
||||
|
||||
--- Flare the COORDINATE White.
|
||||
-- @param #COORDINATE self
|
||||
-- @param DCS#Azimuth (optional) Azimuth The azimuth of the flare direction. The default azimuth is 0.
|
||||
-- @param DCS#Azimuth Azimuth (optional) The azimuth of the flare direction. The default azimuth is 0.
|
||||
function COORDINATE:FlareWhite( Azimuth )
|
||||
self:F2( Azimuth )
|
||||
self:Flare( FLARECOLOR.White, Azimuth )
|
||||
@ -1445,7 +1529,7 @@ do -- COORDINATE
|
||||
|
||||
--- Flare the COORDINATE Yellow.
|
||||
-- @param #COORDINATE self
|
||||
-- @param DCS#Azimuth (optional) Azimuth The azimuth of the flare direction. The default azimuth is 0.
|
||||
-- @param DCS#Azimuth Azimuth (optional) The azimuth of the flare direction. The default azimuth is 0.
|
||||
function COORDINATE:FlareYellow( Azimuth )
|
||||
self:F2( Azimuth )
|
||||
self:Flare( FLARECOLOR.Yellow, Azimuth )
|
||||
@ -1453,7 +1537,7 @@ do -- COORDINATE
|
||||
|
||||
--- Flare the COORDINATE Green.
|
||||
-- @param #COORDINATE self
|
||||
-- @param DCS#Azimuth (optional) Azimuth The azimuth of the flare direction. The default azimuth is 0.
|
||||
-- @param DCS#Azimuth Azimuth (optional) The azimuth of the flare direction. The default azimuth is 0.
|
||||
function COORDINATE:FlareGreen( Azimuth )
|
||||
self:F2( Azimuth )
|
||||
self:Flare( FLARECOLOR.Green, Azimuth )
|
||||
|
||||
@ -496,7 +496,7 @@ end
|
||||
|
||||
--- Sets the coalition of the spawned group. Note that it might be necessary to also set the country explicitly!
|
||||
-- @param #SPAWN self
|
||||
-- @param #DCS.coalition Coaliton Coaliton of the group as number of enumerator, i.e. 0=coaliton.side.NEUTRAL, 1=coaliton.side.RED, 2=coalition.side.BLUE.
|
||||
-- @param DCS#coalition.side Coalition Coalition of the group as number of enumerator, i.e. 0=coaliton.side.NEUTRAL, 1=coaliton.side.RED, 2=coalition.side.BLUE.
|
||||
-- @return #SPAWN self
|
||||
function SPAWN:InitCoalition( Coalition )
|
||||
self:F({coalition=Coalition})
|
||||
@ -1301,6 +1301,7 @@ end
|
||||
-- @param #number TakeoffAltitude (optional) The altitude above the ground.
|
||||
-- @param Wrapper.Airbase#AIRBASE.TerminalType TerminalType (optional) The terminal type the aircraft should be spawned at. See @{Wrapper.Airbase#AIRBASE.TerminalType}.
|
||||
-- @param #boolean EmergencyAirSpawn (optional) If true (default), groups are spawned in air if there is no parking spot at the airbase. If false, nothing is spawned if no parking spot is available.
|
||||
-- @param #table Parkingdata (optional) Table holding the coordinates and terminal ids for all units of the group. Spawning will be forced to happen at exactily these spots!
|
||||
-- @return Wrapper.Group#GROUP that was spawned or nil when nothing was spawned.
|
||||
-- @usage
|
||||
-- Spawn_Plane = SPAWN:New( "Plane" )
|
||||
@ -1321,7 +1322,7 @@ end
|
||||
--
|
||||
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold, nil, AIRBASE.TerminalType.OpenBig )
|
||||
--
|
||||
function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType, EmergencyAirSpawn ) -- R2.2, R2.4
|
||||
function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType, EmergencyAirSpawn, Parkingdata ) -- R2.2, R2.4
|
||||
self:F( { self.SpawnTemplatePrefix, SpawnAirbase, Takeoff, TakeoffAltitude, TerminalType } )
|
||||
|
||||
-- Get position of airbase.
|
||||
@ -1436,6 +1437,10 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
self:T(string.format("Group %s is spawned on farp/ship/runway %s.", self.SpawnTemplatePrefix, SpawnAirbase:GetName()))
|
||||
nfree=SpawnAirbase:GetFreeParkingSpotsNumber(termtype, true)
|
||||
spots=SpawnAirbase:GetFreeParkingSpotsTable(termtype, true)
|
||||
elseif Parkingdata~=nil then
|
||||
-- Parking data explicitly set by user as input parameter.
|
||||
nfree=#Parkingdata
|
||||
spots=Parkingdata
|
||||
else
|
||||
if ishelo then
|
||||
if termtype==nil then
|
||||
@ -1513,7 +1518,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
PointVec3=spots[1].Coordinate
|
||||
|
||||
else
|
||||
-- If there is absolutely not spot ==> air start!
|
||||
-- If there is absolutely no spot ==> air start!
|
||||
_notenough=true
|
||||
end
|
||||
|
||||
@ -1617,6 +1622,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
||||
SpawnTemplate.units[UnitID].y = parkingspots[UnitID].z
|
||||
SpawnTemplate.units[UnitID].alt = parkingspots[UnitID].y
|
||||
|
||||
--parkingspots[UnitID]:MarkToAll(string.format("Group %s spawning at airbase %s on parking spot id %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), parkingindex[UnitID]))
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
@ -189,11 +189,8 @@ function SPAWNSTATIC:SpawnFromPointVec2( PointVec2, Heading, NewName ) --R2.1
|
||||
end
|
||||
|
||||
|
||||
--- Creates the original @{Static} at a POINT_VEC2.
|
||||
--- Respawns the original @{Static}.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param Core.Point#POINT_VEC2 PointVec2 The 2D coordinate where to spawn the static.
|
||||
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
||||
-- @param #string (optional) The name of the new static.
|
||||
-- @return #SPAWNSTATIC
|
||||
function SPAWNSTATIC:ReSpawn()
|
||||
|
||||
@ -202,7 +199,6 @@ function SPAWNSTATIC:ReSpawn()
|
||||
if StaticTemplate then
|
||||
|
||||
local StaticUnitTemplate = StaticTemplate.units[1]
|
||||
|
||||
StaticTemplate.route = nil
|
||||
StaticTemplate.groupId = nil
|
||||
|
||||
|
||||
@ -317,7 +317,8 @@ end
|
||||
|
||||
--- Set the randomization probability of a zone to be selected.
|
||||
-- @param #ZONE_BASE self
|
||||
-- @param ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
||||
-- @param #number ZoneProbability A value between 0 and 1. 0 = 0% and 1 = 100% probability.
|
||||
-- @return #ZONE_BASE self
|
||||
function ZONE_BASE:SetZoneProbability( ZoneProbability )
|
||||
self:F( { self:GetName(), ZoneProbability = ZoneProbability } )
|
||||
|
||||
@ -934,7 +935,7 @@ end
|
||||
function ZONE_RADIUS:GetRandomCoordinate( inner, outer )
|
||||
self:F( self.ZoneName, inner, outer )
|
||||
|
||||
local Coordinate = COORDINATE:NewFromVec2( self:GetRandomVec2() )
|
||||
local Coordinate = COORDINATE:NewFromVec2( self:GetRandomVec2(inner, outer) )
|
||||
|
||||
self:T3( { Coordinate = Coordinate } )
|
||||
|
||||
@ -1079,6 +1080,7 @@ function ZONE_UNIT:GetVec2()
|
||||
local ZoneVec2 = self.ZoneUNIT:GetVec2()
|
||||
if ZoneVec2 then
|
||||
|
||||
local heading
|
||||
if self.relative_to_unit then
|
||||
heading = ( self.ZoneUNIT:GetHeading() or 0.0 ) * math.pi / 180.0
|
||||
else
|
||||
@ -1118,7 +1120,8 @@ function ZONE_UNIT:GetRandomVec2()
|
||||
self:F( self.ZoneName )
|
||||
|
||||
local RandomVec2 = {}
|
||||
local Vec2 = self.ZoneUNIT:GetVec2()
|
||||
--local Vec2 = self.ZoneUNIT:GetVec2() -- FF: This does not take care of the new offset feature!
|
||||
local Vec2 = self:GetVec2()
|
||||
|
||||
if not Vec2 then
|
||||
Vec2 = self.LastVec2
|
||||
@ -1609,16 +1612,16 @@ do -- ZONE_AIRBASE
|
||||
|
||||
--- Constructor to create a ZONE_AIRBASE instance, taking the zone name, a zone @{Wrapper.Airbase#AIRBASE} and a radius.
|
||||
-- @param #ZONE_AIRBASE self
|
||||
-- @param #string ZoneName Name of the zone.
|
||||
-- @param Wrapper.Airbase#AIRBASE ZoneAirbase The @{Wrapper.Airbase} as the center of the zone.
|
||||
-- @param DCS#Distance Radius The radius of the zone.
|
||||
-- @param #string AirbaseName Name of the airbase.
|
||||
-- @param DCS#Distance Radius (Optional)The radius of the zone in meters. Default 4000 meters.
|
||||
-- @return #ZONE_AIRBASE self
|
||||
function ZONE_AIRBASE:New( AirbaseName )
|
||||
function ZONE_AIRBASE:New( AirbaseName, Radius )
|
||||
|
||||
Radius=Radius or 4000
|
||||
|
||||
local Airbase = AIRBASE:FindByName( AirbaseName )
|
||||
|
||||
local self = BASE:Inherit( self, ZONE_RADIUS:New( AirbaseName, Airbase:GetVec2(), 4000 ) )
|
||||
local self = BASE:Inherit( self, ZONE_RADIUS:New( AirbaseName, Airbase:GetVec2(), Radius ) )
|
||||
|
||||
self._.ZoneAirbase = Airbase
|
||||
self._.ZoneVec2Cache = self._.ZoneAirbase:GetVec2()
|
||||
|
||||
@ -208,9 +208,6 @@ do -- country
|
||||
-- @type country
|
||||
-- @field #country.id id
|
||||
|
||||
--- [DCS Enum country](https://wiki.hoggitworld.com/view/DCS_enum_country)
|
||||
-- @field #country
|
||||
country = {}
|
||||
|
||||
--- [DCS enumerator country](https://wiki.hoggitworld.com/view/DCS_enum_country)
|
||||
-- @type country.id
|
||||
@ -289,6 +286,8 @@ do -- country
|
||||
-- @field OMAN
|
||||
-- @field UNITED_ARAB_EMIRATES
|
||||
|
||||
country = {} --#country
|
||||
|
||||
end -- country
|
||||
|
||||
|
||||
|
||||
@ -549,7 +549,7 @@ RAT.id="RAT | "
|
||||
--- RAT version.
|
||||
-- @list version
|
||||
RAT.version={
|
||||
version = "2.3.3",
|
||||
version = "2.3.4",
|
||||
print = true,
|
||||
}
|
||||
|
||||
@ -2064,8 +2064,9 @@ end
|
||||
-- @param #table _waypoint First waypoint to be used (for continue journey, commute, etc).
|
||||
-- @param Core.Point#COORDINATE _lastpos (Optional) Position where the aircraft will be spawned.
|
||||
-- @param #number _nrespawn Number of already performed respawn attempts (e.g. spawning on runway bug).
|
||||
-- @param #table parkingdata Explicitly specify the parking spots when spawning at an airport.
|
||||
-- @return #number Spawn index.
|
||||
function RAT:_SpawnWithRoute(_departure, _destination, _takeoff, _landing, _livery, _waypoint, _lastpos, _nrespawn)
|
||||
function RAT:_SpawnWithRoute(_departure, _destination, _takeoff, _landing, _livery, _waypoint, _lastpos, _nrespawn, parkingdata)
|
||||
self:F({rat=RAT.id, departure=_departure, destination=_destination, takeoff=_takeoff, landing=_landing, livery=_livery, waypoint=_waypoint, lastpos=_lastpos, nrespawn=_nrespawn})
|
||||
|
||||
-- Set takeoff type.
|
||||
@ -2115,7 +2116,7 @@ function RAT:_SpawnWithRoute(_departure, _destination, _takeoff, _landing, _live
|
||||
end
|
||||
|
||||
-- Modify the spawn template to follow the flight plan.
|
||||
local successful=self:_ModifySpawnTemplate(waypoints, livery, _lastpos, departure, takeoff)
|
||||
local successful=self:_ModifySpawnTemplate(waypoints, livery, _lastpos, departure, takeoff, parkingdata)
|
||||
if not successful then
|
||||
return nil
|
||||
end
|
||||
@ -2458,7 +2459,7 @@ function RAT:_SetRoute(takeoff, landing, _departure, _destination, _waypoint)
|
||||
local VxCruiseMin = math.min(VxCruiseMax*0.70, 166)
|
||||
|
||||
-- Cruise speed (randomized). Expectation value at midpoint between min and max.
|
||||
local VxCruise = self:_Random_Gaussian((VxCruiseMax-VxCruiseMin)/2+VxCruiseMin, (VxCruiseMax-VxCruiseMax)/4, VxCruiseMin, VxCruiseMax)
|
||||
local VxCruise = UTILS.RandomGaussian((VxCruiseMax-VxCruiseMin)/2+VxCruiseMin, (VxCruiseMax-VxCruiseMax)/4, VxCruiseMin, VxCruiseMax)
|
||||
|
||||
-- Climb speed 90% ov Vmax but max 720 km/h.
|
||||
local VxClimb = math.min(self.aircraft.Vmax*0.90, 200)
|
||||
@ -2816,7 +2817,7 @@ function RAT:_SetRoute(takeoff, landing, _departure, _destination, _waypoint)
|
||||
end
|
||||
|
||||
-- Set cruise altitude. Selected from Gaussian distribution but limited to FLmin and FLmax.
|
||||
local FLcruise=self:_Random_Gaussian(FLcruise_expect, math.abs(FLmax-FLmin)/4, FLmin, FLmax)
|
||||
local FLcruise=UTILS.RandomGaussian(FLcruise_expect, math.abs(FLmax-FLmin)/4, FLmin, FLmax)
|
||||
|
||||
-- Overrule setting if user specified a flight level explicitly.
|
||||
if self.FLuser then
|
||||
@ -5013,38 +5014,6 @@ function RAT:_Randomize(value, fac, lower, upper)
|
||||
return r
|
||||
end
|
||||
|
||||
--- Generate Gaussian pseudo-random numbers.
|
||||
-- @param #number x0 Expectation value of distribution.
|
||||
-- @param #number sigma (Optional) Standard deviation. Default 10.
|
||||
-- @param #number xmin (Optional) Lower cut-off value.
|
||||
-- @param #number xmax (Optional) Upper cut-off value.
|
||||
-- @return #number Gaussian random number.
|
||||
function RAT:_Random_Gaussian(x0, sigma, xmin, xmax)
|
||||
|
||||
-- Standard deviation. Default 10 if not given.
|
||||
sigma=sigma or 10
|
||||
|
||||
local r
|
||||
local gotit=false
|
||||
local i=0
|
||||
while not gotit do
|
||||
|
||||
-- Uniform numbers in [0,1). We need two.
|
||||
local x1=math.random()
|
||||
local x2=math.random()
|
||||
|
||||
-- Transform to Gaussian exp(-(x-x0)²/(2*sigma²).
|
||||
r = math.sqrt(-2*sigma*sigma * math.log(x1)) * math.cos(2*math.pi * x2) + x0
|
||||
|
||||
i=i+1
|
||||
if (r>=xmin and r<=xmax) or i>100 then
|
||||
gotit=true
|
||||
end
|
||||
end
|
||||
|
||||
return r
|
||||
|
||||
end
|
||||
|
||||
--- Place markers of the waypoints. Note we assume a very specific number and type of waypoints here.
|
||||
-- @param #RAT self
|
||||
@ -5103,9 +5072,10 @@ end
|
||||
-- @param Core.Point#COORDINATE spawnplace (Optional) Place where spawning should happen. If not present, first waypoint is taken.
|
||||
-- @param Wrapper.Airbase#AIRBASE departure Departure airbase or zone.
|
||||
-- @param #number takeoff Takeoff type.
|
||||
-- @param #table parkingdata Parking data, i.e. parking spot coordinates and terminal ids for all units of the group.
|
||||
-- @return #boolean True if modification was successful or nil if not, e.g. when no parking space was found and spawn in air is disabled.
|
||||
function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, takeoff)
|
||||
self:F2({waypoints=waypoints, livery=livery, spawnplace=spawnplace, departure=departure, takeoff=takeoff})
|
||||
function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, takeoff, parkingdata)
|
||||
self:F2({waypoints=waypoints, livery=livery, spawnplace=spawnplace, departure=departure, takeoff=takeoff, parking=parkingdata})
|
||||
|
||||
-- The 3D vector of the first waypoint, i.e. where we actually spawn the template group.
|
||||
local PointVec3 = COORDINATE:New(waypoints[1].x, waypoints[1].alt, waypoints[1].y)
|
||||
@ -5193,6 +5163,10 @@ function RAT:_ModifySpawnTemplate(waypoints, livery, spawnplace, departure, take
|
||||
self:T(RAT.id..string.format("Group %s is spawned on farp/ship/runway %s.", self.alias, departure:GetName()))
|
||||
nfree=departure:GetFreeParkingSpotsNumber(termtype, true)
|
||||
spots=departure:GetFreeParkingSpotsTable(termtype, true)
|
||||
elseif parkingdata~=nil then
|
||||
-- Parking data explicitly set by user as input parameter.
|
||||
nfree=#parkingdata
|
||||
spots=parkingdata
|
||||
else
|
||||
-- Helo is spawned.
|
||||
if self.category==RAT.cat.heli then
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -592,3 +592,70 @@ function UTILS.DisplayMissionTime(duration)
|
||||
local text=string.format("Time: %s - %02d:%02d", local_time, mission_time_minutes, mission_time_seconds)
|
||||
MESSAGE:New(text, duration):ToAll()
|
||||
end
|
||||
|
||||
|
||||
--- Generate a Gaussian pseudo-random number.
|
||||
-- @param #number x0 Expectation value of distribution.
|
||||
-- @param #number sigma (Optional) Standard deviation. Default 10.
|
||||
-- @param #number xmin (Optional) Lower cut-off value.
|
||||
-- @param #number xmax (Optional) Upper cut-off value.
|
||||
-- @param #number imax (Optional) Max number of tries to get a value between xmin and xmax (if specified). Default 100.
|
||||
-- @return #number Gaussian random number.
|
||||
function UTILS.RandomGaussian(x0, sigma, xmin, xmax, imax)
|
||||
|
||||
-- Standard deviation. Default 10 if not given.
|
||||
sigma=sigma or 10
|
||||
|
||||
-- Max attempts.
|
||||
imax=imax or 100
|
||||
|
||||
local r
|
||||
local gotit=false
|
||||
local i=0
|
||||
while not gotit do
|
||||
|
||||
-- Uniform numbers in [0,1). We need two.
|
||||
local x1=math.random()
|
||||
local x2=math.random()
|
||||
|
||||
-- Transform to Gaussian exp(-(x-x0)²/(2*sigma²).
|
||||
r = math.sqrt(-2*sigma*sigma * math.log(x1)) * math.cos(2*math.pi * x2) + x0
|
||||
|
||||
i=i+1
|
||||
if (r>=xmin and r<=xmax) or i>imax then
|
||||
gotit=true
|
||||
end
|
||||
end
|
||||
|
||||
return r
|
||||
end
|
||||
|
||||
--- Randomize a value by a certain amount.
|
||||
-- @param #number value The value which should be randomized
|
||||
-- @param #number fac Randomization factor.
|
||||
-- @param #number lower (Optional) Lower limit of the returned value.
|
||||
-- @param #number upper (Optional) Upper limit of the returned value.
|
||||
-- @return #number Randomized value.
|
||||
-- @usage UTILS.Randomize(100, 0.1) returns a value between 90 and 110, i.e. a plus/minus ten percent variation.
|
||||
-- @usage UTILS.Randomize(100, 0.5, nil, 120) returns a value between 50 and 120, i.e. a plus/minus fivty percent variation with upper bound 120.
|
||||
function UTILS.Randomize(value, fac, lower, upper)
|
||||
local min
|
||||
if lower then
|
||||
min=math.max(value-value*fac, lower)
|
||||
else
|
||||
min=value-value*fac
|
||||
end
|
||||
local max
|
||||
if upper then
|
||||
max=math.min(value+value*fac, upper)
|
||||
else
|
||||
max=value+value*fac
|
||||
end
|
||||
|
||||
local r=math.random(min, max)
|
||||
|
||||
return r
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
--
|
||||
-- ### Author: **FlightControl**
|
||||
--
|
||||
-- ### Contributions:
|
||||
-- ### Contributions: **funkyfranky**
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
@ -261,6 +261,16 @@ AIRBASE.PersianGulf = {
|
||||
["Kerman_Airport"] = "Kerman Airport",
|
||||
}
|
||||
|
||||
--- AIRBASE.ParkingSpot ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
||||
-- @type AIRBASE.ParkingSpot
|
||||
-- @field Core.Point#COORDINATE Coordinate Coordinate of the parking spot.
|
||||
-- @field #number TerminalID Terminal ID of the spot. Generally, this is not the same number as displayed in the mission editor.
|
||||
-- @field #AIRBASE.TerminalType TerminalType Type of the spot, i.e. for which type of aircraft it can be used.
|
||||
-- @field #boolean TOAC Takeoff or landing aircarft. I.e. this stop is occupied currently by an aircraft until it took of or until it landed.
|
||||
-- @field #boolean Free This spot is currently free, i.e. there is no alive aircraft on it at the present moment.
|
||||
-- @field #number TerminalID0 Unknown what this means. If you know, please tell us!
|
||||
-- @field #number DistToRwy Distance to runway in meters. Currently bugged and giving the same number as the TerminalID.
|
||||
|
||||
--- Terminal Types of parking spots. See also https://wiki.hoggitworld.com/view/DCS_func_getParking
|
||||
--
|
||||
-- Supported types are:
|
||||
@ -273,7 +283,16 @@ AIRBASE.PersianGulf = {
|
||||
-- * AIRBASE.TerminalType.OpenMedOrBig = 176: Combines OpenMed and OpenBig spots.
|
||||
-- * AIRBASE.TerminalType.HelicopterUnsable = 216: Combines HelicopterOnly, OpenMed and OpenBig.
|
||||
-- * AIRBASE.TerminalType.FighterAircraft = 244: Combines Shelter. OpenMed and OpenBig spots. So effectively all spots usable by fixed wing aircraft.
|
||||
-- @field TerminalType
|
||||
--
|
||||
-- @type AIRBASE.TerminalType
|
||||
-- @field #number Runway 16: Valid spawn points on runway.
|
||||
-- @field #number HelicopterOnly 40: Special spots for Helicopers.
|
||||
-- @field #number Shelter 68: Hardened Air Shelter. Currently only on Caucaus map.
|
||||
-- @field #number OpenMed 72: Open/Shelter air airplane only.
|
||||
-- @field #number OpenBig 104: Open air spawn points. Generally larger but does not guarantee large aircraft are capable of spawning there.
|
||||
-- @field #number OpenMedOrBig 176: Combines OpenMed and OpenBig spots.
|
||||
-- @field #number HelicopterUnsable 216: Combines HelicopterOnly, OpenMed and OpenBig.
|
||||
-- @field #number FighterAircraft 244: Combines Shelter. OpenMed and OpenBig spots. So effectively all spots usable by fixed wing aircraft.
|
||||
AIRBASE.TerminalType = {
|
||||
Runway=16,
|
||||
HelicopterOnly=40,
|
||||
@ -594,8 +613,9 @@ end
|
||||
-- @param #boolean scanscenery (Optional) Scan for scenery as obstacles. Default false. Can cause problems with e.g. shelters.
|
||||
-- @param #boolean verysafe (Optional) If true, wait until an aircraft has taken off until the parking spot is considered to be free. Defaul false.
|
||||
-- @param #number nspots (Optional) Number of freeparking spots requested. Default is the number of aircraft in the group.
|
||||
-- @param #table parkingdata (Optional) Parking spots data table. If not given it is automatically derived from the GetParkingSpotsTable() function.
|
||||
-- @return #table Table of coordinates and terminal IDs of free parking spots. Each table entry has the elements .Coordinate and .TerminalID.
|
||||
function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nspots)
|
||||
function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius, scanunits, scanstatics, scanscenery, verysafe, nspots, parkingdata)
|
||||
|
||||
-- Init default
|
||||
scanradius=scanradius or 50
|
||||
@ -647,7 +667,7 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
||||
-- 1. A spot is considered as NOT free until an aircraft that is present has finally taken off. This might be a bit long especiall at smaller airports.
|
||||
-- 2. A "free" spot does not take the aircraft size into accound. So if two big aircraft are spawned on spots next to each other, they might overlap and get destroyed.
|
||||
-- 3. The routine return a free spot, if there a static objects placed on the spot.
|
||||
local parkingdata=self:GetParkingSpotsTable(terminaltype)
|
||||
parkingdata=parkingdata or self:GetParkingSpotsTable(terminaltype)
|
||||
|
||||
-- Get the aircraft size, i.e. it's longest side of x,z.
|
||||
local aircraft=group:GetUnit(1)
|
||||
@ -679,6 +699,8 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
||||
local _spot=parkingspot.Coordinate -- Core.Point#COORDINATE
|
||||
local _termid=parkingspot.TerminalID
|
||||
|
||||
if AIRBASE._CheckTerminalType(parkingspot.TerminalType, terminaltype) then
|
||||
|
||||
-- Very safe uses the DCS getParking() info to check if a spot is free. Unfortunately, the function returns free=false until the aircraft has actually taken-off.
|
||||
if verysafe and (parkingspot.Free==false or parkingspot.TOAC==true) then
|
||||
|
||||
@ -695,11 +717,12 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
||||
|
||||
-- Check all units.
|
||||
for _,unit in pairs(_units) do
|
||||
|
||||
local _vec3=unit:getPoint()
|
||||
local _coord=COORDINATE:NewFromVec3(_vec3)
|
||||
-- Unis are now returned as MOOSE units not DCS units!
|
||||
--local _vec3=unit:getPoint()
|
||||
--local _coord=COORDINATE:NewFromVec3(_vec3)
|
||||
local _coord=unit:GetCoordinate()
|
||||
local _dist=_coord:Get2DDistance(_spot)
|
||||
local _safe=_overlap(aircraft, true, unit, false,_dist)
|
||||
local _safe=_overlap(aircraft, true, unit, true,_dist)
|
||||
|
||||
if markobstacles then
|
||||
local l,x,y,z=_GetObjectSize(unit)
|
||||
@ -771,7 +794,7 @@ function AIRBASE:FindFreeParkingSpotForAircraft(group, terminaltype, scanradius,
|
||||
if nvalid>=_nspots then
|
||||
return validspots
|
||||
end
|
||||
|
||||
end -- check terminal type
|
||||
end
|
||||
|
||||
-- Retrun spots we found, even if there were not enough.
|
||||
|
||||
@ -617,6 +617,14 @@ function CONTROLLABLE:CommandStopRoute( StopRoute )
|
||||
end
|
||||
|
||||
|
||||
--- Give an uncontrolled air controllable the start command.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:StartUncontrolled()
|
||||
self:SetCommand({id='Start', params={}})
|
||||
return self
|
||||
end
|
||||
|
||||
-- TASKS FOR AIR CONTROLLABLES
|
||||
|
||||
|
||||
@ -724,28 +732,56 @@ end
|
||||
-- @param DCS#Azimuth Direction (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction.
|
||||
-- @param #number Altitude (optional) The altitude from where to attack.
|
||||
-- @param #number WeaponType (optional) The WeaponType.
|
||||
-- @param #boolean Divebomb (optional) Perform dive bombing. Default false.
|
||||
-- @return DCS#Task The DCS task structure.
|
||||
function CONTROLLABLE:TaskBombing( Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType )
|
||||
self:F2( { self.ControllableName, Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType } )
|
||||
function CONTROLLABLE:TaskBombing( Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, Divebomb )
|
||||
self:E( { self.ControllableName, Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, Divebomb } )
|
||||
|
||||
local _groupattack=false
|
||||
if GroupAttack then
|
||||
_groupattack=GroupAttack
|
||||
end
|
||||
|
||||
local _direction=0
|
||||
local _directionenabled=false
|
||||
if Direction then
|
||||
_direction=math.rad(Direction)
|
||||
_directionenabled=true
|
||||
end
|
||||
|
||||
local _altitude=5000
|
||||
local _altitudeenabled=false
|
||||
if Altitude then
|
||||
_altitude=Altitude
|
||||
_altitudeenabled=true
|
||||
end
|
||||
|
||||
local _attacktype=nil
|
||||
if Divebomb then
|
||||
_attacktype="Dive"
|
||||
end
|
||||
|
||||
|
||||
local DCSTask
|
||||
DCSTask = {
|
||||
id = 'Bombing',
|
||||
params = {
|
||||
point = Vec2,
|
||||
groupAttack = GroupAttack or false,
|
||||
x = Vec2.x,
|
||||
y = Vec2.y,
|
||||
groupAttack = _groupattack,
|
||||
expend = WeaponExpend or "Auto",
|
||||
attackQtyLimit = AttackQty and true or false,
|
||||
attackQty = AttackQty,
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = Direction,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude or 30,
|
||||
attackQtyLimit = false, --AttackQty and true or false,
|
||||
attackQty = AttackQty or 1,
|
||||
directionEnabled = _directionenabled,
|
||||
direction = _direction,
|
||||
altitudeEnabled = _altitudeenabled,
|
||||
altitude = _altitude,
|
||||
weaponType = WeaponType,
|
||||
--attackType=_attacktype,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
self:T3( { DCSTask } )
|
||||
self:E( { TaskBombing=DCSTask } )
|
||||
return DCSTask
|
||||
end
|
||||
|
||||
@ -1611,7 +1647,7 @@ end
|
||||
-- RouteToZone( GroundGroup, ZoneList[1] )
|
||||
--
|
||||
function CONTROLLABLE:TaskFunction( FunctionString, ... )
|
||||
self:F2( { FunctionString, arg } )
|
||||
self:E({TaskFunction=FunctionString, arguments=arg})
|
||||
|
||||
local DCSTask
|
||||
|
||||
@ -1622,17 +1658,12 @@ function CONTROLLABLE:TaskFunction( FunctionString, ... )
|
||||
local ArgumentKey = '_' .. tostring( arg ):match("table: (.*)")
|
||||
self:SetState( self, ArgumentKey, arg )
|
||||
DCSScript[#DCSScript+1] = "local Arguments = MissionControllable:GetState( MissionControllable, '" .. ArgumentKey .. "' ) "
|
||||
--DCSScript[#DCSScript+1] = "MissionControllable:ClearState( MissionControllable, '" .. ArgumentKey .. "' ) "
|
||||
DCSScript[#DCSScript+1] = FunctionString .. "( MissionControllable, unpack( Arguments ) )"
|
||||
else
|
||||
DCSScript[#DCSScript+1] = FunctionString .. "( MissionControllable )"
|
||||
end
|
||||
|
||||
DCSTask = self:TaskWrappedAction(
|
||||
self:CommandDoScript(
|
||||
table.concat( DCSScript )
|
||||
)
|
||||
)
|
||||
DCSTask = self:TaskWrappedAction(self:CommandDoScript(table.concat( DCSScript )))
|
||||
|
||||
self:T( DCSTask )
|
||||
|
||||
@ -2003,6 +2034,28 @@ do -- Route methods
|
||||
return self
|
||||
end
|
||||
|
||||
--- Make the TRAIN Controllable to drive towards a specific point using railroads.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to.
|
||||
-- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h.
|
||||
-- @param #number DelaySeconds (Optional) Wait for the specified seconds before executing the Route. Default is one second.
|
||||
-- @return #CONTROLLABLE The CONTROLLABLE.
|
||||
function CONTROLLABLE:RouteGroundOnRailRoads( ToCoordinate, Speed, DelaySeconds)
|
||||
|
||||
-- Defaults.
|
||||
Speed=Speed or 20
|
||||
DelaySeconds=DelaySeconds or 1
|
||||
|
||||
-- Get the route task.
|
||||
local route=self:TaskGroundOnRailRoads(ToCoordinate, Speed)
|
||||
|
||||
-- Route controllable to destination.
|
||||
self:Route( route, DelaySeconds )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Make a task for a GROUND Controllable to drive towards a specific point using (mostly) roads.
|
||||
-- @param #CONTROLLABLE self
|
||||
@ -2010,16 +2063,18 @@ do -- Route methods
|
||||
-- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h.
|
||||
-- @param #string OffRoadFormation (Optional) The formation at initial and final waypoint. Default is "Off Road".
|
||||
-- @param #boolean Shortcut (Optional) If true, controllable will take the direct route if the path on road is 10x longer or path on road is less than 5% of total path.
|
||||
-- @return Task
|
||||
function CONTROLLABLE:TaskGroundOnRoad( ToCoordinate, Speed, OffRoadFormation, Shortcut )
|
||||
-- @param Core.Point#COORDINATE FromCoordinate (Optional) Explicit initial coordinate. Default is the position of the controllable.
|
||||
-- @return DCS#Task Task.
|
||||
-- @return #boolean If true, path on road is possible. If false, task will route the group directly to its destination.
|
||||
function CONTROLLABLE:TaskGroundOnRoad( ToCoordinate, Speed, OffRoadFormation, Shortcut, FromCoordinate )
|
||||
self:F2({ToCoordinate=ToCoordinate, Speed=Speed, OffRoadFormation=OffRoadFormation})
|
||||
|
||||
-- Defaults.
|
||||
Speed=Speed or 20
|
||||
OffRoadFormation=OffRoadFormation or "Off Road"
|
||||
|
||||
-- Current coordinate.
|
||||
local FromCoordinate = self:GetCoordinate()
|
||||
-- Initial (current) coordinate.
|
||||
FromCoordinate = FromCoordinate or self:GetCoordinate()
|
||||
|
||||
-- Get path and path length on road including the end points (From and To).
|
||||
local PathOnRoad, LengthOnRoad=FromCoordinate:GetPathOnRoad(ToCoordinate, true)
|
||||
@ -2028,11 +2083,20 @@ do -- Route methods
|
||||
local _,LengthRoad=FromCoordinate:GetPathOnRoad(ToCoordinate, false)
|
||||
|
||||
-- Off road part of the rout: Total=OffRoad+OnRoad.
|
||||
local LengthOffRoad=LengthOnRoad-LengthRoad
|
||||
local LengthOffRoad
|
||||
local LongRoad
|
||||
|
||||
-- Calculate the direct distance between the initial and final points.
|
||||
local LengthDirect=FromCoordinate:Get2DDistance(ToCoordinate)
|
||||
|
||||
if PathOnRoad then
|
||||
|
||||
-- Off road part of the rout: Total=OffRoad+OnRoad.
|
||||
LengthOffRoad=LengthOnRoad-LengthRoad
|
||||
|
||||
-- Length on road is 10 times longer than direct route or path on road is very short (<5% of total path).
|
||||
LongRoad=LengthOnRoad and ((LengthOnRoad > LengthDirect*10) or (LengthRoad/LengthOnRoad*100<5))
|
||||
|
||||
-- Debug info.
|
||||
self:T(string.format("Length on road = %.3f km", LengthOnRoad/1000))
|
||||
self:T(string.format("Length directly = %.3f km", LengthDirect/1000))
|
||||
@ -2041,15 +2105,14 @@ do -- Route methods
|
||||
self:T(string.format("Length off road = %.3f km", LengthOffRoad/1000))
|
||||
self:T(string.format("Percent on road = %.1f", LengthRoad/LengthOnRoad*100))
|
||||
|
||||
end
|
||||
|
||||
-- Route, ground waypoints along road.
|
||||
local route={}
|
||||
|
||||
-- Length on road is 10 times longer than direct route or path on road is very short (<5% of total path).
|
||||
local LongRoad=LengthOnRoad and ((LengthOnRoad > LengthDirect*10) or (LengthRoad/LengthOnRoad*100<5))
|
||||
local canroad=false
|
||||
|
||||
-- Check if a valid path on road could be found.
|
||||
if PathOnRoad then
|
||||
|
||||
-- Check whether the road is very long compared to direct path.
|
||||
if LongRoad and Shortcut then
|
||||
|
||||
@ -2074,6 +2137,7 @@ do -- Route methods
|
||||
|
||||
end
|
||||
|
||||
canroad=true
|
||||
else
|
||||
|
||||
-- No path on road could be found (can happen!) ==> Route group directly from A to B.
|
||||
@ -2082,9 +2146,42 @@ do -- Route methods
|
||||
|
||||
end
|
||||
|
||||
return route
|
||||
return route, canroad
|
||||
end
|
||||
|
||||
--- Make a task for a TRAIN Controllable to drive towards a specific point using railroad.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to.
|
||||
-- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h.
|
||||
-- @return Task
|
||||
function CONTROLLABLE:TaskGroundOnRailRoads(ToCoordinate, Speed)
|
||||
self:F2({ToCoordinate=ToCoordinate, Speed=Speed})
|
||||
|
||||
-- Defaults.
|
||||
Speed=Speed or 20
|
||||
|
||||
-- Current coordinate.
|
||||
local FromCoordinate = self:GetCoordinate()
|
||||
|
||||
-- Get path and path length on railroad.
|
||||
local PathOnRail, LengthOnRail=FromCoordinate:GetPathOnRoad(ToCoordinate, false, true)
|
||||
|
||||
-- Debug info.
|
||||
self:T(string.format("Length on railroad = %.3f km", LengthOnRail/1000))
|
||||
|
||||
-- Route, ground waypoints along road.
|
||||
local route={}
|
||||
|
||||
-- Check if a valid path on railroad could be found.
|
||||
if PathOnRail then
|
||||
|
||||
table.insert(route, PathOnRail[1]:WaypointGround(Speed, "On Railroad"))
|
||||
table.insert(route, PathOnRail[2]:WaypointGround(Speed, "On Railroad"))
|
||||
|
||||
end
|
||||
|
||||
return route
|
||||
end
|
||||
|
||||
--- Make the AIR Controllable fly towards a specific point.
|
||||
-- @param #CONTROLLABLE self
|
||||
|
||||
@ -445,6 +445,38 @@ function GROUP:GetSpeedMax()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the maximum range of the group.
|
||||
-- If the group is heterogenious and consists of different units, the smallest range of all units is returned.
|
||||
-- @param #GROUP self
|
||||
-- @return #number Range in meters.
|
||||
function GROUP:GetRange()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
if DCSGroup then
|
||||
|
||||
local Units=self:GetUnits()
|
||||
|
||||
local Rangemin=nil
|
||||
|
||||
for _,unit in pairs(Units) do
|
||||
local unit=unit --Wrapper.Unit#UNIT
|
||||
local range=unit:GetRange()
|
||||
if range then
|
||||
if Rangemin==nil then
|
||||
Rangemin=range
|
||||
elseif range<Rangemin then
|
||||
Rangemin=range
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Rangemin
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns a list of @{Wrapper.Unit} objects of the @{Wrapper.Group}.
|
||||
-- @param #GROUP self
|
||||
@ -659,8 +691,9 @@ function GROUP:GetDCSUnits()
|
||||
end
|
||||
|
||||
|
||||
--- Activates a GROUP.
|
||||
--- Activates a late activated GROUP.
|
||||
-- @param #GROUP self
|
||||
-- @return #GROUP self
|
||||
function GROUP:Activate()
|
||||
self:F2( { self.GroupName } )
|
||||
trigger.action.activateGroup( self:GetDCSObject() )
|
||||
@ -1453,16 +1486,18 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) --
|
||||
SpawnPoint.airdromeId = AirbaseID
|
||||
end
|
||||
|
||||
SpawnPoint.alt = AirbaseCoord:GetLandHeight()
|
||||
|
||||
SpawnPoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
||||
SpawnPoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
||||
|
||||
-- Get the units of the group.
|
||||
local units=self:GetUnits()
|
||||
|
||||
for UnitID,_unit in pairs(units) do
|
||||
local x
|
||||
local y
|
||||
for UnitID=1,#units do
|
||||
|
||||
local unit=_unit --Wrapper.Unit#UNIT
|
||||
local unit=units[UnitID] --Wrapper.Unit#UNIT
|
||||
|
||||
-- Get closest parking spot of current unit. Note that we look for occupied spots since the unit is currently sitting on it!
|
||||
local Parkingspot, TermialID, Distance=unit:GetCoordinate():GetClosestParkingSpot(airbase)
|
||||
@ -1472,26 +1507,33 @@ function GROUP:RespawnAtCurrentAirbase(SpawnTemplate, Takeoff, Uncontrolled) --
|
||||
|
||||
-- Get unit coordinates for respawning position.
|
||||
local uc=unit:GetCoordinate()
|
||||
SpawnTemplate.units[UnitID].x = Parkingspot.x
|
||||
SpawnTemplate.units[UnitID].y = Parkingspot.z
|
||||
SpawnTemplate.units[UnitID].alt = Parkingspot.y
|
||||
--uc:MarkToAll(string.format("re-spawnplace %s terminal %d", unit:GetName(), TermialID))
|
||||
|
||||
SpawnTemplate.units[UnitID].x = uc.x --Parkingspot.x
|
||||
SpawnTemplate.units[UnitID].y = uc.z --Parkingspot.z
|
||||
SpawnTemplate.units[UnitID].alt = uc.y --Parkingspot.y
|
||||
|
||||
SpawnTemplate.units[UnitID].parking = TermialID
|
||||
SpawnTemplate.units[UnitID].parking_id = nil
|
||||
|
||||
--SpawnTemplate.units[UnitID].unitId=nil
|
||||
end
|
||||
|
||||
SpawnPoint.x = AirbaseCoord.x
|
||||
SpawnPoint.y = AirbaseCoord.z
|
||||
--SpawnTemplate.groupId=nil
|
||||
|
||||
SpawnTemplate.x = AirbaseCoord.x
|
||||
SpawnTemplate.y = AirbaseCoord.z
|
||||
SpawnPoint.x = SpawnTemplate.units[1].x --x --AirbaseCoord.x
|
||||
SpawnPoint.y = SpawnTemplate.units[1].y --y --AirbaseCoord.z
|
||||
SpawnPoint.alt = SpawnTemplate.units[1].alt --AirbaseCoord:GetLandHeight()
|
||||
|
||||
SpawnTemplate.x = SpawnTemplate.units[1].x --x --AirbaseCoord.x
|
||||
SpawnTemplate.y = SpawnTemplate.units[1].y --y --AirbaseCoord.z
|
||||
|
||||
-- Set uncontrolled state.
|
||||
SpawnTemplate.uncontrolled=Uncontrolled
|
||||
|
||||
-- Destroy and respawn.
|
||||
-- Destroy old group.
|
||||
self:Destroy(false)
|
||||
|
||||
_DATABASE:Spawn( SpawnTemplate )
|
||||
|
||||
-- Reset events.
|
||||
@ -1592,8 +1634,7 @@ end
|
||||
|
||||
--- Returns true if the first unit of the GROUP is in the air.
|
||||
-- @param Wrapper.Group#GROUP self
|
||||
-- @return #boolean true if in the first unit of the group is in the air.
|
||||
-- @return #nil The GROUP is not existing or not alive.
|
||||
-- @return #boolean true if in the first unit of the group is in the air or #nil if the GROUP is not existing or not alive.
|
||||
function GROUP:InAir()
|
||||
self:F2( self.GroupName )
|
||||
|
||||
@ -1611,6 +1652,23 @@ function GROUP:InAir()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the DCS descriptor table of the nth unit of the group.
|
||||
-- @param #GROUP self
|
||||
-- @param #number n (Optional) The number of the unit for which the dscriptor is returned.
|
||||
-- @return DCS#Object.Desc The descriptor of the first unit of the group or #nil if the group does not exist any more.
|
||||
function GROUP:GetDCSDesc(n)
|
||||
-- Default.
|
||||
n=n or 1
|
||||
|
||||
local unit=self:GetUnit(n)
|
||||
if unit and unit:IsAlive()~=nil then
|
||||
local desc=unit:GetDesc()
|
||||
return desc
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
do -- Route methods
|
||||
|
||||
--- (AIR) Return the Group to an @{Wrapper.Airbase#AIRBASE}.
|
||||
|
||||
@ -207,7 +207,18 @@ function IDENTIFIABLE:GetCountry()
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns country name of the Identifiable.
|
||||
-- @param #IDENTIFIABLE self
|
||||
-- @return #string Name of the country.
|
||||
function IDENTIFIABLE:GetCountryName()
|
||||
self:F2( self.IdentifiableName )
|
||||
local countryid=self:GetCountry()
|
||||
for name,id in pairs(country.id) do
|
||||
if countryid==id then
|
||||
return name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Returns Identifiable descriptor. Descriptor type depends on Identifiable category.
|
||||
-- @param #IDENTIFIABLE self
|
||||
|
||||
@ -54,8 +54,7 @@ end
|
||||
|
||||
--- Returns the unit's unique identifier.
|
||||
-- @param Wrapper.Object#OBJECT self
|
||||
-- @return DCS#Object.ID ObjectID
|
||||
-- @return #nil The DCS Object is not existing or alive.
|
||||
-- @return DCS#Object.ID ObjectID or #nil if the DCS Object is not existing or alive. Note that the ID is passed as a string and not a number.
|
||||
function OBJECT:GetID()
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
|
||||
@ -994,6 +994,7 @@ do -- Cargo
|
||||
-- return self.__.CargoBayVolumeLimit - CargoVolume
|
||||
-- end
|
||||
--
|
||||
|
||||
--- Get Cargo Bay Free Weight in kg.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @return #number CargoBayFreeWeight
|
||||
@ -1018,7 +1019,7 @@ do -- Cargo
|
||||
-- self.__.CargoBayVolumeLimit = VolumeLimit
|
||||
-- end
|
||||
|
||||
--- Get Cargo Bay Weight Limit in kg.
|
||||
--- Set Cargo Bay Weight Limit in kg.
|
||||
-- @param #POSITIONABLE self
|
||||
-- @param #number WeightLimit
|
||||
function POSITIONABLE:SetCargoBayWeightLimit( WeightLimit )
|
||||
|
||||
@ -194,9 +194,10 @@ end
|
||||
--- Respawn the @{Wrapper.Unit} at the same location with the same properties.
|
||||
-- This is useful to respawn a cargo after it has been destroyed.
|
||||
-- @param #STATIC self
|
||||
function STATIC:ReSpawn()
|
||||
-- @param DCS#country.id countryid The country ID used for spawning the new static.
|
||||
function STATIC:ReSpawn(countryid)
|
||||
|
||||
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName )
|
||||
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, countryid )
|
||||
|
||||
SpawnStatic:ReSpawn()
|
||||
end
|
||||
|
||||
@ -119,11 +119,13 @@ end
|
||||
-- @param DCS#Unit DCSUnit An existing DCS Unit object reference.
|
||||
-- @return #UNIT self
|
||||
function UNIT:Find( DCSUnit )
|
||||
|
||||
if DCSUnit then
|
||||
local UnitName = DCSUnit:getName()
|
||||
local UnitFound = _DATABASE:FindUnit( UnitName )
|
||||
return UnitFound
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Find a UNIT in the _DATABASE using the name of an existing DCS Unit.
|
||||
-- @param #UNIT self
|
||||
@ -388,6 +390,28 @@ function UNIT:GetSpeedMax()
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the unit's max range in meters derived from the DCS descriptors.
|
||||
-- For ground units it will return a range of 10,000 km as they have no real range.
|
||||
-- @param #UNIT self
|
||||
-- @return #number Range in meters.
|
||||
function UNIT:GetRange()
|
||||
self:F2( self.UnitName )
|
||||
|
||||
local Desc = self:GetDesc()
|
||||
|
||||
if Desc then
|
||||
local Range = Desc.range --This is in nautical miles for some reason. But should check again!
|
||||
if Range then
|
||||
Range=UTILS.NMToMeters(Range)
|
||||
else
|
||||
Range=10000000 --10.000 km if no range
|
||||
end
|
||||
return Range
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Returns the unit's group if it exist and nil otherwise.
|
||||
-- @param Wrapper.Unit#UNIT self
|
||||
-- @return Wrapper.Group#GROUP The Group of the Unit.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user