This commit is contained in:
Frank
2020-04-27 01:48:16 +02:00
parent 3653199bfc
commit 25e58393ea
4 changed files with 251 additions and 24 deletions
+17
View File
@@ -446,6 +446,23 @@ do -- COORDINATE
return gotunits, gotstatics, gotscenery, Units, Statics, Scenery
end
--- Scan/find UNITS within a certain radius around the coordinate using the world.searchObjects() DCS API function.
-- @param #COORDINATE self
-- @param #number radius (Optional) Scan radius in meters. Default 100 m.
-- @return Core.Set#SET_UNIT Set of units.
function COORDINATE:ScanUnits(radius)
local _,_,_,units=self:ScanObjects(radius, true, false, false)
local set=SET_UNIT:New()
for _,unit in pairs(units) do
set:AddUnit(unit)
end
return set
end
--- Calculate the distance from a reference @{#COORDINATE}.
-- @param #COORDINATE self
+3 -3
View File
@@ -852,7 +852,7 @@ function AUFTRAG:NewBOMBING(Target, Altitude)
mission.missionAltitude=mission.engageAltitude*0.8
mission.missionFraction=0.5
mission.optionROE=ENUMS.ROE.OpenFire
mission.optionROT=ENUMS.ROT.PassiveDefense
mission.optionROT=ENUMS.ROT.NoReaction -- No reaction is better.
-- Evaluate result after 5 min. We might need time until the bombs have dropped and targets have been detroyed.
mission.dTevaluate=5*60
@@ -922,7 +922,7 @@ function AUFTRAG:NewBOMBCARPET(Target, Altitude, CarpetLength)
mission.missionAltitude=mission.engageAltitude*0.8
mission.missionFraction=0.2
mission.optionROE=ENUMS.ROE.OpenFire
mission.optionROT=ENUMS.ROT.PassiveDefense
mission.optionROT=ENUMS.ROT.NoReaction
-- Evaluate result after 5 min.
mission.dTevaluate=5*60
@@ -2655,7 +2655,7 @@ function AUFTRAG:UpdateMarker()
else
if self.marker.text~=text then
if self.marker:GetText()~=text then
self.marker:UpdateText(text)
end
+170 -16
View File
@@ -874,17 +874,41 @@ end
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetAirboss(airboss)
self.airboss=airboss
return self
end
--- Set low fuel threshold. Triggers event "FuelLow" and calls event function "OnAfterFuelLow".
-- @param #FLIGHTGROUP self
-- @param #number threshold Fuel threshold in percent. Default 25 %.
-- @param #boolean rtb If true, RTB on fuel low event.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetFuelLowThreshold(threshold, rtb)
self.fuellow=false
function FLIGHTGROUP:SetFuelLowThreshold(threshold)
self.fuellowthresh=threshold or 25
self.fuellowrtb=rtb
return self
end
--- Set if low fuel threshold is reached, flight goes RTB.
-- @param #FLIGHTGROUP self
-- @param #boolean switch If true or nil, flight goes RTB. If false, turn this off.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetFuelLowRTB(switch)
if switch==false then
self.fuellowrtb=false
else
self.fuellowrtb=true
end
return self
end
--- Set if low fuel threshold is reached, flight tries to refuel at the neares tanker.
-- @param #FLIGHTGROUP self
-- @param #boolean switch If true or nil, flight goes for refuelling. If false, turn this off.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetFuelLowRefuel(switch)
if switch==false then
self.fuellowrefuel=false
else
self.fuellowrefuel=true
end
return self
end
@@ -894,7 +918,6 @@ end
-- @param #boolean rtb If true, RTB on fuel critical event.
-- @return #FLIGHTGROUP self
function FLIGHTGROUP:SetFuelCriticalThreshold(threshold, rtb)
self.fuelcritical=false
self.fuelcriticalthresh=threshold or 10
self.fuelcriticalrtb=rtb
return self
@@ -1563,31 +1586,54 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
local time=timer.getAbsTime()
-- Current position.
local position=self:GetCoordinate()
-- Travelled distance since last check.
local ds=self.position:Get3DDistance(position)
-- Time interval.
local dt=time-self.traveltime
-- Speed.
local v=ds/dt
-- Add up travelled distance.
self.traveldist=self.traveldist+ds
self.traveltime=time
self.position=position
self:I(self.lid..string.format("FF Travelled ds=%.1f km dt=%.1f s ==> v=%.1f knots", self.traveldist/1000, dt, UTILS.MpsToKnots(v)))
local fuelmass=math.huge
for _,_element in pairs(self.elements) do
local element=_element --#FLIGHTGROUP.Element
local fuel=element.unit:GetFuel() or 0
local df=element.fuelrel-fuel
local fmass=element.fuelmass*fuel
local dm=element.fuelmass-fmass
local dmds=dm/ds
local dmdt=dm/dt
if fmass<fuelmass then
fuelmass=fmass
end
self:I(self.lid..string.format("Fuel consumption %s: df=%.1f, dm=%.1f kg ==> dm/ds=%.1f kg/s dm/dt=%.1f 1/s", element.name, df, dm, dmds, dmdt))
element.fuelrel=fuel
element.fuelmass=fmass
end
-- Log outut.
self:I(self.lid..string.format("FF Distance travelled = %.1f km v=%.1f knots fuel=%d kg", self.traveldist/1000, UTILS.MpsToKnots(v), fuelmass))
--self:I(self.lid..string.format("FF Distance travelled = %.1f km v=%.1f knots fuel=%d kg", self.traveldist/1000, UTILS.MpsToKnots(v), fuelmass))
-- Update parameters.
self.traveltime=time
self.position=position
end
---
@@ -1654,6 +1700,15 @@ function FLIGHTGROUP:onafterFlightStatus(From, Event, To)
if self:IsAlive() and self.group:IsAirborne(true) then
local fuelmin=self:GetFuelMin()
if fuelmin>=self.fuellowthresh then
self.fuellow=false
end
if fuelmin>=self.fuelcriticalthresh then
self.fuelcritical=false
end
-- Low fuel?
if fuelmin<self.fuellowthresh and not self.fuellow then
@@ -2888,7 +2943,7 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp
self.flightcontrol:_AddFlightToInboundQueue(self)
end
-- Altitude above ground for a glide slope of 3.
-- Altitude above ground for a glide slope of 3 degrees.
local x1=self.ishelo and UTILS.NMToMeters(5.0) or UTILS.NMToMeters(10)
local x2=self.ishelo and UTILS.NMToMeters(2.5) or UTILS.NMToMeters(5)
local alpha=math.rad(3)
@@ -3103,6 +3158,8 @@ function FLIGHTGROUP:onafterRefueled(From, Event, To)
self:__UpdateRoute(-1)
end
-- TODO: reset fuellow and fuelcrit to false if enough fuel was taken.
end
@@ -3274,14 +3331,30 @@ function FLIGHTGROUP:onafterFuelLow(From, Event, To)
self:Refuel(tanker.flightgroup:GetCoordinate())
else
if airbase and self.fuellowrtb then
self:RTB(airbase)
--TODO: RTZ
end
end
end
else
if self.fuellowrefuel and self.refueltype then
local tanker=self:FindNearestTanker(50)
if tanker then
self:I(self.lid..string.format("Send to refuel at tanker %s", tanker:GetName()))
self:Refuel()
return
end
end
if airbase and self.fuellowrtb then
self:RTB(airbase)
--TODO: RTZ
@@ -3306,7 +3379,7 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To)
-- Set switch to true.
self.fuelcritical=true
-- Route helo back home. It is respawned! But this is the only way to ensure that it actually lands at the airbase.
-- Airbase.
local airbase=self.destbase or self.homebase
if airbase and self.fuelcriticalrtb and not self:IsGoing4Fuel() then
@@ -4195,7 +4268,9 @@ function FLIGHTGROUP:AddElementByName(unitname)
element.modex=element.unit:GetTemplate().onboard_num
element.skill=element.unit:GetTemplate().skill
element.pylons=element.unit:GetTemplatePylons()
element.fuelmass=element.unit:GetTemplatePayload().fuel
element.fuelmass0=element.unit:GetTemplatePayload().fuel
element.fuelmass=element.fuelmass0
element.fuelrel=element.unit:GetFuel()
element.category=element.unit:GetCategory()
element.categoryname=element.unit:GetCategoryName()
element.callsign=element.unit:GetCallsign()
@@ -4208,8 +4283,8 @@ function FLIGHTGROUP:AddElementByName(unitname)
element.ai=true
end
local text=string.format("Adding element %s: status=%s, skill=%s, modex=%s, fuelmass=%.1f, category=%d, categoryname=%s, callsign=%s, ai=%s",
element.name, element.status, element.skill, element.modex, element.fuelmass, element.category, element.categoryname, element.callsign, tostring(element.ai))
local text=string.format("Adding element %s: status=%s, skill=%s, modex=%s, fuelmass=%.1f (%d %%), category=%d, categoryname=%s, callsign=%s, ai=%s",
element.name, element.status, element.skill, element.modex, element.fuelmass, element.fuelrel, element.category, element.categoryname, element.callsign, tostring(element.ai))
self:I(self.lid..text)
-- Add element to table.
@@ -4268,6 +4343,85 @@ function FLIGHTGROUP:GetHomebaseFromWaypoints()
return nil
end
--- Find the nearest friendly airbase (same or neutral coalition).
-- @param #FLIGHTGROUP self
-- @param #number Radius Search radius in NM. Default 50 NM.
-- @return Wrapper.Airbase#AIRBASE Closest tanker group #nil.
function FLIGHTGROUP:FindNearestAirbase(Radius)
local coord=self:GetCoordinate()
local dmin=math.huge
local airbase=nil --Wrapper.Airbase#AIRBASE
for _,_airbase in pairs(AIRBASE.GetAllAirbases()) do
local ab=_airbase --Wrapper.Airbase#AIRBASE
local coalitionAB=ab:GetCoalition()
if coalitionAB==self:GetCoalition() or coalitionAB==coalition.side.NEUTRAL then
if airbase then
local d=ab:GetCoordinate():Get2DDistance(coord)
if d<dmin then
d=dmin
airbase=ab
end
end
end
end
return airbase
end
--- Find the nearest tanker.
-- @param #FLIGHTGROUP self
-- @param #number Radius Search radius in NM. Default 50 NM.
-- @return Wrapper.Group#GROUP Closest tanker group #nil.
function FLIGHTGROUP:FindNearestTanker(Radius)
Radius=UTILS.NMToMeters(Radius or 50)
if self.refueltype then
local coord=self:GetCoordinate()
local units=coord:ScanUnits(Radius)
local dmin=math.huge
local tanker=nil --Wrapper.Unit#UNIT
for _,_unit in pairs(units.Set) do
local unit=_unit --Wrapper.Unit#UNIT
local istanker, refuelsystem=unit:IsTanker()
if istanker and self.refueltype==refuelsystem then
-- Distance.
local d=unit:GetCoordinate():Get2DDistance(coord)
if d<dmin then
d=dmin
tanker=unit
end
end
end
if tanker then
return tanker:GetGroup()
end
end
return nil
end
--- Check if a unit is and element of the flightgroup.
-- @param #FLIGHTGROUP self
-- @return Wrapper.Airbase#AIRBASE Final destination airbase or #nil.
+61 -5
View File
@@ -29,9 +29,7 @@
-- @field #number coalition Coalition to which the marker is displayed.
-- @extends Core.Fsm#FSM
--- **Ground Control**: Airliner X, Good news, you are clear to taxi to the active.
-- **Pilot**: Roger, What's the bad news?
-- **Ground Control**: No bad news at the moment, but you probably want to get gone before I find any.
--- Just because...
--
-- ===
--
@@ -39,31 +37,89 @@
--
-- # The MARKER Class Idea
--
-- # Creat a Marker
-- The MARKER class simplifies creating, updating and removing of markers on the F10 map.
--
-- # Create a Marker
--
-- -- Create a MARKER object at Batumi with a trivial text.
-- local Coordinate=AIRBASE:FindByName("Batumi"):GetCoordinate()
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield")
--
-- Now this does **not** show the marker yet. We still need to specifiy to whom it is shown. There are several options, i.e.
-- show the marker to everyone, to a speficic coaliton only, or only to a specific group.
--
-- ## For Everyone
--
-- If the marker should be visible to everyone, you can use the :ToAll() function.
--
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield"):ToAll()
--
-- ## For a Coaliton
--
-- If the maker should be visible to a specific coalition, you can use the :ToCoalition() function.
--
-- mymarker=MARKER:New(Coordinate, "I am Batumi Airfield"):ToCoaliton(coaliton.side.BLUE)
--
-- ### To Blue Coaliton
--
-- ### To Red Coalition
--
-- This would show the marker only to the Blue coaliton.
--
-- ## For a Group
--
--
-- # Update a Marker
-- # Removing a Marker
--
--
-- # Updating a Marker
--
-- The marker text and/coordinate can be updated easily as shown below.
--
-- However, note that updateing involves to remove and recreate the marker if either text or its coordinate is changed.
-- This is a DCS scripting engine limitation.
--
-- ## Update Text
--
-- If you created a marker "mymarker" as shown above, you can update the dispayed test by
--
-- mymarker:UpdateText("I am the new text at Batumi")
--
-- The update can also be delayed by, e.g. 90 seconds, using
--
-- mymarker:UpdateText("I am the new text at Batumi", 90)
--
-- ## Update Coordinate
--
-- If you created a marker "mymarker" as shown above, you can update its coordinate on the F10 map by
--
-- mymarker:UpdateCoordinate(NewCoordinate)
--
-- The update can also be delayed by, e.g. 60 seconds, using
--
-- mymarker:UpdateCoordinate(NewCoordinate, 60)
--
-- # Retrieve Data
--
-- The important data as the displayed text and the coordinate of the marker can be retrieved quite easily.
--
-- ## Text
--
-- local text=mymarker:GetText()
-- env.info("Marker Text = " .. text)
--
-- ## Coordinate
--
-- local Coordinate=mymarker:GetCoordinate()
-- env.info("Marker Coordinate LL DSM = " .. Coordinate:ToStringLLDMS())
--
--
-- # FSM Events
--
-- Moose creates addditonal events, so called FSM event, when markers are added, changed, removed, and text or the coordianteis updated.
--
-- These events can be captured and used for processing via OnAfter functions as shown below.
--
-- ## Added
--
-- ## Changed