This commit is contained in:
Frank 2020-11-04 22:48:14 +01:00
parent e05d57d908
commit cef0e444c9
5 changed files with 106 additions and 31 deletions

View File

@ -744,7 +744,7 @@ do -- COORDINATE
-- @return #string MGRS coordinates.
function COORDINATE:GetName()
local name=self:ToStringMGRS()
return rname
return name
end
--- Return velocity text of the COORDINATE.
@ -1751,9 +1751,9 @@ do -- COORDINATE
self:F2( { ExplosionIntensity } )
ExplosionIntensity=ExplosionIntensity or 100
if Delay and Delay>0 then
SCHEDULER:New(nil, self.Explosion, {self,ExplosionIntensity}, Delay)
self:ScheduleOnce(Delay, self.Explosion, self, ExplosionIntensity)
else
trigger.action.explosion( self:GetVec3(), ExplosionIntensity )
trigger.action.explosion(self:GetVec3(), ExplosionIntensity)
end
return self
end

View File

@ -47,6 +47,7 @@
-- @field #number markerCoaliton Coalition to which the marker is dispayed.
-- @field #table DCStask DCS task structure.
-- @field #number Ncasualties Number of own casualties during mission.
-- @field #number Nkills Number of (enemy) units killed by assets of this mission.
-- @field #number Nelements Number of elements (units) assigned to mission.
-- @field #number dTevaluate Time interval in seconds before the mission result is evaluated after mission is over.
-- @field #number Tover Mission abs. time stamp, when mission was over.
@ -504,8 +505,9 @@ function AUFTRAG:New(Type)
self.NrepeatFailure=0
self.NrepeatSuccess=0
self.nassets=1
self.dTevaluate=0
self.dTevaluate=5
self.Ncasualties=0
self.Nkills=0
self.Nelements=0
-- FMS start state is PLANNED.
@ -1697,6 +1699,14 @@ function AUFTRAG:GetCasualties()
return self.Ncasualties or 0
end
--- Get kills, i.e. number of units that were destroyed by assets of this mission.
-- @param #AUFTRAG self
-- @return #number Number of units destroyed.
function AUFTRAG:GetKills()
return self.Nkills or 0
end
--- Check if mission is "urgent".
-- @param #AUFTRAG self
-- @return #boolean If `true`, mission is "urgent".
@ -2101,6 +2111,11 @@ function AUFTRAG:onafterStatus(From, Event, To)
-- Ready to evaluate mission outcome?
local ready2evaluate=self.Tover and Tnow-self.Tover>=self.dTevaluate or false
--env.info("FF Tover="..tostring(self.Tover))
--if self.Tover then
-- env.info("FF Tnow-Tover="..tostring(Tnow-self.Tover))
--end
-- Check if mission is OVER (done or cancelled) and enough time passed to evaluate the result.
if self:IsOver() and ready2evaluate then
@ -2199,13 +2214,12 @@ function AUFTRAG:Evaluate()
local text=string.format("Evaluating mission:\n")
text=text..string.format("Own casualties = %d/%d\n", self.Ncasualties, self.Nelements)
text=text..string.format("Own losses = %.1f %%\n", owndamage)
text=text..string.format("Killed units = %d\n", self.Nkills)
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)
--text=text..string.format("--------------------------\n")
text=text..string.format("Success Cond = %s\n", tostring(successCondition))
text=text..string.format("Failure Cond = %s\n", tostring(failureCondition))
text=text..string.format("--------------------------\n")
@ -2563,6 +2577,8 @@ function AUFTRAG:onafterAssetDead(From, Event, To, Asset)
-- Number of groups alive.
local N=self:CountOpsGroups()
self:I(self.lid..string.format("Asset %s dead! Number of ops groups remaining %d", tostring(Asset.spawngroupname), N))
-- All assets dead?
if N==0 then
@ -3045,7 +3061,7 @@ function AUFTRAG:CountOpsGroups()
local N=0
for _,_groupdata in pairs(self.groupdata) do
local groupdata=_groupdata --#AUFTRAG.GroupData
if groupdata and groupdata.opsgroup and groupdata.opsgroup:IsAlive() then
if groupdata and groupdata.opsgroup and groupdata.opsgroup:IsAlive() and not groupdata.opsgroup:IsDead() then
N=N+1
end
end

View File

@ -336,6 +336,7 @@ function FLIGHTGROUP:New(group)
self:HandleEvent(EVENTS.Crash, self.OnEventCrash)
self:HandleEvent(EVENTS.RemoveUnit, self.OnEventRemoveUnit)
self:HandleEvent(EVENTS.UnitLost, self.OnEventUnitLost)
self:HandleEvent(EVENTS.Kill, self.OnEventKill)
-- Init waypoints.
self:InitWaypoints()
@ -715,6 +716,12 @@ function FLIGHTGROUP:GetFuelMin()
return fuelmin*100
end
--- Get number of kills of this group.
-- @param #FLIGHTGROUP self
-- @return #number Number of units killed.
function FLIGHTGROUP:GetKills()
return self.Nkills
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Status
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -741,18 +748,22 @@ function FLIGHTGROUP:onbeforeStatus(From, Event, To)
-- Units with life <=1 are dead.
if life<=1 then
--env.info(string.format("FF unit %s: live<=1 in status at T=%.3f", unit:GetName(), timer.getTime()))
isdead=true
end
else
-- Not alive any more.
--env.info(string.format("FF unit %s: NOT alive in status at T=%.3f", unit:GetName(), timer.getTime()))
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)
local text=string.format("Element %s is dead at t=%.3f! Maybe despawned without notice or landed at a too small airbase. Calling ElementDead in 60 sec to give other events a chance",
tostring(element.name), timer.getTime())
self:E(self.lid..text)
self:__ElementDead(60, element)
end
end
@ -854,9 +865,9 @@ function FLIGHTGROUP:onafterStatus(From, Event, To)
local parking=element.parking and tostring(element.parking.TerminalID) or "X"
-- Check if element is not dead and we missed an event.
if life<=0 and element.status~=OPSGROUP.ElementStatus.DEAD and element.status~=OPSGROUP.ElementStatus.INUTERO then
self:ElementDead(element)
end
--if life<=0 and element.status~=OPSGROUP.ElementStatus.DEAD and element.status~=OPSGROUP.ElementStatus.INUTERO then
-- self:ElementDead(element)
--end
-- Get ammo.
local ammo=self:GetAmmoElement(element)
@ -1177,9 +1188,9 @@ function FLIGHTGROUP:OnEventCrash(EventData)
-- Get element.
local element=self:GetElementByName(unitname)
if element then
self:T3(self.lid..string.format("EVENT: Element %s crashed ==> dead", element.name))
self:ElementDead(element)
if element and element.status~=OPSGROUP.ElementStatus.DEAD then
self:I(self.lid..string.format("EVENT: Element %s crashed ==> destroyed", element.name))
self:ElementDestroyed(element)
end
end
@ -1193,7 +1204,7 @@ function FLIGHTGROUP:OnEventUnitLost(EventData)
-- Check that this is the right group.
if EventData and EventData.IniGroup and EventData.IniUnit and EventData.IniGroupName and EventData.IniGroupName==self.groupname then
self:T(self.lid..string.format("EVENT: Unit %s lost!", EventData.IniUnitName))
self:I(self.lid..string.format("EVENT: Unit %s lost at t=%.3f", EventData.IniUnitName, timer.getTime()))
local unit=EventData.IniUnit
local group=EventData.IniGroup
@ -1202,8 +1213,8 @@ function FLIGHTGROUP:OnEventUnitLost(EventData)
-- Get element.
local element=self:GetElementByName(unitname)
if element then
self:T3(self.lid..string.format("EVENT: Element %s unit lost ==> destroyed", element.name))
if element and element.status~=OPSGROUP.ElementStatus.DEAD then
self:I(self.lid..string.format("EVENT: Element %s unit lost ==> destroyed t=%.3f", element.name, timer.getTime()))
self:ElementDestroyed(element)
end
@ -1211,6 +1222,30 @@ function FLIGHTGROUP:OnEventUnitLost(EventData)
end
--- Flightgroup event function handling the crash of a unit.
-- @param #FLIGHTGROUP self
-- @param Core.Event#EVENTDATA EventData Event data.
function FLIGHTGROUP:OnEventKill(EventData)
-- Check that this is the right group.
if EventData and EventData.IniGroup and EventData.IniUnit and EventData.IniGroupName and EventData.IniGroupName==self.groupname then
self:I(self.lid..string.format("EVENT: Unit %s killed unit %s!", tostring(EventData.IniUnitName), tostring(EventData.TgtUnitName)))
local unit=EventData.IniUnit
local group=EventData.IniGroup
local unitname=EventData.IniUnitName
self.Nkills=self.Nkills+1
local mission=self:GetMissionCurrent()
if mission then
mission.Nkills=mission.Nkills+1
end
end
end
--- Flightgroup event function handling the crash of a unit.
-- @param #FLIGHTGROUP self
-- @param Core.Event#EVENTDATA EventData Event data.

View File

@ -55,6 +55,7 @@
-- @field #boolean detectionOn If true, detected units of the group are analyzed.
-- @field Ops.Auftrag#AUFTRAG missionpaused Paused mission.
-- @field #number Ndestroyed Number of destroyed units.
-- @field #number Nkills Number kills of this groups.
--
-- @field Core.Point#COORDINATE coordinate Current coordinate.
--
@ -88,7 +89,7 @@
--
-- @field #OPSGROUP.Spot spot Laser and IR spot.
--
-- @field #OPSGROUP.Ammo ammo Initial ammuont of ammo.
-- @field #OPSGROUP.Ammo ammo Initial ammount of ammo.
--
-- @extends Core.Fsm#FSM
@ -142,6 +143,7 @@ OPSGROUP = {
icls = {},
callsign = {},
Ndestroyed = 0,
Nkills = 0,
}
@ -352,9 +354,16 @@ function OPSGROUP:New(Group)
self.group=Group
self.groupname=Group:GetName()
end
-- Set some string id for output to DCS.log file.
self.lid=string.format("OPSGROUP %s | ", self.groupname)
self.lid=string.format("OPSGROUP %s | ", tostring(self.groupname))
if self.group then
if not self:IsExist() then
self:E(self.lid.."ERROR: GROUP does not exist! Returning nil")
return nil
end
end
-- Init set of detected units.
self.detectedunits=SET_UNIT:New()
@ -531,7 +540,11 @@ end
-- @return #OPSGROUP self
function OPSGROUP:SetLaser(Code, CheckLOS, IROff, UpdateTime)
self.spot.Code=Code or 1688
self.spot.CheckLOS=CheckLOS and CheckLOS or true
if CheckLOS~=nil then
self.spot.CheckLOS=CheckLOS
else
self.spot.CheckLOS=true
end
self.spot.IRon=not IROff
self.spot.dt=UpdateTime or 0.5
return self
@ -1303,7 +1316,7 @@ end
-- @return #OPSGROUP.Waypoint Waypoint data.
function OPSGROUP:GetWaypointByID(uid)
for _,_waypoint in pairs(self.waypoints) do
for _,_waypoint in pairs(self.waypoints or {}) do
local waypoint=_waypoint --#OPSGROUP.Waypoint
if waypoint.uid==uid then
return waypoint
@ -2190,11 +2203,16 @@ function OPSGROUP:onafterTaskCancel(From, Event, To, Task)
-- Set stop flag. When the flag is true, the _TaskDone function is executed and calls :TaskDone()
Task.stopflag:Set(1)
local done=false
if Task.dcstask.id=="Formation" then
Task.formation:Stop()
self:TaskDone(Task)
elseif stopflag==1 or not self:IsAlive() then
done=true
elseif stopflag==1 or (not self:IsAlive()) or self:IsDead() or self:IsStopped() then
-- Manual call TaskDone if setting flag to one was not successful.
done=true
end
if done then
self:TaskDone(Task)
end
@ -3173,7 +3191,7 @@ function OPSGROUP:onbeforeLaserOn(From, Event, To, Target)
self.spot.element=element
-- Height offset. No offset for aircraft. We take the height for ground or naval.
local offsetY=0
local offsetY=0
if self.isGround or self.isNaval then
offsetY=element.height
end
@ -3480,6 +3498,10 @@ function OPSGROUP:SetLaserTarget(Target)
-- Coordinate as target.
self.spot.TargetType=0
self.spot.offsetTarget={x=0, y=0, z=0}
elseif Target:IsInstanceOf("SCENERY") then
-- Coordinate as target.
self.spot.TargetType=0
self.spot.offsetTarget={x=0, y=1, z=0}
else
self:E(self.lid.."ERROR: LASER target should be a POSITIONABLE (GROUP, UNIT or STATIC) or a COORDINATE object!")
return
@ -3625,7 +3647,7 @@ end
-- @param #string To To state.
-- @param #OPSGROUP.Element Element The flight group element.
function OPSGROUP:onafterElementDead(From, Event, To, Element)
self:T(self.lid..string.format("Element dead %s", Element.name))
self:T(self.lid..string.format("Element dead %s at t=%.3f", Element.name, timer.getTime()))
-- Set element status.
self:_UpdateStatus(Element, OPSGROUP.ElementStatus.DEAD)
@ -3672,7 +3694,7 @@ end
-- @param #string Event Event.
-- @param #string To To state.
function OPSGROUP:onafterDead(From, Event, To)
self:T(self.lid..string.format("Group dead!"))
self:T(self.lid..string.format("Group dead at t=%.3f", timer.getTime()))
-- Delete waypoints so they are re-initialized at the next spawn.
self.waypoints=nil
@ -3682,6 +3704,8 @@ function OPSGROUP:onafterDead(From, Event, To)
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
self:T(self.lid.."Cancelling mission because group is dead! Mission name "..tostring(mission:GetName()))
self:MissionCancel(mission)
mission:GroupDead(self)
@ -3713,7 +3737,7 @@ function OPSGROUP:onafterStop(From, Event, To)
end
-- Debug output.
self:T(self.lid.."STOPPED! Unhandled events, cleared scheduler and removed from database.")
self:I(self.lid.."STOPPED! Unhandled events, cleared scheduler and removed from database.")
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -525,12 +525,12 @@ function TARGET:_AddObject(Object)
elseif Object:IsInstanceOf("COORDINATE") then
local coord=Object --Core.Point#COORDINATE
local coord=UTILS.DeepCopy(Object) --Core.Point#COORDINATE
target.Type=TARGET.ObjectType.COORDINATE
target.Name=coord:ToStringMGRS()
target.Coordinate=Object
target.Coordinate=coord
target.Life0=1
target.Life=1