- 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.optionAlarm=0
mission.missionFraction=0.1
mission.missionFraction=0.0
-- Evaluate after 8 min.
mission.dTevaluate=8*60
mission.DCStask=mission:GetDCSMissionTask()
@ -1186,29 +1189,10 @@ function AUFTRAG:NewTargetAir(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 mission=self:NewAUTO(target)
if mission then
mission:SetPriority(10, true)
end
@ -2133,6 +2117,9 @@ function AUFTRAG:Evaluate()
local Ntargets=self:CountMissionTargets()
local Ntargets0=self:GetTargetInitialNumber()
local Life=self:GetTargetLife()
local Life0=self:GetTargetInitialLife()
if Ntargets0>0 then
@ -2196,6 +2183,7 @@ function AUFTRAG:Evaluate()
text=text..string.format("Own losses = %.1f %%\n", owndamage)
text=text..string.format("--------------------------\n")
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("--------------------------\n")
--text=text..string.format("Loss ratio = %.1f %%\n", targetdamage)

View File

@ -708,6 +708,41 @@ end
-- @param #FLIHGTGROUP self
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
self:T(self.lid..string.format("Onbefore Status DEAD ==> false"))
return false
@ -1328,6 +1363,13 @@ end
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"))
if self.despawnAfterLanding then
-- Despawn the element.
self:DespawnElement(Element)
else
-- Helos with skids land directly on parking spots.
if self.ishelo then
@ -1339,6 +1381,8 @@ function FLIGHTGROUP:onafterElementLanded(From, Event, To, Element, airbase)
-- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.LANDED, airbase)
end
end
--- On after "ElementArrived" event.
@ -1411,6 +1455,9 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
-- Set ROT.
self:SwitchROT(self.option.ROT)
-- Set Formation
self:SwitchFormation(self.option.Formation)
-- Turn TACAN beacon on.
if self.tacan.On then
self:_SwitchTACAN(self.tacan)
@ -1573,10 +1620,6 @@ function FLIGHTGROUP:onafterLanded(From, Event, To, airbase)
self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.TAXIINB)
end
if self.despawnAfterLanding then
self:Despawn()
end
end
--- On after "LandedAt" event.
@ -1603,9 +1646,9 @@ function FLIGHTGROUP:onafterArrived(From, Event, To)
self.flightcontrol:SetFlightStatus(self, FLIGHTCONTROL.FlightStatus.ARRIVED)
end
-- Stop and despawn in 5 min.
-- Despawn in 5 min.
if not self.airwing then
self:__Stop(5*60)
self:Despawn(5*60)
end
end
@ -1732,8 +1775,10 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
local current=self.group:GetCoordinate():WaypointAir(COORDINATE.WaypointAltType.BARO, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, speed, true, nil, {}, "Current")
table.insert(wp, current)
local Nwp=self.waypoints and #self.waypoints or 0
-- Add remaining waypoints to route.
for i=n, #self.waypoints do
for i=n, Nwp do
table.insert(wp, self.waypoints[i])
end
@ -2437,9 +2482,6 @@ function FLIGHTGROUP:onafterStop(From, Event, To)
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
-- Handle events:

View File

@ -575,7 +575,7 @@ function NAVYGROUP:onafterUpdateRoute(From, Event, To, n, Speed, Depth)
n=n or self:GetWaypointIndexNext()
-- 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.
self:_UpdateWaypointTasks(n)
@ -784,6 +784,7 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function NAVYGROUP:onafterFullStop(From, Event, To)
self:T(self.lid.."Full stop ==> holding")
-- Get current position.
local pos=self:GetCoordinate()

View File

@ -669,16 +669,37 @@ function OPSGROUP:Destroy(Delay)
return self
end
--- Despawn a unit.
--- Despawn an element/unit of the group.
-- @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
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 DCSunit then
-- Destroy object.
DCSunit:destroy()
-- Create a remove unit event.
if not NoEventRemoveUnit then
self:CreateEventRemoveUnit(timer.getTime(), DCSunit)
end
end
end
if DCSGroup then
DCSGroup:destroy()
self:CreateEventRemoveUnit(timer.getTime(), DCSObject)
end
return self
@ -1082,7 +1103,7 @@ end
function OPSGROUP:GetWaypointIndex(uid)
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
if waypoint.uid==uid then
return i
@ -2242,11 +2263,6 @@ function OPSGROUP:onafterMissionExecute(From, Event, To, Mission)
-- Set mission status to EXECUTING.
Mission:Executing()
-- Formation
if Mission.optionFormation then
self:SwitchFormation(Mission.optionFormation)
end
end
--- On after "PauseMission" event.
@ -2371,7 +2387,7 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
-- Remove mission waypoint.
local wpidx=Mission:GetGroupWaypointIndex(self)
if wpidx then
self:RemoveWaypoint(wpidx)
self:RemoveWaypointByID(wpidx)
end
-- Decrease patrol data.
@ -2380,6 +2396,27 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
AIRWING.UpdatePatrolPointMarker(Mission.patroldata)
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
if Mission.tacan then
@ -2400,22 +2437,7 @@ function OPSGROUP:onafterMissionDone(From, Event, To, Mission)
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
self:SwitchROE()
end
if Mission.optionROT then
self:SwitchROT()
end
if Mission.optionAlarm then
self:SwitchAlarmstate()
end
-- TODO: reset ICLS settings.
-- Check if group is done.
self:_CheckGroupDone(1)
@ -2482,17 +2504,21 @@ function OPSGROUP:RouteToMission(mission, delay)
-- Check if we are within range.
if dist>weapondata.RangeMax then
local d=dist-weapondata.RangeMax
d=(1.1)*d
local d=(dist-weapondata.RangeMax)*1.1
-- New waypoint coord.
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
local d=dist-weapondata.RangeMin
d=(1.1)*d
local d=(dist-weapondata.RangeMin)*1.1
-- New waypoint coord.
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
@ -2523,22 +2549,26 @@ function OPSGROUP:RouteToMission(mission, delay)
if mission.optionROT then
self:SwitchROT(mission.optionROT)
end
-- Radio
if mission.radio then
self:SwitchRadio(mission.radio.Freq, mission.radio.Modu)
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)
-- Alarm state.
if mission.optionAlarm then
self:SwitchAlarmstate(mission.optionAlarm)
end
-- Formation
if mission.optionFormation then
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
@ -2735,8 +2765,22 @@ end
-- @param #string To To state.
-- @param Wrapper.Unit#UNIT Unit The detected 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
--- On after "DetectedUnitNew" event.
@ -2747,6 +2791,9 @@ end
-- @param Wrapper.Unit#UNIT Unit The detected unit.
function OPSGROUP:onafterDetectedUnitNew(From, Event, To, Unit)
self:T(self.lid..string.format("Detected New unit %s", Unit:GetName()))
-- Add unit to detected unit set.
self.detectedunits:AddUnit(Unit)
end
--- On after "EnterZone" event. Sets self.inzones[zonename]=true.
@ -2851,9 +2898,11 @@ function OPSGROUP:onafterStop(From, Event, To)
-- Stop FSM scheduler.
self.CallScheduler:Clear()
if self:IsAlive() then
if self:IsAlive() and not (self:IsDead() or self:IsStopped()) then
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
-- Debug output.
@ -2931,6 +2980,8 @@ function OPSGROUP:_CheckDetectedUnits()
local DetectedObject=Detection.object -- DCS#Object
if DetectedObject and DetectedObject:isExist() and DetectedObject.id_<50000000 then
-- Unit.
local unit=UNIT:Find(DetectedObject)
if unit and unit:IsAlive() then
@ -2941,17 +2992,9 @@ function OPSGROUP:_CheckDetectedUnits()
-- Add unit to detected table of this run.
table.insert(detected, unit)
-- Trigger detected unit event.
-- Trigger detected unit event ==> This also triggers the DetectedUnitNew and DetectedUnitKnown events.
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
@ -3059,6 +3102,8 @@ function OPSGROUP:_CheckGroupDone(delay)
--- No waypoints left
-- No further waypoints. Command a full stop.
self:T(self.lid..string.format("No waypoints left ==> Full Stop"))
self:__FullStop(-1)
end
@ -3197,7 +3242,15 @@ function OPSGROUP:_AddWaypoint(waypoint, wpnumber)
table.insert(self.waypoints, wpnumber, waypoint)
-- 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
--- Initialize Mission Editor waypoints.
@ -3288,7 +3341,7 @@ end
-- @param #number n Waypoint
function OPSGROUP:_UpdateWaypointTasks(n)
local waypoints=self.waypoints
local waypoints=self.waypoints or {}
local nwaypoints=#waypoints
for i,_wp in pairs(waypoints) do