AUFTRAG
- Changed ESCORT engage distance input to NM (not meters)

TARGET
- Fixed bug in count targets
- Improved dead/destroyed management

FLIGHTGROUP
- Only register UNIT/STATIC kills (not SCENERY)

INTEL
- Improved agent set
This commit is contained in:
Frank 2020-11-21 21:49:47 +01:00
parent 122425338e
commit 770fb3228f
4 changed files with 260 additions and 93 deletions

View File

@ -1073,7 +1073,7 @@ end
-- @param #AUFTRAG self -- @param #AUFTRAG self
-- @param Wrapper.Group#GROUP EscortGroup The group to escort. -- @param Wrapper.Group#GROUP EscortGroup The group to escort.
-- @param DCS#Vec3 OffsetVector A table with x, y and z components specifying the offset of the flight to the escorted group. Default {x=-100, y=0, z=200} for z=200 meters to the right, same alitude, x=100 meters behind. -- @param DCS#Vec3 OffsetVector A table with x, y and z components specifying the offset of the flight to the escorted group. Default {x=-100, y=0, z=200} for z=200 meters to the right, same alitude, x=100 meters behind.
-- @param #number EngageMaxDistance Max engage distance of targets in meters. Default auto (*nil*). -- @param #number EngageMaxDistance Max engage distance of targets in nautical miles. Default auto (*nil*).
-- @param #table TargetTypes Types of targets to engage automatically. Default is {"Air"}, i.e. all enemy airborne units. Use an empty set {} for a simple "FOLLOW" mission. -- @param #table TargetTypes Types of targets to engage automatically. Default is {"Air"}, i.e. all enemy airborne units. Use an empty set {} for a simple "FOLLOW" mission.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetTypes) function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetTypes)
@ -1084,7 +1084,7 @@ function AUFTRAG:NewESCORT(EscortGroup, OffsetVector, EngageMaxDistance, TargetT
-- DCS task parameters: -- DCS task parameters:
mission.escortVec3=OffsetVector or {x=-100, y=0, z=200} mission.escortVec3=OffsetVector or {x=-100, y=0, z=200}
mission.engageMaxDistance=EngageMaxDistance mission.engageMaxDistance=EngageMaxDistance and UTILS.NMToMeters(EngageMaxDistance) or nil
mission.engageTargetTypes=TargetTypes or {"Air"} mission.engageTargetTypes=TargetTypes or {"Air"}
-- Mission options: -- Mission options:
@ -2608,7 +2608,7 @@ end
function AUFTRAG:onafterCancel(From, Event, To) function AUFTRAG:onafterCancel(From, Event, To)
-- Debug info. -- Debug info.
self:I(self.lid..string.format("CANCELLING mission in status %s. Will wait for groups to report mission DONE before evaluation.", self.status)) self:I(self.lid..string.format("CANCELLING mission in status %s. Will wait for groups to report mission DONE before evaluation", self.status))
-- Time stamp. -- Time stamp.
self.Tover=timer.getAbsTime() self.Tover=timer.getAbsTime()
@ -2846,7 +2846,7 @@ function AUFTRAG:_TargetFromObject(Object)
end end
-- Debug info. -- Debug info.
self:I(self.lid..string.format("Mission Target %s Type=%s, Ntargets=%d, Lifepoints=%d", self.engageTarget.lid, self.engageTarget.lid, self.engageTarget.Ntargets0, self.engageTarget:GetLife())) --self:T2(self.lid..string.format("Mission Target %s Type=%s, Ntargets=%d, Lifepoints=%d", self.engageTarget.lid, self.engageTarget.lid, self.engageTarget.N0, self.engageTarget:GetLife()))
return self return self
end end
@ -2871,7 +2871,7 @@ end
function AUFTRAG:GetTargetInitialNumber() function AUFTRAG:GetTargetInitialNumber()
local target=self:GetTargetData() local target=self:GetTargetData()
if target then if target then
return target.Ntargets0 return target.N0
else else
return 0 return 0
end end

View File

@ -225,7 +225,7 @@ FLIGHTGROUP.version="0.6.0"
--- Create a new FLIGHTGROUP object and start the FSM. --- Create a new FLIGHTGROUP object and start the FSM.
-- @param #FLIGHTGROUP self -- @param #FLIGHTGROUP self
-- @param Wrapper.Group#GROUP Group The group object. Can also be given by its group name as `#string`. -- @param Wrapper.Group#GROUP group The group object. Can also be given by its group name as `#string`.
-- @return #FLIGHTGROUP self -- @return #FLIGHTGROUP self
function FLIGHTGROUP:New(group) function FLIGHTGROUP:New(group)
@ -1229,17 +1229,34 @@ function FLIGHTGROUP:OnEventKill(EventData)
-- Check that this is the right group. -- Check that this is the right group.
if EventData and EventData.IniGroup and EventData.IniUnit and EventData.IniGroupName and EventData.IniGroupName==self.groupname then if EventData and EventData.IniGroup and EventData.IniUnit and EventData.IniGroupName and EventData.IniGroupName==self.groupname then
self:T2(self.lid..string.format("EVENT: Unit %s killed unit %s!", tostring(EventData.IniUnitName), tostring(EventData.TgtUnitName)))
local unit=EventData.IniUnit -- Target name
local group=EventData.IniGroup local targetname=tostring(EventData.TgtUnitName)
local unitname=EventData.IniUnitName
-- Debug info.
self:T2(self.lid..string.format("EVENT: Unit %s killed object %s!", tostring(EventData.IniUnitName), targetname))
-- Check if this was a UNIT or STATIC object.
local target=UNIT:FindByName(targetname)
if not target then
target=STATIC:FindByName(targetname, false)
end
-- Only count UNITS and STATICs (not SCENERY)
if target then
-- Debug info.
self:T(self.lid..string.format("EVENT: Unit %s killed unit/static %s!", tostring(EventData.IniUnitName), targetname))
-- Kill counter.
self.Nkills=self.Nkills+1 self.Nkills=self.Nkills+1
-- Check if on a mission.
local mission=self:GetMissionCurrent() local mission=self:GetMissionCurrent()
if mission then if mission then
mission.Nkills=mission.Nkills+1 mission.Nkills=mission.Nkills+1 -- Increase mission kill counter.
end
end end
end end
@ -1526,9 +1543,9 @@ function FLIGHTGROUP:onafterSpawned(From, Event, To)
end end
-- TODO: make this input. -- TODO: make this input.
self.group:SetOption(AI.Option.Air.id.PROHIBIT_JETT, true) self:GetGroup():SetOption(AI.Option.Air.id.PROHIBIT_JETT, true)
self.group:SetOption(AI.Option.Air.id.PROHIBIT_AB, true) -- Does not seem to work. AI still used the after burner. self:GetGroup():SetOption(AI.Option.Air.id.PROHIBIT_AB, true) -- Does not seem to work. AI still used the after burner.
self.group:SetOption(AI.Option.Air.id.RTB_ON_BINGO, false) self:GetGroup():SetOption(AI.Option.Air.id.RTB_ON_BINGO, false)
--self.group:SetOption(AI.Option.Air.id.RADAR_USING, AI.Option.Air.val.RADAR_USING.FOR_CONTINUOUS_SEARCH) --self.group:SetOption(AI.Option.Air.id.RADAR_USING, AI.Option.Air.val.RADAR_USING.FOR_CONTINUOUS_SEARCH)
-- Update route. -- Update route.

View File

@ -113,8 +113,9 @@ INTEL.version="0.0.3"
-- @param #INTEL self -- @param #INTEL self
-- @param Core.Set#SET_GROUP DetectionSet Set of detection groups. -- @param Core.Set#SET_GROUP DetectionSet Set of detection groups.
-- @param #number Coalition Coalition side. Can also be passed as a string "red", "blue" or "neutral". -- @param #number Coalition Coalition side. Can also be passed as a string "red", "blue" or "neutral".
-- @param #string Alias An *optional* alias how this object is called in the logs etc.
-- @return #INTEL self -- @return #INTEL self
function INTEL:New(DetectionSet, Coalition) function INTEL:New(DetectionSet, Coalition, Alias)
-- Inherit everything from FSM class. -- Inherit everything from FSM class.
local self=BASE:Inherit(self, FSM:New()) -- #INTEL local self=BASE:Inherit(self, FSM:New()) -- #INTEL
@ -122,10 +123,34 @@ function INTEL:New(DetectionSet, Coalition)
-- Detection set. -- Detection set.
self.detectionset=DetectionSet or SET_GROUP:New() self.detectionset=DetectionSet or SET_GROUP:New()
if Coalition and type(Coalition)=="string" then
if Coalition=="blue" then
Coalition=coalition.side.BLUE
elseif Coalition=="red" then
Coalition=coalition.side.RED
elseif Coalition=="neutral" then
Coalition=coalition.side.NEUTRAL
else
self:E("ERROR: Unknown coalition in INTEL!")
end
end
-- Determine coalition from first group in set. -- Determine coalition from first group in set.
self.coalition=Coalition or DetectionSet:CountAlive()>0 and DetectionSet:GetFirst():GetCoalition() or nil self.coalition=Coalition or DetectionSet:CountAlive()>0 and DetectionSet:GetFirst():GetCoalition() or nil
-- Filter coalition.
if self.coalition then
local coalitionname=UTILS.GetCoalitionName(self.coalition):lower()
self.detectionset:FilterCoalitions(coalitionname)
end
-- Filter once.
self.detectionset:FilterOnce()
-- Set alias. -- Set alias.
if Alias then
self.alias=tostring(Alias)
else
self.alias="SPECTRE" self.alias="SPECTRE"
if self.coalition then if self.coalition then
if self.coalition==coalition.side.RED then if self.coalition==coalition.side.RED then
@ -134,9 +159,10 @@ function INTEL:New(DetectionSet, Coalition)
self.alias="CIA" self.alias="CIA"
end end
end end
end
-- Set some string id for output to DCS.log file. -- Set some string id for output to DCS.log file.
self.lid=string.format("INTEL %s | ", self.alias) self.lid=string.format("INTEL %s (%s) | ", self.alias, self.coalition and UTILS.GetCoalitionName(self.coalition) or "unknown")
-- Start State. -- Start State.
self:SetStartState("Stopped") self:SetStartState("Stopped")

View File

@ -16,7 +16,6 @@
--- TARGET class. --- TARGET class.
-- @type TARGET -- @type TARGET
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @field #boolean Debug Debug mode. Messages to all about status.
-- @field #number verbose Verbosity level. -- @field #number verbose Verbosity level.
-- @field #string lid Class id string for output to DCS log file. -- @field #string lid Class id string for output to DCS log file.
-- @field #table targets Table of target objects. -- @field #table targets Table of target objects.
@ -25,7 +24,12 @@
-- @field #number life0 Total life points of completely healthy targets. -- @field #number life0 Total life points of completely healthy targets.
-- @field #number threatlevel0 Initial threat level. -- @field #number threatlevel0 Initial threat level.
-- @field #number category Target category (Ground, Air, Sea). -- @field #number category Target category (Ground, Air, Sea).
-- @field #number Ntargets0 Number of initial targets. -- @field #number N0 Number of initial target elements/units.
-- @field #number Ntargets0 Number of initial target objects.
-- @field #number Ndestroyed Number of target elements/units that were destroyed.
-- @field #number Ndead Number of target elements/units that are dead (destroyed or despawned).
-- @field #table elements Table of target elements/units.
-- @field #table casualties Table of dead element names.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- **It is far more important to be able to hit the target than it is to haggle over who makes a weapon or who pulls a trigger** -- Dwight D. Eisenhower --- **It is far more important to be able to hit the target than it is to haggle over who makes a weapon or who pulls a trigger** -- Dwight D. Eisenhower
@ -44,14 +48,18 @@
-- @field #TARGET -- @field #TARGET
TARGET = { TARGET = {
ClassName = "TARGET", ClassName = "TARGET",
Debug = nil,
verbose = 0, verbose = 0,
lid = nil, lid = nil,
targets = {}, targets = {},
targetcounter = 0, targetcounter = 0,
life = 0, life = 0,
life0 = 0, life0 = 0,
N0 = 0,
Ntargets0 = 0, Ntargets0 = 0,
Ndestroyed = 0,
Ndead = 0,
elements = {},
casualties = {},
threatlevel0 = 0 threatlevel0 = 0
} }
@ -83,7 +91,7 @@ TARGET.ObjectType={
-- @field #string COORDINATE -- @field #string COORDINATE
TARGET.Category={ TARGET.Category={
AIRCRAFT="Aircraft", AIRCRAFT="Aircraft",
GROUND="Grund", GROUND="Ground",
NAVAL="Naval", NAVAL="Naval",
AIRBASE="Airbase", AIRBASE="Airbase",
COORDINATE="Coordinate", COORDINATE="Coordinate",
@ -97,14 +105,17 @@ TARGET.ObjectStatus={
ALIVE="Alive", ALIVE="Alive",
DEAD="Dead", DEAD="Dead",
} }
--- Type. --- Target object.
-- @type TARGET.Object -- @type TARGET.Object
-- @field #number ID Target unique ID. -- @field #number ID Target unique ID.
-- @field #string Name Target name. -- @field #string Name Target name.
-- @field #string Type Target type. -- @field #string Type Target type.
-- @field Wrapper.Positionable#POSITIONABLE Object The object, which can be many things, e.g. a UNIT, GROUP, STATIC, AIRBASE or COORDINATE object. -- @field Wrapper.Positionable#POSITIONABLE Object The object, which can be many things, e.g. a UNIT, GROUP, STATIC, SCENERY, AIRBASE or COORDINATE object.
-- @field #number Life Life points on last status update. -- @field #number Life Life points on last status update.
-- @field #number Life0 Life points of completely healthy target. -- @field #number Life0 Life points of completely healthy target.
-- @field #number N0 Number of initial elements.
-- @field #number Ndead Number of dead elements.
-- @field #number Ndestroyed Number of destroyed elements.
-- @field #string Status Status "Alive" or "Dead". -- @field #string Status Status "Alive" or "Dead".
-- @field Core.Point#COORDINATE Coordinate of the target object. -- @field Core.Point#COORDINATE Coordinate of the target object.
@ -113,7 +124,7 @@ _TARGETID=0
--- TARGET class version. --- TARGET class version.
-- @field #string version -- @field #string version
TARGET.version="0.2.1" TARGET.version="0.3.0"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
@ -144,7 +155,7 @@ function TARGET:New(TargetObject)
local Target=self.targets[1] --#TARGET.Object local Target=self.targets[1] --#TARGET.Object
if not Target then if not Target then
self:E(self.lid.."ERROR: No valid TARGET!") self:E("ERROR: No valid TARGET!")
return nil return nil
end end
@ -155,7 +166,7 @@ function TARGET:New(TargetObject)
self.category=self:GetTargetCategory(Target) self.category=self:GetTargetCategory(Target)
-- Log ID. -- Log ID.
self.lid=string.format("TARGET #%03d %s | ", _TARGETID, self.category) self.lid=string.format("TARGET #%03d [%s] | ", _TARGETID, tostring(self.category))
-- Start state. -- Start state.
self:SetStartState("Stopped") self:SetStartState("Stopped")
@ -166,12 +177,13 @@ function TARGET:New(TargetObject)
self:AddTransition("*", "Status", "*") -- Status update. self:AddTransition("*", "Status", "*") -- Status update.
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM. self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
self:AddTransition("*", "ObjectDamaged", "*") -- A Target was damaged. self:AddTransition("*", "ObjectDamaged", "*") -- A target object was damaged.
self:AddTransition("*", "ObjectDestroyed", "*") -- A Target was destroyed. self:AddTransition("*", "ObjectDestroyed", "*") -- A target object was destroyed.
self:AddTransition("*", "ObjectRemoved", "*") -- A Target was removed. self:AddTransition("*", "ObjectDead", "*") -- A target object is dead (destroyed or despawned).
self:AddTransition("*", "Damaged", "*") -- Target was damaged. self:AddTransition("*", "Damaged", "*") -- Target was damaged.
self:AddTransition("*", "Destroyed", "Dead") -- Target was completely destroyed. self:AddTransition("*", "Destroyed", "Dead") -- Target was completely destroyed.
self:AddTransition("*", "Dead", "Dead") -- Target was completely destroyed.
------------------------ ------------------------
--- Pseudo Functions --- --- Pseudo Functions ---
@ -232,14 +244,6 @@ function TARGET:AddObject(Object)
self:AddObject(object) self:AddObject(object)
end end
--[[
elseif Object:IsInstanceOf("GROUP") then
for _,unit in pairs(Object:GetUnits()) do
self:_AddObject(unit)
end
]]
else else
--- ---
@ -254,14 +258,14 @@ end
--- Check if TARGET is alive. --- Check if TARGET is alive.
-- @param #TARGET self -- @param #TARGET self
-- @param #boolean If true, target is alive. -- @return #boolean If true, target is alive.
function TARGET:IsAlive() function TARGET:IsAlive()
return self:Is("Alive") return self:Is("Alive")
end end
--- Check if TARGET is dead. --- Check if TARGET is dead.
-- @param #TARGET self -- @param #TARGET self
-- @param #boolean If true, target is dead. -- @return #boolean If true, target is dead.
function TARGET:IsDead() function TARGET:IsDead()
return self:Is("Dead") return self:Is("Dead")
end end
@ -284,8 +288,7 @@ function TARGET:onafterStart(From, Event, To)
self:HandleEvent(EVENTS.Dead, self.OnEventUnitDeadOrLost) self:HandleEvent(EVENTS.Dead, self.OnEventUnitDeadOrLost)
self:HandleEvent(EVENTS.UnitLost, self.OnEventUnitDeadOrLost) self:HandleEvent(EVENTS.UnitLost, self.OnEventUnitDeadOrLost)
self:HandleEvent(EVENTS.RemoveUnit, self.OnEventUnitDeadOrLost)
self:HandleEvent(EVENTS.RemoveUnit, self.OnEventRemoveUnit)
self:__Status(-1) self:__Status(-1)
end end
@ -323,8 +326,8 @@ function TARGET:onafterStatus(From, Event, To)
end end
-- Log output verbose=1. -- Log output verbose=1.
if self.verbose>=0 then if self.verbose>=1 then
local text=string.format("%s: Targets=%d/%d Life=%.1f/%.1f Damage=%.1f", fsmstate, self:CountTargets(), self.Ntargets0, self:GetLife(), self:GetLife0(), self:GetDamage()) local text=string.format("%s: Targets=%d/%d Life=%.1f/%.1f Damage=%.1f", fsmstate, self:CountTargets(), self.N0, self:GetLife(), self:GetLife0(), self:GetDamage())
if damaged then if damaged then
text=text.." Damaged!" text=text.." Damaged!"
end end
@ -332,7 +335,7 @@ function TARGET:onafterStatus(From, Event, To)
end end
-- Log output verbose=2. -- Log output verbose=2.
if self.verbose>=0 then if self.verbose>=2 then
local text="Target:" local text="Target:"
for i,_target in pairs(self.targets) do for i,_target in pairs(self.targets) do
local target=_target --#TARGET.Object local target=_target --#TARGET.Object
@ -343,7 +346,9 @@ function TARGET:onafterStatus(From, Event, To)
end end
-- Update status again in 30 sec. -- Update status again in 30 sec.
if self:IsAlive() then
self:__Status(-30) self:__Status(-30)
end
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -358,6 +363,7 @@ end
-- @param #TARGET.Object Target Target object. -- @param #TARGET.Object Target Target object.
function TARGET:onafterObjectDamaged(From, Event, To, Target) function TARGET:onafterObjectDamaged(From, Event, To, Target)
-- Debug info.
self:T(self.lid..string.format("Object %s damaged", Target.Name)) self:T(self.lid..string.format("Object %s damaged", Target.Name))
end end
@ -371,11 +377,33 @@ end
function TARGET:onafterObjectDestroyed(From, Event, To, Target) function TARGET:onafterObjectDestroyed(From, Event, To, Target)
-- Debug message. -- Debug message.
self:I(self.lid..string.format("Object %s destroyed", Target.Name)) self:T(self.lid..string.format("Object %s destroyed", Target.Name))
-- Increase destroyed counter.
self.Ndestroyed=self.Ndestroyed+1
-- Call object dead event.
self:ObjectDead(Target)
end
--- On after "ObjectDead" event.
-- @param #TARGET self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #TARGET.Object Target Target object.
function TARGET:onafterObjectDead(From, Event, To, Target)
-- Debug message.
self:T(self.lid..string.format("Object %s dead", Target.Name))
-- Set target status. -- Set target status.
Target.Status=TARGET.ObjectStatus.DEAD Target.Status=TARGET.ObjectStatus.DEAD
-- Increase dead counter.
self.Ndead=self.Ndead+1
-- Check if anyone is alive? -- Check if anyone is alive?
local dead=true local dead=true
for _,_target in pairs(self.targets) do for _,_target in pairs(self.targets) do
@ -387,7 +415,16 @@ function TARGET:onafterObjectDestroyed(From, Event, To, Target)
-- All dead ==> Trigger destroyed event. -- All dead ==> Trigger destroyed event.
if dead then if dead then
if self.Ndestroyed==self.Ntargets0 then
self:Destroyed() self:Destroyed()
else
self:Dead()
end
end end
end end
@ -399,7 +436,7 @@ end
-- @param #string To To state. -- @param #string To To state.
function TARGET:onafterDamaged(From, Event, To) function TARGET:onafterDamaged(From, Event, To)
self:T(self.lid..string.format("Target damaged")) self:T(self.lid..string.format("TARGET damaged"))
end end
@ -410,7 +447,20 @@ end
-- @param #string To To state. -- @param #string To To state.
function TARGET:onafterDestroyed(From, Event, To) function TARGET:onafterDestroyed(From, Event, To)
self:I(self.lid..string.format("Target destroyed")) self:T(self.lid..string.format("TARGET destroyed"))
self:Dead()
end
--- On after "Dead" event.
-- @param #TARGET self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function TARGET:onafterDead(From, Event, To)
self:T(self.lid..string.format("TARGET dead"))
end end
@ -423,44 +473,61 @@ end
-- @param Core.Event#EVENTDATA EventData Event data. -- @param Core.Event#EVENTDATA EventData Event data.
function TARGET:OnEventUnitDeadOrLost(EventData) function TARGET:OnEventUnitDeadOrLost(EventData)
local Name=EventData and EventData.IniUnitName or nil
-- Check that this is the right group. -- Check that this is the right group.
if EventData and EventData.IniUnitName then if self:IsElement(Name) and not self:IsCasualty(Name) then
-- Debug info. -- Debug info.
self:T(self.lid..string.format("EVENT: Unit %s dead or lost!", tostring(EventData.IniUnitName))) self:T3(self.lid..string.format("EVENT ID=%d: Unit %s dead or lost!", EventData.id, tostring(Name)))
local deadnow=false -- Add to the list of casualties.
table.insert(self.casualties, Name)
-- Target -- Try to get target Group.
local target=self:GetTargetByName(EventData.IniGroupName) local target=self:GetTargetByName(EventData.IniGroupName)
if target then -- Try unit target.
if not target then
local N=self:CountObjectives(target)
if N==0 then
deadnow=true
end
else
target=self:GetTargetByName(EventData.IniUnitName) target=self:GetTargetByName(EventData.IniUnitName)
if target then
deadnow=true
end
end end
-- Check if this is one of ours. -- Check if we could find a target object.
if deadnow and target.Status==TARGET.ObjectStatus.ALIVE then if target then
if EventData.id==EVENTS.RemoveUnit then
target.Ndead=target.Ndead+1
else
target.Ndestroyed=target.Ndestroyed+1
target.Ndead=target.Ndead+1
end
if target.Ndead==target.N0 then
if target.Ndestroyed>=target.N0 then
-- Debug message. -- Debug message.
self:T(self.lid..string.format("EVENT: target unit %s dead or lost ==> destroyed", tostring(target.Name))) self:T2(self.lid..string.format("EVENT ID=%d: target %s dead/lost ==> destroyed", EventData.id, tostring(target.Name)))
-- Trigger object destroyed event. -- Trigger object destroyed event.
self:ObjectDestroyed(target) self:ObjectDestroyed(target)
else
-- Debug message.
self:T2(self.lid..string.format("EVENT ID=%d: target %s removed ==> dead", EventData.id, tostring(target.Name)))
-- Trigger object dead event.
self:ObjectDead(target)
end end
end end
end -- Event belongs to this TARGET
end
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -474,6 +541,10 @@ function TARGET:_AddObject(Object)
local target={} --#TARGET.Object local target={} --#TARGET.Object
target.N0=0
target.Ndead=0
target.Ndestroyed=0
if Object:IsInstanceOf("GROUP") then if Object:IsInstanceOf("GROUP") then
local group=Object --Wrapper.Group#GROUP local group=Object --Wrapper.Group#GROUP
@ -496,7 +567,9 @@ function TARGET:_AddObject(Object)
self.threatlevel0=self.threatlevel0+unit:GetThreatLevel() self.threatlevel0=self.threatlevel0+unit:GetThreatLevel()
self.Ntargets0=self.Ntargets0+1 table.insert(self.elements, unit:GetName())
target.N0=target.N0+1
end end
elseif Object:IsInstanceOf("UNIT") then elseif Object:IsInstanceOf("UNIT") then
@ -514,7 +587,9 @@ function TARGET:_AddObject(Object)
self.threatlevel0=self.threatlevel0+unit:GetThreatLevel() self.threatlevel0=self.threatlevel0+unit:GetThreatLevel()
self.Ntargets0=self.Ntargets0+1 table.insert(self.elements, unit:GetName())
target.N0=target.N0+1
end end
elseif Object:IsInstanceOf("STATIC") then elseif Object:IsInstanceOf("STATIC") then
@ -527,10 +602,13 @@ function TARGET:_AddObject(Object)
target.Coordinate=static:GetCoordinate() target.Coordinate=static:GetCoordinate()
if static and static:IsAlive() then if static and static:IsAlive() then
target.Life0=1 target.Life0=1
target.Life=1 target.Life=1
target.N0=target.N0+1
table.insert(self.elements, target.Name)
self.Ntargets0=self.Ntargets0+1
end end
elseif Object:IsInstanceOf("SCENERY") then elseif Object:IsInstanceOf("SCENERY") then
@ -545,7 +623,9 @@ function TARGET:_AddObject(Object)
target.Life0=1 target.Life0=1
target.Life=1 target.Life=1
self.Ntargets0=self.Ntargets0+1 target.N0=target.N0+1
table.insert(self.elements, target.Name)
elseif Object:IsInstanceOf("AIRBASE") then elseif Object:IsInstanceOf("AIRBASE") then
@ -559,7 +639,9 @@ function TARGET:_AddObject(Object)
target.Life0=1 target.Life0=1
target.Life=1 target.Life=1
self.Ntargets0=self.Ntargets0+1 target.N0=target.N0+1
table.insert(self.elements, target.Name)
elseif Object:IsInstanceOf("COORDINATE") then elseif Object:IsInstanceOf("COORDINATE") then
@ -594,6 +676,9 @@ function TARGET:_AddObject(Object)
self.life=self.life+target.Life self.life=self.life+target.Life
self.life0=self.life0+target.Life0 self.life0=self.life0+target.Life0
self.N0=self.N0+target.N0
self.Ntargets0=self.Ntargets0+1
-- Increase counter. -- Increase counter.
self.targetcounter=self.targetcounter+1 self.targetcounter=self.targetcounter+1
@ -1009,7 +1094,7 @@ end
-- @return #number Number of alive target objects. -- @return #number Number of alive target objects.
function TARGET:CountObjectives(Target) function TARGET:CountObjectives(Target)
local N=1 local N=0
if Target.Type==TARGET.ObjectType.GROUP then if Target.Type==TARGET.ObjectType.GROUP then
@ -1028,7 +1113,7 @@ function TARGET:CountObjectives(Target)
local target=Target.Object --Wrapper.Unit#UNIT local target=Target.Object --Wrapper.Unit#UNIT
if target and target:IsAlive() and target:GetLife()>1 then if target and target:IsAlive()~=nil and target:GetLife()>1 then
N=N+1 N=N+1
end end
@ -1080,6 +1165,45 @@ function TARGET:CountTargets()
return N return N
end end
--- Check if something is an element of the TARGET.
-- @param #TARGET self
-- @param #string Name The name of the potential element.
-- @return #boolean If `true`, this name is part of this TARGET.
function TARGET:IsElement(Name)
if Name==nil then
return false
end
for _,name in pairs(self.elements) do
if name==Name then
return true
end
end
return false
end
--- Check if something is a a casualty of this TARGET.
-- @param #TARGET self
-- @param #string Name The name of the potential element.
-- @return #boolean If `true`, this name is a casualty of this TARGET.
function TARGET:IsCasualty(Name)
if Name==nil then
return false
end
for _,name in pairs(self.casualties) do
if name==Name then
return true
end
end
return false
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------