- Quite a few fixes while going through the example missions.
This commit is contained in:
Frank 2020-09-16 23:35:13 +02:00
parent 40ffef035b
commit 29d694722b
4 changed files with 187 additions and 103 deletions

View File

@ -1169,7 +1169,10 @@ function AUFTRAG:NewARTY(Target, Nshots, Radius)
mission.optionROE=ENUMS.ROE.OpenFire -- Ground/naval need open fire! mission.optionROE=ENUMS.ROE.OpenFire -- Ground/naval need open fire!
mission.optionAlarm=0 mission.optionAlarm=0
mission.missionFraction=0.1 mission.missionFraction=0.0
-- Evaluate after 8 min.
mission.dTevaluate=8*60
mission.DCStask=mission:GetDCSMissionTask() mission.DCStask=mission:GetDCSMissionTask()
@ -1185,30 +1188,11 @@ function AUFTRAG:NewTargetAir(Target)
local mission=nil --#AUFTRAG local mission=nil --#AUFTRAG
self.engageTarget=Target self.engageTarget=Target
--[[
if Target.category==TARGET.Category.GROUND then
elseif Target.category==TARGET.Category.AIRCRAFT then
mission=AUFTRAG:NewINTERCEPT(Target)
elseif Target.category==TARGET.Category.AIRBASE then
mission=AUFTRAG:NewBOMBRUNWAY(Airdrome,Altitude)
elseif Target.category==TARGET.Category.COORDINATE then
end
]]
local target=self.engageTarget:GetObject() local target=self.engageTarget:GetObject()
local mission=self:NewAUTO(target) local mission=self:NewAUTO(target)
if mission then if mission then
mission:SetPriority(10, true) mission:SetPriority(10, true)
end end
@ -2133,6 +2117,9 @@ function AUFTRAG:Evaluate()
local Ntargets=self:CountMissionTargets() local Ntargets=self:CountMissionTargets()
local Ntargets0=self:GetTargetInitialNumber() local Ntargets0=self:GetTargetInitialNumber()
local Life=self:GetTargetLife()
local Life0=self:GetTargetInitialLife()
if Ntargets0>0 then if Ntargets0>0 then
@ -2196,6 +2183,7 @@ function AUFTRAG:Evaluate()
text=text..string.format("Own losses = %.1f %%\n", owndamage) text=text..string.format("Own losses = %.1f %%\n", owndamage)
text=text..string.format("--------------------------\n") text=text..string.format("--------------------------\n")
text=text..string.format("Targets left = %d/%d\n", Ntargets, Ntargets0) text=text..string.format("Targets left = %d/%d\n", Ntargets, Ntargets0)
text=text..string.format("Targets life = %.1f/%.1f\n", Life, Life0)
text=text..string.format("Enemy losses = %.1f %%\n", targetdamage) text=text..string.format("Enemy losses = %.1f %%\n", targetdamage)
text=text..string.format("--------------------------\n") text=text..string.format("--------------------------\n")
--text=text..string.format("Loss ratio = %.1f %%\n", targetdamage) --text=text..string.format("Loss ratio = %.1f %%\n", targetdamage)

View File

@ -708,6 +708,41 @@ end
-- @param #FLIHGTGROUP self -- @param #FLIHGTGROUP self
function FLIGHTGROUP:onbeforeStatus(From, Event, To) function FLIGHTGROUP:onbeforeStatus(From, Event, To)
-- First we check if elements are still alive. Could be that they were despawned without notice, e.g. when landing on a too small airbase.
for i,_element in pairs(self.elements) do
local element=_element --#FLIGHTGROUP.Element
-- Check that element is not already dead or not yet alive.
if element.status~=OPSGROUP.ElementStatus.DEAD and element.status~=OPSGROUP.ElementStatus.INUTERO then
-- Unit shortcut.
local unit=element.unit
local isdead=false
if unit and unit:IsAlive() then
-- Get life points.
local life=unit:GetLife() or 0
-- Units with life <=1 are dead.
if life<=1 then
isdead=true
end
else
-- Not alive any more.
isdead=true
end
-- This one is dead.
if isdead then
self:E(self.lid..string.format("Element %s is dead! Probably despawned without notice or landed at a too small airbase", tostring(element.name)))
self:ElementDead(element)
end
end
end
if self:IsDead() then if self:IsDead() then
self:T(self.lid..string.format("Onbefore Status DEAD ==> false")) self:T(self.lid..string.format("Onbefore Status DEAD ==> false"))
return false return false
@ -1327,18 +1362,27 @@ end
-- @param Wrapper.Airbase#AIRBASE airbase The airbase if applicable or nil. -- @param Wrapper.Airbase#AIRBASE airbase The airbase if applicable or nil.
function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase) function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase)
self:T2(self.lid..string.format("Element landed %s at %s airbase", Element.name, airbase and airbase:GetName() or "unknown")) self:T2(self.lid..string.format("Element landed %s at %s airbase", Element.name, airbase and airbase:GetName() or "unknown"))
if self.despawnAfterLanding then
-- Despawn the element.
self:DespawnElement(Element)
else
-- Helos with skids land directly on parking spots. -- Helos with skids land directly on parking spots.
if self.ishelo then if self.ishelo then
local Spot=self:GetParkingSpot(Element, 10, airbase) local Spot=self:GetParkingSpot(Element, 10, airbase)
self:_SetElementParkingAt(Element, Spot) self:_SetElementParkingAt(Element, Spot)
end
-- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.LANDED, airbase)
end end
-- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.LANDED, airbase)
end end
--- On after "ElementArrived" event. --- On after "ElementArrived" event.
@ -1410,6 +1454,9 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
-- Set ROT. -- Set ROT.
self:SwitchROT(self.option.ROT) self:SwitchROT(self.option.ROT)
-- Set Formation
self:SwitchFormation(self.option.Formation)
-- Turn TACAN beacon on. -- Turn TACAN beacon on.
if self.tacan.On then if self.tacan.On then
@ -1572,10 +1619,6 @@ function FLIGHTGROUP:onafterLanded(From, Event, To, airbase)
-- Add flight to taxiinb queue. -- Add flight to taxiinb queue.
self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.TAXIINB) self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.TAXIINB)
end end
if self.despawnAfterLanding then
self:Despawn()
end
end end
@ -1603,9 +1646,9 @@ function FLIGHTGROUP:onafterArrived(From, Event, To)
self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.ARRIVED) self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.ARRIVED)
end end
-- Stop and despawn in 5 min. -- Despawn in 5 min.
if not self.airwing then if not self.airwing then
self:__Stop(5*60) self:Despawn(5*60)
end end
end end
@ -1731,9 +1774,11 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
-- Set current waypoint or we get problem that the _PassingWaypoint function is triggered too early, i.e. right now and not when passing the next WP. -- Set current waypoint or we get problem that the _PassingWaypoint function is triggered too early, i.e. right now and not when passing the next WP.
local current=self.group:GetCoordinate():WaypointAir(COORDINATE.WaypointAltType.BARO, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, speed, true, nil, {}, "Current") local current=self.group:GetCoordinate():WaypointAir(COORDINATE.WaypointAltType.BARO, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, speed, true, nil, {}, "Current")
table.insert(wp, current) table.insert(wp, current)
local Nwp=self.waypoints and #self.waypoints or 0
-- Add remaining waypoints to route. -- Add remaining waypoints to route.
for i=n, #self.waypoints do for i=n, Nwp do
table.insert(wp, self.waypoints[i]) table.insert(wp, self.waypoints[i])
end end
@ -2437,9 +2482,6 @@ function FLIGHTGROUP:onafterStop(From, Event, To)
end end
end end
-- Destroy group. No event is generated.
-- DISABLED for now. Should use :Despawn() or :Destroy() which then calls stop.
--self.group:Destroy(false)
end end
-- Handle events: -- Handle events:

View File

@ -575,7 +575,7 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
n=n or self:GetWaypointIndexNext() n=n or self:GetWaypointIndexNext()
-- Debug info. -- Debug info.
self:T(self.lid..string.format("FF Update route n=%d", n)) self:T(self.lid..string.format("Update route n=%d", n))
-- Update waypoint tasks, i.e. inject WP tasks into waypoint table. -- Update waypoint tasks, i.e. inject WP tasks into waypoint table.
self:_UpdateWaypointTasks(n) self:_UpdateWaypointTasks(n)
@ -784,6 +784,7 @@ end
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @param #string To To state.
function NAVYGROUP:onafterFullStop(From, Event, To) function NAVYGROUP:onafterFullStop(From, Event, To)
self:T(self.lid.."Full stop ==> holding")
-- Get current position. -- Get current position.
local pos=self:GetCoordinate() local pos=self:GetCoordinate()

View File

@ -669,16 +669,37 @@ function OPSGROUP:Destroy(Delay)
return self return self
end end
--- Despawn a unit. --- Despawn an element/unit of the group.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #OPSGROUP.Element Element The element that will be despawned.
-- @param #number Delay Delay in seconds before the element will be despawned. Default immediately.
-- @param #boolean NoEventRemoveUnit If true, no event "Remove Unit" is generated.
-- @return #OPSGROUP self -- @return #OPSGROUP self
function OPSGROUP:DespawnUnit(UnitName) function OPSGROUP:DespawnElement(Element, Delay, NoEventRemoveUnit)
local DCSGroup=self:GetDCSGroup() if Delay and Delay>0 then
self:ScheduleOnce(Delay, OPSGROUP.DespawnElement, self, Element, 0, NoEventRemoveUnit)
else
if Element then
-- Get DCS unit object.
local DCSunit=Unit.getByName(Element.name)
if DCSGroup then if DCSunit then
DCSGroup:destroy()
self:CreateEventRemoveUnit(timer.getTime(), DCSObject) -- Destroy object.
DCSunit:destroy()
-- Create a remove unit event.
if not NoEventRemoveUnit then
self:CreateEventRemoveUnit(timer.getTime(), DCSunit)
end
end
end
end end
return self return self
@ -1082,7 +1103,7 @@ end
function OPSGROUP:GetWaypointIndex(uid) function OPSGROUP:GetWaypointIndex(uid)
if uid then if uid then
for i,_waypoint in pairs(self.waypoints) do for i,_waypoint in pairs(self.waypoints or {}) do
local waypoint=_waypoint --#OPSGROUP.Waypoint local waypoint=_waypoint --#OPSGROUP.Waypoint
if waypoint.uid==uid then if waypoint.uid==uid then
return i return i
@ -2241,12 +2262,7 @@ function OPSGROUP:onafterMissionExecute(From, Event, To, Mission)
-- Set mission status to EXECUTING. -- Set mission status to EXECUTING.
Mission:Executing() Mission:Executing()
-- Formation
if Mission.optionFormation then
self:SwitchFormation(Mission.optionFormation)
end
end end
--- On after "PauseMission" event. --- On after "PauseMission" event.
@ -2371,7 +2387,7 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
-- Remove mission waypoint. -- Remove mission waypoint.
local wpidx=Mission:GetGroupWaypointIndex(self) local wpidx=Mission:GetGroupWaypointIndex(self)
if wpidx then if wpidx then
self:RemoveWaypoint(wpidx) self:RemoveWaypointByID(wpidx)
end end
-- Decrease patrol data. -- Decrease patrol data.
@ -2380,6 +2396,27 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
AIRWING.UpdatePatrolPointMarker(Mission.patroldata) AIRWING.UpdatePatrolPointMarker(Mission.patroldata)
end end
-- ROE to default.
if Mission.optionROE then
self:SwitchROE()
end
-- ROT to default
if Mission.optionROT then
self:SwitchROT()
end
-- Alarm state to default.
if Mission.optionAlarm then
self:SwitchAlarmstate()
end
-- Formation to default.
if Mission.optionFormation then
self:SwitchFormation()
end
-- Radio freq and modu to last used.
if Mission.radio and self.radioLast then
self:SwitchRadio(self.radioLast.Freq, self.radioLast.Modu)
end
-- TACAN -- TACAN
if Mission.tacan then if Mission.tacan then
@ -2399,23 +2436,8 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
asset.tacan=nil asset.tacan=nil
end end
end end
-- TODO: reset mission specific parameters like radio, ROE etc.
if Mission.radio and self.radioLast then
self:SwitchRadio(self.radioLast.Freq, self.radioLast.Modu)
end
if Mission.optionROE then -- TODO: reset ICLS settings.
self:SwitchROE()
end
if Mission.optionROT then
self:SwitchROT()
end
if Mission.optionAlarm then
self:SwitchAlarmstate()
end
-- Check if group is done. -- Check if group is done.
self:_CheckGroupDone(1) self:_CheckGroupDone(1)
@ -2482,17 +2504,21 @@ function OPSGROUP:RouteToMission(mission, delay)
-- Check if we are within range. -- Check if we are within range.
if dist>weapondata.RangeMax then if dist>weapondata.RangeMax then
local d=dist-weapondata.RangeMax
d=(1.1)*d local d=(dist-weapondata.RangeMax)*1.1
-- New waypoint coord. -- New waypoint coord.
waypointcoord=self:GetCoordinate():Translate(d, heading) waypointcoord=self:GetCoordinate():Translate(d, heading)
self:T(self.lid..string.format("Out of max range = %.1f km for weapon %d", weapondata.RangeMax/1000, mission.engageWeaponType))
elseif dist<weapondata.RangeMin then elseif dist<weapondata.RangeMin then
local d=dist-weapondata.RangeMin
d=(1.1)*d local d=(dist-weapondata.RangeMin)*1.1
-- New waypoint coord. -- New waypoint coord.
waypointcoord=self:GetCoordinate():Translate(d, heading) waypointcoord=self:GetCoordinate():Translate(d, heading)
self:T(self.lid..string.format("Out of min range = %.1f km for weapon %d", weapondata.RangeMax/1000, mission.engageWeaponType))
end end
end end
@ -2523,21 +2549,25 @@ function OPSGROUP:RouteToMission(mission, delay)
if mission.optionROT then if mission.optionROT then
self:SwitchROT(mission.optionROT) self:SwitchROT(mission.optionROT)
end end
-- Radio -- Alarm state.
if mission.radio then if mission.optionAlarm then
self:SwitchRadio(mission.radio.Freq, mission.radio.Modu) self:SwitchAlarmstate(mission.optionAlarm)
end end
-- TACAN
if mission.tacan then
self:SwitchTACAN(mission.tacan.Channel, mission.tacan.Morse, mission.tacan.BeaconName, mission.tacan.Band)
end
-- ICLS
if mission.icls then
self:SwitchICLS(mission.icls.Channel, mission.icls.Morse, mission.icls.UnitName)
end
-- Formation -- Formation
if mission.optionFormation then if mission.optionFormation then
self:SwitchFormation(mission.optionFormation) self:SwitchFormation(mission.optionFormation)
end
-- Radio frequency and modulation.
if mission.radio then
self:SwitchRadio(mission.radio.Freq, mission.radio.Modu)
end
-- TACAN settings.
if mission.tacan then
self:SwitchTACAN(mission.tacan.Channel, mission.tacan.Morse, mission.tacan.BeaconName, mission.tacan.Band)
end
-- ICLS settings.
if mission.icls then
self:SwitchICLS(mission.icls.Channel, mission.icls.Morse, mission.icls.UnitName)
end end
end end
@ -2735,8 +2765,22 @@ end
-- @param #string To To state. -- @param #string To To state.
-- @param Wrapper.Unit#UNIT Unit The detected unit. -- @param Wrapper.Unit#UNIT Unit The detected unit.
function OPSGROUP:onafterDetectedUnit(From, Event, To, Unit) function OPSGROUP:onafterDetectedUnit(From, Event, To, Unit)
self:T2(self.lid..string.format("Detected unit %s", Unit:GetName()))
self.detectedunits:AddUnit(Unit) -- Get unit name.
local unitname=Unit and Unit:GetName() or "unknown"
-- Debug.
self:T2(self.lid..string.format("Detected unit %s", unitname))
if self.detectedunits:FindUnit(unitname) then
-- Unit is already in the detected unit set ==> Trigger "DetectedUnitKnown" event.
self:DetectedUnitKnown(Unit)
else
-- Unit is was not detected ==> Trigger "DetectedUnitNew" event.
self:DetectedUnitNew(Unit)
end
end end
--- On after "DetectedUnitNew" event. --- On after "DetectedUnitNew" event.
@ -2747,6 +2791,9 @@ end
-- @param Wrapper.Unit#UNIT Unit The detected unit. -- @param Wrapper.Unit#UNIT Unit The detected unit.
function OPSGROUP:onafterDetectedUnitNew(From, Event, To, Unit) function OPSGROUP:onafterDetectedUnitNew(From, Event, To, Unit)
self:T(self.lid..string.format("Detected New unit %s", Unit:GetName())) self:T(self.lid..string.format("Detected New unit %s", Unit:GetName()))
-- Add unit to detected unit set.
self.detectedunits:AddUnit(Unit)
end end
--- On after "EnterZone" event. Sets self.inzones[zonename]=true. --- On after "EnterZone" event. Sets self.inzones[zonename]=true.
@ -2851,9 +2898,11 @@ function OPSGROUP:onafterStop(From, Event, To)
-- Stop FSM scheduler. -- Stop FSM scheduler.
self.CallScheduler:Clear() self.CallScheduler:Clear()
if self:IsAlive() then if self:IsAlive() and not (self:IsDead() or self:IsStopped()) then
local life, life0=self:GetLifePoints() local life, life0=self:GetLifePoints()
self:E(self.lid..string.format("WARNING: Group is still alive! Life points=%d/%d. Use OPSGROUP:Destroy() or OPSGROUP:Despawn() for a clean stop", life, life0)) local state=self:GetState()
local text=string.format("WARNING: Group is still alive! Current state=%s. Life points=%d/%d. Use OPSGROUP:Destroy() or OPSGROUP:Despawn() for a clean stop", state, life, life0)
self:E(self.lid..text)
end end
-- Debug output. -- Debug output.
@ -2931,6 +2980,8 @@ function OPSGROUP:_CheckDetectedUnits()
local DetectedObject=Detection.object -- DCS#Object local DetectedObject=Detection.object -- DCS#Object
if DetectedObject and DetectedObject:isExist() and DetectedObject.id_<50000000 then if DetectedObject and DetectedObject:isExist() and DetectedObject.id_<50000000 then
-- Unit.
local unit=UNIT:Find(DetectedObject) local unit=UNIT:Find(DetectedObject)
if unit and unit:IsAlive() then if unit and unit:IsAlive() then
@ -2941,17 +2992,9 @@ function OPSGROUP:_CheckDetectedUnits()
-- Add unit to detected table of this run. -- Add unit to detected table of this run.
table.insert(detected, unit) table.insert(detected, unit)
-- Trigger detected unit event. -- Trigger detected unit event ==> This also triggers the DetectedUnitNew and DetectedUnitKnown events.
self:DetectedUnit(unit) self:DetectedUnit(unit)
if self.detectedunits:FindUnit(unitname) then
-- Unit is already in the detected unit set ==> Trigger "DetectedUnitKnown" event.
self:DetectedUnitKnown(unit)
else
-- Unit is was not detected ==> Trigger "DetectedUnitNew" event.
self:DetectedUnitNew(unit)
end
end end
end end
end end
@ -3059,6 +3102,8 @@ function OPSGROUP:_CheckGroupDone(delay)
--- No waypoints left --- No waypoints left
-- No further waypoints. Command a full stop. -- No further waypoints. Command a full stop.
self:T(self.lid..string.format("No waypoints left ==> Full Stop"))
self:__FullStop(-1) self:__FullStop(-1)
end end
@ -3197,7 +3242,15 @@ function OPSGROUP:_AddWaypoint(waypoint, wpnumber)
table.insert(self.waypoints, wpnumber, waypoint) table.insert(self.waypoints, wpnumber, waypoint)
-- Debug info. -- Debug info.
self:T2(self.lid..string.format("Adding waypoint at index=%d id=%d", wpnumber, waypoint.uid)) self:T(self.lid..string.format("Adding waypoint at index=%d id=%d", wpnumber, waypoint.uid))
-- Now we obviously did not pass the final waypoint.
self.passedfinalwp=false
-- Switch to cruise mode.
if self:IsHolding() then
self:Cruise()
end
end end
--- Initialize Mission Editor waypoints. --- Initialize Mission Editor waypoints.
@ -3288,7 +3341,7 @@ end
-- @param #number n Waypoint -- @param #number n Waypoint
function OPSGROUP:_UpdateWaypointTasks(n) function OPSGROUP:_UpdateWaypointTasks(n)
local waypoints=self.waypoints local waypoints=self.waypoints or {}
local nwaypoints=#waypoints local nwaypoints=#waypoints
for i,_wp in pairs(waypoints) do for i,_wp in pairs(waypoints) do