mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Ops
This commit is contained in:
parent
495a9fd3a0
commit
337e1a837f
@ -1609,6 +1609,7 @@ WAREHOUSE = {
|
|||||||
-- @field #boolean iscargo If true, asset is cargo. If false asset is transport. Nil if in stock.
|
-- @field #boolean iscargo If true, asset is cargo. If false asset is transport. Nil if in stock.
|
||||||
-- @field #number rid The request ID of this asset.
|
-- @field #number rid The request ID of this asset.
|
||||||
-- @field #boolean arrived If true, asset arrived at its destination.
|
-- @field #boolean arrived If true, asset arrived at its destination.
|
||||||
|
-- @field #number damage Damage of asset group in percent.
|
||||||
|
|
||||||
--- Item of the warehouse queue table.
|
--- Item of the warehouse queue table.
|
||||||
-- @type WAREHOUSE.Queueitem
|
-- @type WAREHOUSE.Queueitem
|
||||||
@ -3822,6 +3823,11 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu
|
|||||||
asset.iscargo=nil
|
asset.iscargo=nil
|
||||||
asset.arrived=nil
|
asset.arrived=nil
|
||||||
|
|
||||||
|
-- Destroy group if it is alive.
|
||||||
|
if group:IsAlive()==true then
|
||||||
|
asset.damage=group:GetDamage()
|
||||||
|
end
|
||||||
|
|
||||||
-- Add asset to stock.
|
-- Add asset to stock.
|
||||||
table.insert(self.stock, asset)
|
table.insert(self.stock, asset)
|
||||||
|
|
||||||
@ -3991,6 +3997,7 @@ function WAREHOUSE:_RegisterAsset(group, ngroups, forceattribute, forcecargobay,
|
|||||||
asset.skill=skill
|
asset.skill=skill
|
||||||
asset.assignment=assignment
|
asset.assignment=assignment
|
||||||
asset.spawned=false
|
asset.spawned=false
|
||||||
|
asset.damage=0
|
||||||
asset.spawngroupname=string.format("%s_AID-%d", templategroupname, asset.uid)
|
asset.spawngroupname=string.format("%s_AID-%d", templategroupname, asset.uid)
|
||||||
|
|
||||||
if i==1 then
|
if i==1 then
|
||||||
|
|||||||
@ -66,7 +66,7 @@
|
|||||||
-- At this point the airwing does not have any assets (aircraft). In order to add these, one needs to first define SQUADRONS.
|
-- At this point the airwing does not have any assets (aircraft). In order to add these, one needs to first define SQUADRONS.
|
||||||
--
|
--
|
||||||
-- VFA151=SQUADRON:New("F-14 Group", 8, "VFA-151 (Vigilantes)")
|
-- VFA151=SQUADRON:New("F-14 Group", 8, "VFA-151 (Vigilantes)")
|
||||||
-- VFA151:AddMissionCapability({AUFTRAG.Type.PATROL, AUFTRAG.Type.INTERCEPT})
|
-- VFA151:AddMissionCapability({AUFTRAG.Type.GCCAP, AUFTRAG.Type.INTERCEPT})
|
||||||
--
|
--
|
||||||
-- airwing:AddSquadron(VFA151)
|
-- airwing:AddSquadron(VFA151)
|
||||||
--
|
--
|
||||||
@ -78,8 +78,8 @@
|
|||||||
-- defined in the Mission Editor.
|
-- defined in the Mission Editor.
|
||||||
--
|
--
|
||||||
-- -- F-14 payloads for CAP and INTERCEPT. Phoenix are first, sparrows are second choice.
|
-- -- F-14 payloads for CAP and INTERCEPT. Phoenix are first, sparrows are second choice.
|
||||||
-- airwing:NewPayload(GROUP:FindByName("F-14 Payload AIM-54C"), 2, {AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.PATROL}, 80)
|
-- airwing:NewPayload(GROUP:FindByName("F-14 Payload AIM-54C"), 2, {AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.GCCAP}, 80)
|
||||||
-- airwing:NewPayload(GROUP:FindByName("F-14 Payload AIM-7M"), 20, {AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.PATROL})
|
-- airwing:NewPayload(GROUP:FindByName("F-14 Payload AIM-7M"), 20, {AUFTRAG.Type.INTERCEPT, AUFTRAG.Type.GCCAP})
|
||||||
--
|
--
|
||||||
-- This will add two AIM-54C and 20 AIM-7M payloads.
|
-- This will add two AIM-54C and 20 AIM-7M payloads.
|
||||||
--
|
--
|
||||||
@ -127,6 +127,7 @@ AIRWING = {
|
|||||||
-- @field #AIRWING.Payload payload The payload of the asset.
|
-- @field #AIRWING.Payload payload The payload of the asset.
|
||||||
-- @field Ops.FlightGroup#FLIGHTGROUP flightgroup The flightgroup object.
|
-- @field Ops.FlightGroup#FLIGHTGROUP flightgroup The flightgroup object.
|
||||||
-- @field #string squadname Name of the squadron this asset belongs to.
|
-- @field #string squadname Name of the squadron this asset belongs to.
|
||||||
|
-- @field #number Treturned Time stamp when asset returned to the airwing.
|
||||||
-- @extends Functional.Warehouse#WAREHOUSE.Assetitem
|
-- @extends Functional.Warehouse#WAREHOUSE.Assetitem
|
||||||
|
|
||||||
--- Payload data.
|
--- Payload data.
|
||||||
@ -284,26 +285,32 @@ function AIRWING:NewPayload(Unit, Npayloads, MissionTypes, Performance)
|
|||||||
Performance=Performance or 50
|
Performance=Performance or 50
|
||||||
|
|
||||||
if type(Unit)=="string" then
|
if type(Unit)=="string" then
|
||||||
Unit=UNIT:FindByName(Unit)
|
local name=Unit
|
||||||
|
env.info("unit as string "..Unit)
|
||||||
|
Unit=UNIT:FindByName(name)
|
||||||
if not Unit then
|
if not Unit then
|
||||||
Unit=GROUP:FindByName(Unit)
|
env.info("no UNIT trying group")
|
||||||
|
Unit=GROUP:FindByName(name)
|
||||||
|
if not Unit then
|
||||||
|
env.info("no GROUP either!")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If a GROUP object was given, get the first unit.
|
|
||||||
if Unit:IsInstanceOf("GROUP") then
|
|
||||||
Unit=Unit:GetUnit(1)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Ensure Missiontypes is a table.
|
|
||||||
if MissionTypes and type(MissionTypes)~="table" then
|
|
||||||
MissionTypes={MissionTypes}
|
|
||||||
end
|
|
||||||
|
|
||||||
if Unit then
|
if Unit then
|
||||||
|
|
||||||
local payload={} --#AIRWING.Payload
|
-- If a GROUP object was given, get the first unit.
|
||||||
|
if Unit:IsInstanceOf("GROUP") then
|
||||||
|
Unit=Unit:GetUnit(1)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Ensure Missiontypes is a table.
|
||||||
|
if MissionTypes and type(MissionTypes)~="table" then
|
||||||
|
MissionTypes={MissionTypes}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create payload.
|
||||||
|
local payload={} --#AIRWING.Payload
|
||||||
payload.unitname=Unit:GetName()
|
payload.unitname=Unit:GetName()
|
||||||
payload.aircrafttype=Unit:GetTypeName()
|
payload.aircrafttype=Unit:GetTypeName()
|
||||||
payload.pylons=Unit:GetTemplatePayload()
|
payload.pylons=Unit:GetTemplatePayload()
|
||||||
@ -338,8 +345,10 @@ function AIRWING:NewPayload(Unit, Npayloads, MissionTypes, Performance)
|
|||||||
table.insert(self.payloads, payload)
|
table.insert(self.payloads, payload)
|
||||||
|
|
||||||
return payload
|
return payload
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:E(self.lid.."ERROR: No UNIT found to create PAYLOAD!")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -771,7 +780,7 @@ function AIRWING:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
-- General info:
|
-- General info:
|
||||||
-- TODO: assets total
|
-- TODO: assets total
|
||||||
local text=string.format("Status %s: missions=%d, payloads=%d (%d), squads=%d", fsmstate, nmissions, #self.payloads, Npayloads, #self.squadrons)
|
local text=string.format("%s: Missions=%d, Payloads=%d (%d), Squads=%d", fsmstate, nmissions, Npayloads, #self.payloads, #self.squadrons)
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
|
|
||||||
------------------
|
------------------
|
||||||
@ -898,7 +907,7 @@ end
|
|||||||
-- @return #AIRWING self
|
-- @return #AIRWING self
|
||||||
function AIRWING:CheckCAP()
|
function AIRWING:CheckCAP()
|
||||||
|
|
||||||
local Ncap=self:CountMissionsInQueue({AUFTRAG.Type.PATROL, AUFTRAG.Type.INTERCEPT})
|
local Ncap=self:CountMissionsInQueue({AUFTRAG.Type.GCCAP, AUFTRAG.Type.INTERCEPT})
|
||||||
|
|
||||||
for i=1,self.nflightsCAP-Ncap do
|
for i=1,self.nflightsCAP-Ncap do
|
||||||
|
|
||||||
@ -906,7 +915,7 @@ function AIRWING:CheckCAP()
|
|||||||
|
|
||||||
local altitude=patrol.altitude+1000*patrol.noccupied
|
local altitude=patrol.altitude+1000*patrol.noccupied
|
||||||
|
|
||||||
local missionCAP=AUFTRAG:NewPATROL(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg)
|
local missionCAP=AUFTRAG:NewGCCAP(patrol.coord, altitude, patrol.speed, patrol.heading, patrol.leg)
|
||||||
|
|
||||||
missionCAP.patroldata=patrol
|
missionCAP.patroldata=patrol
|
||||||
|
|
||||||
@ -1068,7 +1077,7 @@ function AIRWING:GetTankerForFlight(flightgroup)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get next mission.
|
--- Check if mission is not over and ready to cancel.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
function AIRWING:_CheckMissions()
|
function AIRWING:_CheckMissions()
|
||||||
|
|
||||||
@ -1076,12 +1085,8 @@ function AIRWING:_CheckMissions()
|
|||||||
for _,_mission in pairs(self.missionqueue) do
|
for _,_mission in pairs(self.missionqueue) do
|
||||||
local mission=_mission --Ops.Auftrag#AUFTRAG
|
local mission=_mission --Ops.Auftrag#AUFTRAG
|
||||||
|
|
||||||
if mission:IsNotOver() then
|
if mission:IsNotOver() and mission:IsReadyToCancel() then
|
||||||
|
mission:Cancel()
|
||||||
if mission:IsReadyToCancel() then
|
|
||||||
mission:Cancel()
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1157,7 +1162,7 @@ function AIRWING:_GetNextMission()
|
|||||||
|
|
||||||
-- Another check.
|
-- Another check.
|
||||||
if #assets<mission.nassets then
|
if #assets<mission.nassets then
|
||||||
self:E(self.lid..string.format("ERROR: Not enought payloads for mission assets! Can only do %d/%d", #assets, mission.nassets))
|
self:E(self.lid..string.format("ERROR: Not enough payloads for mission assets! Can only do %d/%d", #assets, mission.nassets))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Optimize the asset selection. Now we include the payload performance as this could change the result.
|
-- Optimize the asset selection. Now we include the payload performance as this could change the result.
|
||||||
@ -1424,7 +1429,7 @@ end
|
|||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
-- @param Functional.Warehouse#WAREHOUSE.Assetitem asset The asset that has just been added.
|
-- @param #AIRWING.SquadronAsset asset The asset that has just been added.
|
||||||
-- @param #string assignment The (optional) assignment for the asset.
|
-- @param #string assignment The (optional) assignment for the asset.
|
||||||
function AIRWING:onafterNewAsset(From, Event, To, asset, assignment)
|
function AIRWING:onafterNewAsset(From, Event, To, asset, assignment)
|
||||||
|
|
||||||
@ -1487,6 +1492,9 @@ function AIRWING:onafterNewAsset(From, Event, To, asset, assignment)
|
|||||||
self:I(self.lid..string.format("Asset %s from squadron %s returned! asset.assignment=\"%s\", assignment=\"%s\"", asset.spawngroupname, squad.name, tostring(asset.assignment), tostring(assignment)))
|
self:I(self.lid..string.format("Asset %s from squadron %s returned! asset.assignment=\"%s\", assignment=\"%s\"", asset.spawngroupname, squad.name, tostring(asset.assignment), tostring(assignment)))
|
||||||
self:ReturnPayloadFromAsset(asset)
|
self:ReturnPayloadFromAsset(asset)
|
||||||
|
|
||||||
|
-- Set timestamp.
|
||||||
|
asset.Treturned=timer.getAbsTime()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1545,8 +1553,8 @@ function AIRWING:onafterAssetSpawned(From, Event, To, group, asset, request)
|
|||||||
-- Add mission to flightgroup queue.
|
-- Add mission to flightgroup queue.
|
||||||
if mission then
|
if mission then
|
||||||
|
|
||||||
-- RTB on low fuel if on PATROL.
|
-- RTB on low fuel if on GCCAP.
|
||||||
if mission.type==AUFTRAG.Type.PATROL then
|
if mission.type==AUFTRAG.Type.GCCAP then
|
||||||
flightgroup:SetFuelLowThreshold(nil, true)
|
flightgroup:SetFuelLowThreshold(nil, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -1787,6 +1795,12 @@ end
|
|||||||
-- @return #number Count of available payloads in stock.
|
-- @return #number Count of available payloads in stock.
|
||||||
function AIRWING:CountPayloadsInStock(MissionTypes, UnitTypes)
|
function AIRWING:CountPayloadsInStock(MissionTypes, UnitTypes)
|
||||||
|
|
||||||
|
if MissionTypes then
|
||||||
|
if type(MissionTypes)=="string" then
|
||||||
|
MissionTypes={MissionTypes}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if UnitTypes then
|
if UnitTypes then
|
||||||
if type(UnitTypes)=="string" then
|
if type(UnitTypes)=="string" then
|
||||||
UnitTypes={UnitTypes}
|
UnitTypes={UnitTypes}
|
||||||
@ -1811,17 +1825,20 @@ function AIRWING:CountPayloadsInStock(MissionTypes, UnitTypes)
|
|||||||
for _,_payload in pairs(self.payloads) do
|
for _,_payload in pairs(self.payloads) do
|
||||||
local payload=_payload --#AIRWING.Payload
|
local payload=_payload --#AIRWING.Payload
|
||||||
|
|
||||||
if self:CheckMissionCapability(MissionTypes, payload.capabilities) and _checkUnitTypes(payload) then
|
for _,MissionType in pairs(MissionTypes) do
|
||||||
|
|
||||||
|
if self:CheckMissionCapability(MissionType, payload.capabilities) and _checkUnitTypes(payload) then
|
||||||
|
|
||||||
|
if payload.unlimited then
|
||||||
|
-- Payload is unlimited. Return a BIG number.
|
||||||
|
return 999
|
||||||
|
else
|
||||||
|
n=n+payload.navail
|
||||||
|
end
|
||||||
|
|
||||||
if payload.unlimited then
|
|
||||||
-- Payload is unlimited. Return a BIG number.
|
|
||||||
return 999
|
|
||||||
else
|
|
||||||
n=n+payload.navail
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return n
|
return n
|
||||||
@ -1911,14 +1928,6 @@ function AIRWING:GetAssetsOnMission(MissionTypes, IncludeQueued)
|
|||||||
return assets
|
return assets
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Check
|
|
||||||
-- @param #AIRWING self
|
|
||||||
-- @param #boolean onlyactive Count only the active ones.
|
|
||||||
-- @return #table Table of unit types.
|
|
||||||
function AIRWING:_CheckSquads(onlyactive)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get the aircraft types of this airwing.
|
--- Get the aircraft types of this airwing.
|
||||||
-- @param #AIRWING self
|
-- @param #AIRWING self
|
||||||
-- @param #boolean onlyactive Count only the active ones.
|
-- @param #boolean onlyactive Count only the active ones.
|
||||||
@ -2003,18 +2012,6 @@ function AIRWING:CanMission(Mission)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Payloads are not fetched from stock any more.
|
|
||||||
--[[
|
|
||||||
-- Now clear all reserved payloads.
|
|
||||||
for _,_asset in pairs(Assets) do
|
|
||||||
local asset=_asset --#AIRWING.SquadronAsset
|
|
||||||
-- Only unspawned payloads are returned.
|
|
||||||
if not asset.spawned and not asset.requested then
|
|
||||||
self:ReturnPayloadFromAsset(asset)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
]]
|
|
||||||
|
|
||||||
-- Check if required assets are present.
|
-- Check if required assets are present.
|
||||||
if Mission.nassets and Mission.nassets > #Assets then
|
if Mission.nassets and Mission.nassets > #Assets then
|
||||||
self:I(self.lid..string.format("INFO: Not enough assets available! Got %d but need at least %d", #Assets, Mission.nassets))
|
self:I(self.lid..string.format("INFO: Not enough assets available! Got %d but need at least %d", #Assets, Mission.nassets))
|
||||||
|
|||||||
@ -51,7 +51,7 @@
|
|||||||
-- @field #number orbitLeg Length of orbit leg in meters.
|
-- @field #number orbitLeg Length of orbit leg in meters.
|
||||||
-- @field Core.Point#COORDINATE orbitRaceTrack Race-track orbit coordinate.
|
-- @field Core.Point#COORDINATE orbitRaceTrack Race-track orbit coordinate.
|
||||||
--
|
--
|
||||||
-- @field #AUFTRAG.TargetData engageTarget Target data to engage.
|
-- @field Ops.Target#TARGET engageTarget Target data to engage.
|
||||||
--
|
--
|
||||||
-- @field Core.Zone#ZONE_RADIUS engageZone *Circular* engagement zone.
|
-- @field Core.Zone#ZONE_RADIUS engageZone *Circular* engagement zone.
|
||||||
-- @field #table engageTargetTypes Table of target types that are engaged in the engagement zone.
|
-- @field #table engageTargetTypes Table of target types that are engaged in the engagement zone.
|
||||||
@ -98,11 +98,6 @@
|
|||||||
-- @field #number missionRepeated Number of times mission was repeated.
|
-- @field #number missionRepeated Number of times mission was repeated.
|
||||||
-- @field #number missionRepeatMax Number of times mission is repeated if failed.
|
-- @field #number missionRepeatMax Number of times mission is repeated if failed.
|
||||||
--
|
--
|
||||||
-- @field #number radioFreq Mission radio frequency in MHz.
|
|
||||||
-- @field #number radioModu Mission radio modulation (0=AM and 1=FM).
|
|
||||||
-- @field #number tacanChannel Mission TACAN channel.
|
|
||||||
-- @field #number tacanMorse Mission TACAN morse code.
|
|
||||||
--
|
|
||||||
-- @field Ops.OpsGroup#OPSGROUP.Radio radio Radio freq and modulation.
|
-- @field Ops.OpsGroup#OPSGROUP.Radio radio Radio freq and modulation.
|
||||||
-- @field Ops.OpsGroup#OPSGROUP.Beacon tacan TACAN setting.
|
-- @field Ops.OpsGroup#OPSGROUP.Beacon tacan TACAN setting.
|
||||||
-- @field Ops.OpsGroup#OPSGROUP.Beacon icls ICLS setting.
|
-- @field Ops.OpsGroup#OPSGROUP.Beacon icls ICLS setting.
|
||||||
@ -188,9 +183,9 @@
|
|||||||
--
|
--
|
||||||
-- An orbit mission can be created with the @{#AUFTRAG.NewORBIT}() function.
|
-- An orbit mission can be created with the @{#AUFTRAG.NewORBIT}() function.
|
||||||
--
|
--
|
||||||
-- ## PATROL
|
-- ## GCCAP
|
||||||
--
|
--
|
||||||
-- An patrol mission can be created with the @{#AUFTRAG.NewPATROL}() function.
|
-- An patrol mission can be created with the @{#AUFTRAG.NewGCCAP}() function.
|
||||||
--
|
--
|
||||||
-- ## RECON
|
-- ## RECON
|
||||||
--
|
--
|
||||||
@ -293,7 +288,7 @@ _AUFTRAGSNR=0
|
|||||||
-- @field #string FERRY Ferry flight mission.
|
-- @field #string FERRY Ferry flight mission.
|
||||||
-- @field #string INTERCEPT Intercept mission.
|
-- @field #string INTERCEPT Intercept mission.
|
||||||
-- @field #string ORBIT Orbit mission.
|
-- @field #string ORBIT Orbit mission.
|
||||||
-- @field #string PATROL Similar to CAP but no auto engage targets.
|
-- @field #string GCCAP Similar to CAP but no auto engage targets.
|
||||||
-- @field #string RECON Recon mission.
|
-- @field #string RECON Recon mission.
|
||||||
-- @field #string RECOVERYTANKER Recovery tanker mission. Not implemented yet.
|
-- @field #string RECOVERYTANKER Recovery tanker mission. Not implemented yet.
|
||||||
-- @field #string RESCUEHELO Rescue helo.
|
-- @field #string RESCUEHELO Rescue helo.
|
||||||
@ -316,7 +311,7 @@ AUFTRAG.Type={
|
|||||||
FERRY="Ferry Flight",
|
FERRY="Ferry Flight",
|
||||||
INTERCEPT="Intercept",
|
INTERCEPT="Intercept",
|
||||||
ORBIT="Orbit",
|
ORBIT="Orbit",
|
||||||
PATROL="Patrol",
|
GCCAP="Patrol",
|
||||||
RECON="Recon",
|
RECON="Recon",
|
||||||
RECOVERYTANKER="Recovery Tanker",
|
RECOVERYTANKER="Recovery Tanker",
|
||||||
RESCUEHELO="Rescue Helo",
|
RESCUEHELO="Rescue Helo",
|
||||||
@ -632,7 +627,7 @@ function AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
|
|||||||
return mission
|
return mission
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create a PATROL mission.
|
--- Create a GCCAP mission.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param Core.Point#COORDINATE Coordinate Where to orbit.
|
-- @param Core.Point#COORDINATE Coordinate Where to orbit.
|
||||||
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
|
-- @param #number Altitude Orbit altitude in feet. Default is y component of `Coordinate`.
|
||||||
@ -640,13 +635,13 @@ end
|
|||||||
-- @param #number Heading Heading of race-track pattern in degrees. Default random in [0, 360) degrees.
|
-- @param #number Heading Heading of race-track pattern in degrees. Default random in [0, 360) degrees.
|
||||||
-- @param #number Leg Length of race-track in NM. Default 10 NM.
|
-- @param #number Leg Length of race-track in NM. Default 10 NM.
|
||||||
-- @return #AUFTRAG self
|
-- @return #AUFTRAG self
|
||||||
function AUFTRAG:NewPATROL(Coordinate, Altitude, Speed, Heading, Leg)
|
function AUFTRAG:NewGCCAP(Coordinate, Altitude, Speed, Heading, Leg)
|
||||||
|
|
||||||
-- Create ORBIT first.
|
-- Create ORBIT first.
|
||||||
local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
|
local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
|
||||||
|
|
||||||
-- Mission type PATROL.
|
-- Mission type GCCAP.
|
||||||
mission.type=AUFTRAG.Type.PATROL
|
mission.type=AUFTRAG.Type.GCCAP
|
||||||
|
|
||||||
mission:_SetLogID()
|
mission:_SetLogID()
|
||||||
|
|
||||||
@ -671,7 +666,7 @@ function AUFTRAG:NewTANKER(Coordinate, Altitude, Speed, Heading, Leg, RefuelSyst
|
|||||||
-- Create ORBIT first.
|
-- Create ORBIT first.
|
||||||
local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
|
local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
|
||||||
|
|
||||||
-- Mission type PATROL.
|
-- Mission type TANKER.
|
||||||
mission.type=AUFTRAG.Type.TANKER
|
mission.type=AUFTRAG.Type.TANKER
|
||||||
|
|
||||||
mission:_SetLogID()
|
mission:_SetLogID()
|
||||||
@ -701,7 +696,7 @@ function AUFTRAG:NewAWACS(Coordinate, Altitude, Speed, Heading, Leg)
|
|||||||
-- Create ORBIT first.
|
-- Create ORBIT first.
|
||||||
local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
|
local mission=AUFTRAG:NewORBIT_RACETRACK(Coordinate, Altitude, Speed, Heading, Leg)
|
||||||
|
|
||||||
-- Mission type PATROL.
|
-- Mission type AWACS.
|
||||||
mission.type=AUFTRAG.Type.AWACS
|
mission.type=AUFTRAG.Type.AWACS
|
||||||
|
|
||||||
mission:_SetLogID()
|
mission:_SetLogID()
|
||||||
@ -1082,7 +1077,7 @@ function AUFTRAG:NewRESCUEHELO(Carrier)
|
|||||||
|
|
||||||
local mission=AUFTRAG:New(AUFTRAG.Type.RESCUEHELO)
|
local mission=AUFTRAG:New(AUFTRAG.Type.RESCUEHELO)
|
||||||
|
|
||||||
mission:_TargetFromObject(Carrier)
|
self.carrier=Carrier
|
||||||
|
|
||||||
-- Mission options:
|
-- Mission options:
|
||||||
mission.missionTask=ENUMS.MissionTask.NOTHING
|
mission.missionTask=ENUMS.MissionTask.NOTHING
|
||||||
@ -1157,6 +1152,31 @@ function AUFTRAG:NewARTY(Target, Nshots, Radius)
|
|||||||
return mission
|
return mission
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Create a mission to attack a group. Mission type is automatically chosen from the group category.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param Ops.Target#TARGET Target The target.
|
||||||
|
-- @return #AUFTRAG self
|
||||||
|
function AUFTRAG:NewTARGET(Target)
|
||||||
|
|
||||||
|
local mission=nil --#AUFTRAG
|
||||||
|
|
||||||
|
if Target.category==TARGET.Category.GROUND then
|
||||||
|
|
||||||
|
|
||||||
|
elseif Target.category==TARGET.Category.AIRCRAFT then
|
||||||
|
|
||||||
|
elseif Target.category==TARGET.Category.AIRBASE then
|
||||||
|
|
||||||
|
elseif Target.category==TARGET.Category.COORDINATE then
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if mission then
|
||||||
|
mission:SetPriority(10, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Create a mission to attack a group. Mission type is automatically chosen from the group category.
|
--- Create a mission to attack a group. Mission type is automatically chosen from the group category.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
@ -1882,12 +1902,6 @@ function AUFTRAG:Evaluate()
|
|||||||
-- Assume success and check if any failed condition applies.
|
-- Assume success and check if any failed condition applies.
|
||||||
local failed=false
|
local failed=false
|
||||||
|
|
||||||
-- Any success condition true?
|
|
||||||
local successCondition=self:EvalConditionsAny(self.conditionSuccess)
|
|
||||||
|
|
||||||
-- Any failure condition true?
|
|
||||||
local failureCondition=self:EvalConditionsAny(self.conditionFailure)
|
|
||||||
|
|
||||||
-- Target damage in %.
|
-- Target damage in %.
|
||||||
local targetdamage=self:GetTargetDamage()
|
local targetdamage=self:GetTargetDamage()
|
||||||
|
|
||||||
@ -1931,6 +1945,13 @@ function AUFTRAG:Evaluate()
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Any success condition true?
|
||||||
|
local successCondition=self:EvalConditionsAny(self.conditionSuccess)
|
||||||
|
|
||||||
|
-- Any failure condition true?
|
||||||
|
local failureCondition=self:EvalConditionsAny(self.conditionFailure)
|
||||||
|
|
||||||
if failureCondition then
|
if failureCondition then
|
||||||
failed=true
|
failed=true
|
||||||
elseif successCondition then
|
elseif successCondition then
|
||||||
@ -2217,8 +2238,7 @@ end
|
|||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
-- @param #string Event Event.
|
-- @param #string Event Event.
|
||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
-- @param Ops.OpsGroup#OPSGROUP FlightGroup
|
function AUFTRAG:onafterScheduled(From, Event, To)
|
||||||
function AUFTRAG:onafterScheduled(From, Event, To, FlightGroup)
|
|
||||||
self.status=AUFTRAG.Status.SCHEDULED
|
self.status=AUFTRAG.Status.SCHEDULED
|
||||||
self:T(self.lid..string.format("New mission status=%s", self.status))
|
self:T(self.lid..string.format("New mission status=%s", self.status))
|
||||||
end
|
end
|
||||||
@ -2264,6 +2284,7 @@ end
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
-- @param Ops.OpsGroup#OPSGROUP OpsGroup The ops group that is dead now.
|
-- @param Ops.OpsGroup#OPSGROUP OpsGroup The ops group that is dead now.
|
||||||
function AUFTRAG:onafterElementDestroyed(From, Event, To, OpsGroup, Element)
|
function AUFTRAG:onafterElementDestroyed(From, Event, To, OpsGroup, Element)
|
||||||
|
-- Increase number of own casualties.
|
||||||
self.Ncasualties=self.Ncasualties+1
|
self.Ncasualties=self.Ncasualties+1
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2499,6 +2520,170 @@ function AUFTRAG:onafterStop(From, Event, To)
|
|||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
-- Target Functions
|
||||||
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Create target data from a given object.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param Wrapper.Positionable#POSITIONABLE Object The target GROUP, UNIT, STATIC.
|
||||||
|
function AUFTRAG:_TargetFromObject(Object)
|
||||||
|
|
||||||
|
if not self.engageTarget then
|
||||||
|
|
||||||
|
self.engageTarget=TARGET:New(Object)
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
-- Target was already specified elsewhere.
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: get rid of this.
|
||||||
|
self.Ntargets=self.engageTarget.Ntargets0
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
self:T(self.lid..string.format("Mission Target %s Type=%s, Ntargets=%d, Lifepoints=%d", self.engageTarget.lid, self.engageTarget.lid, self.Ntargets, self.engageTarget:GetLife()))
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Count alive mission targets.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param #AUFTRAG.TargetData Target (Optional) The target object.
|
||||||
|
-- @return #number Number of alive target units.
|
||||||
|
function AUFTRAG:CountMissionTargets(Target)
|
||||||
|
|
||||||
|
if self.engageTarget then
|
||||||
|
return self.engageTarget:CountTargets()
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get target life points.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return #number Number of initial life points when mission was planned.
|
||||||
|
function AUFTRAG:GetTargetInitialLife()
|
||||||
|
local target=self:GetTargetData()
|
||||||
|
if target then
|
||||||
|
return target.life0
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get target damage.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return #number Damage in percent.
|
||||||
|
function AUFTRAG:GetTargetDamage()
|
||||||
|
local target=self:GetTargetData()
|
||||||
|
if target then
|
||||||
|
return target:GetDamage()
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get target life points.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return #number Life points of target.
|
||||||
|
function AUFTRAG:GetTargetLife()
|
||||||
|
local target=self:GetTargetData()
|
||||||
|
if target then
|
||||||
|
return target:GetLife()
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get target.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return Ops.Target#TARGET The target object. Could be many things.
|
||||||
|
function AUFTRAG:GetTargetData()
|
||||||
|
return self.engageTarget
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get mission objective object. Could be many things depending on the mission type.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return Wrapper.Positionable#POSITIONABLE The target object. Could be many things.
|
||||||
|
function AUFTRAG:GetObjective()
|
||||||
|
return self:GetTargetData().Target
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get type of target.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return #string The target type.
|
||||||
|
function AUFTRAG:GetTargetType()
|
||||||
|
return self:GetTargetData().Type
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get 2D vector of target.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return DCS#VEC2 The target 2D vector or *nil*.
|
||||||
|
function AUFTRAG:GetTargetVec2()
|
||||||
|
local coord=self:GetTargetCoordinate()
|
||||||
|
if coord then
|
||||||
|
return coord:GetVec2()
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get coordinate of target.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return Core.Point#COORDINATE The target coordinate or *nil*.
|
||||||
|
function AUFTRAG:GetTargetCoordinate()
|
||||||
|
|
||||||
|
if self.transportPickup then
|
||||||
|
|
||||||
|
-- Special case where we defined a
|
||||||
|
return self.transportPickup
|
||||||
|
|
||||||
|
elseif self.engageTarget then
|
||||||
|
|
||||||
|
return self.engageTarget:GetCoordinate()
|
||||||
|
|
||||||
|
else
|
||||||
|
self:E(self.lid.."ERROR: Cannot get target coordinate!")
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get name of the target.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @return #string Name of the target or "N/A".
|
||||||
|
function AUFTRAG:GetTargetName()
|
||||||
|
|
||||||
|
if self.engageTarget.Target then
|
||||||
|
return self.engageTarget.Name
|
||||||
|
end
|
||||||
|
|
||||||
|
return "N/A"
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get distance to target.
|
||||||
|
-- @param #AUFTRAG self
|
||||||
|
-- @param Core.Point#COORDINATE FromCoord The coordinate from which the distance is measured.
|
||||||
|
-- @return #number Distance in meters or 0.
|
||||||
|
function AUFTRAG:GetTargetDistance(FromCoord)
|
||||||
|
|
||||||
|
local TargetCoord=self:GetTargetCoordinate()
|
||||||
|
|
||||||
|
if TargetCoord and FromCoord then
|
||||||
|
return TargetCoord:Get2DDistance(FromCoord)
|
||||||
|
else
|
||||||
|
self:E(self.lid.."ERROR: TargetCoord or FromCoord does not exist in AUFTRAG:GetTargetDistance() function! Returning 0")
|
||||||
|
end
|
||||||
|
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Misc Functions
|
-- Misc Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -2554,229 +2739,6 @@ function AUFTRAG:GetAssetByName(Name)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Count alive mission targets.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @param #AUFTRAG.TargetData Target (Optional) The target object.
|
|
||||||
-- @return #number Number of alive target units.
|
|
||||||
function AUFTRAG:CountMissionTargets(Target)
|
|
||||||
|
|
||||||
local N=0
|
|
||||||
|
|
||||||
Target=Target or self:GetTargetData()
|
|
||||||
|
|
||||||
if Target then
|
|
||||||
|
|
||||||
if Target.Type==AUFTRAG.TargetType.GROUP then
|
|
||||||
|
|
||||||
local target=Target.Target --Wrapper.Group#GROUP
|
|
||||||
|
|
||||||
local units=target:GetUnits()
|
|
||||||
|
|
||||||
for _,_unit in pairs(units or {}) do
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
-- We check that unit is "alive" and has health >1. Somtimes units get heavily damanged but are still alive.
|
|
||||||
-- TODO: here I could introduce and count that if units have only health < 50% if mission objective is to just "damage" the units.
|
|
||||||
if unit and unit:IsAlive() and unit:GetLife()>1 then
|
|
||||||
N=N+1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.UNIT then
|
|
||||||
|
|
||||||
local target=Target.Target --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
if target and target:IsAlive() and target:GetLife()>1 then
|
|
||||||
N=N+1
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.STATIC then
|
|
||||||
|
|
||||||
local target=Target.Target --Wrapper.Static#STATIC
|
|
||||||
|
|
||||||
if target and target:IsAlive() then
|
|
||||||
N=N+1
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.AIRBASE then
|
|
||||||
|
|
||||||
-- TODO: any (good) way to tell whether an airbase was "destroyed" or at least damaged? Is :GetLive() working?
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.COORDINATE then
|
|
||||||
|
|
||||||
-- No target!
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.SETGROUP then
|
|
||||||
|
|
||||||
for _,_group in pairs(Target.Target.Set or {}) do
|
|
||||||
local group=_group --Wrapper.Group#GROUP
|
|
||||||
|
|
||||||
local units=group:GetUnits()
|
|
||||||
|
|
||||||
for _,_unit in pairs(units or {}) do
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
-- We check that unit is "alive".
|
|
||||||
if unit and unit:IsAlive() and unit:GetLife()>1 then
|
|
||||||
N=N+1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.SETUNIT then
|
|
||||||
|
|
||||||
for _,_unit in pairs(Target.Target.Set or {}) do
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
-- We check that unit is "alive".
|
|
||||||
if unit and unit:IsAlive() and unit:GetLife()>1 then
|
|
||||||
N=N+1
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
self:E("ERROR unknown target type")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return N
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get target life points.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return #number Number of initial life points when mission was planned.
|
|
||||||
function AUFTRAG:GetTargetInitialLife()
|
|
||||||
return self:GetTargetData().Lifepoints
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get target damage.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return #number Damage in percent.
|
|
||||||
function AUFTRAG:GetTargetDamage()
|
|
||||||
local target=self:GetTargetData()
|
|
||||||
local life=self:GetTargetLife()/self:GetTargetInitialLife()
|
|
||||||
local damage=1-life
|
|
||||||
return damage*100
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Get target life points.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return #number Life points of target.
|
|
||||||
function AUFTRAG:GetTargetLife()
|
|
||||||
return self:_GetTargetLife(nil, false)
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get target life points.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @param #AUFTRAG.TargetData Target (Optional) The target object.
|
|
||||||
-- @param #boolean Healthy Get the life points of the healthy target.
|
|
||||||
-- @return #number Life points of target.
|
|
||||||
function AUFTRAG:_GetTargetLife(Target, Healthy)
|
|
||||||
|
|
||||||
local N=0
|
|
||||||
|
|
||||||
Target=Target or self:GetTargetData()
|
|
||||||
|
|
||||||
local function _GetLife(unit)
|
|
||||||
local unit=unit --Wrapper.Unit#UNIT
|
|
||||||
if Healthy then
|
|
||||||
local life=unit:GetLife()
|
|
||||||
local life0=unit:GetLife0()
|
|
||||||
|
|
||||||
return math.max(life, life0)
|
|
||||||
else
|
|
||||||
return unit:GetLife()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if Target then
|
|
||||||
|
|
||||||
if Target.Type==AUFTRAG.TargetType.GROUP then
|
|
||||||
|
|
||||||
local target=Target.Target --Wrapper.Group#GROUP
|
|
||||||
|
|
||||||
local units=target:GetUnits()
|
|
||||||
|
|
||||||
for _,_unit in pairs(units or {}) do
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
-- We check that unit is "alive".
|
|
||||||
if unit and unit:IsAlive() then
|
|
||||||
N=N+_GetLife(unit)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.UNIT then
|
|
||||||
|
|
||||||
local target=Target.Target --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
if target and target:IsAlive() then
|
|
||||||
N=N+_GetLife(target)
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.STATIC then
|
|
||||||
|
|
||||||
local target=Target.Target --Wrapper.Static#STATIC
|
|
||||||
|
|
||||||
-- Statics are alive or not.
|
|
||||||
if target and target:IsAlive() then
|
|
||||||
N=N+1 --_GetLife(target)
|
|
||||||
else
|
|
||||||
N=N+0
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.AIRBASE then
|
|
||||||
|
|
||||||
-- TODO: any (good) way to tell whether an airbase was "destroyed" or at least damaged? Is :GetLive() working?
|
|
||||||
N=N+1
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.COORDINATE then
|
|
||||||
|
|
||||||
-- A coordinate does not live.
|
|
||||||
N=N+1
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.SETGROUP then
|
|
||||||
|
|
||||||
for _,_group in pairs(Target.Target.Set or {}) do
|
|
||||||
local group=_group --Wrapper.Group#GROUP
|
|
||||||
|
|
||||||
local units=group:GetUnits()
|
|
||||||
|
|
||||||
for _,_unit in pairs(units or {}) do
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
-- We check that unit is "alive".
|
|
||||||
if unit and unit:IsAlive() then
|
|
||||||
N=N+_GetLife(unit)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Target.Type==AUFTRAG.TargetType.SETUNIT then
|
|
||||||
|
|
||||||
for _,_unit in pairs(Target.Target.Set or {}) do
|
|
||||||
local unit=_unit --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
-- We check that unit is "alive".
|
|
||||||
if unit and unit:IsAlive() then
|
|
||||||
N=N+_GetLife(unit)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
self:E(self.lid.."ERROR unknown target type")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return N
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Count alive flight groups assigned for this mission.
|
--- Count alive flight groups assigned for this mission.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @return #number Number of alive flight groups.
|
-- @return #number Number of alive flight groups.
|
||||||
@ -2791,109 +2753,6 @@ function AUFTRAG:CountOpsGroups()
|
|||||||
return N
|
return N
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Get coordinate of target.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return #AUFTRAG.TargetData The target object. Could be many things.
|
|
||||||
function AUFTRAG:GetTargetData()
|
|
||||||
return self.engageTarget
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get mission objective object. Could be many things depending on the mission type.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return Wrapper.Positionable#POSITIONABLE The target object. Could be many things.
|
|
||||||
function AUFTRAG:GetObjective()
|
|
||||||
return self:GetTargetData().Target
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get type of target.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return #string The target type.
|
|
||||||
function AUFTRAG:GetTargetType()
|
|
||||||
return self:GetTargetData().Type
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get 2D vector of target.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return DCS#VEC2 The target 2D vector or *nil*.
|
|
||||||
function AUFTRAG:GetTargetVec2()
|
|
||||||
local coord=self:GetTargetCoordinate()
|
|
||||||
if coord then
|
|
||||||
return coord:GetVec2()
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get coordinate of target.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return Core.Point#COORDINATE The target coordinate or *nil*.
|
|
||||||
function AUFTRAG:GetTargetCoordinate()
|
|
||||||
|
|
||||||
if self.transportPickup then
|
|
||||||
|
|
||||||
-- Special case where we defined a
|
|
||||||
return self.transportPickup
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
local target
|
|
||||||
|
|
||||||
if self:GetTargetType()==AUFTRAG.TargetType.COORDINATE then
|
|
||||||
|
|
||||||
-- Here the objective itself is a COORDINATE.
|
|
||||||
return self:GetObjective()
|
|
||||||
|
|
||||||
elseif self:GetTargetType()==AUFTRAG.TargetType.SETGROUP then
|
|
||||||
|
|
||||||
-- Return the first group in the set.
|
|
||||||
-- TODO: does this only return ALIVE groups?!
|
|
||||||
return self:GetObjective():GetFirst():GetCoordinate()
|
|
||||||
|
|
||||||
elseif self:GetTargetType()==AUFTRAG.TargetType.SETUNIT then
|
|
||||||
|
|
||||||
-- Return the first unit in the set.
|
|
||||||
-- TODO: does this only return ALIVE units?!
|
|
||||||
return self:GetObjective():GetFirst():GetCoordinate()
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
-- In all other cases the GetCoordinate() function should work.
|
|
||||||
return self:GetObjective():GetCoordinate()
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get name of the target.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @return #string Name of the target or "N/A".
|
|
||||||
function AUFTRAG:GetTargetName()
|
|
||||||
|
|
||||||
if self.engageTarget.Target then
|
|
||||||
return self.engageTarget.Name
|
|
||||||
end
|
|
||||||
|
|
||||||
return "N/A"
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--- Get distance to target.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @param Core.Point#COORDINATE FromCoord The coordinate from which the distance is measured.
|
|
||||||
-- @return #number Distance in meters or 0.
|
|
||||||
function AUFTRAG:GetTargetDistance(FromCoord)
|
|
||||||
|
|
||||||
local TargetCoord=self:GetTargetCoordinate()
|
|
||||||
|
|
||||||
if TargetCoord and FromCoord then
|
|
||||||
return TargetCoord:Get2DDistance(FromCoord)
|
|
||||||
else
|
|
||||||
self:E(self.lid.."ERROR: TargetCoord or FromCoord does not exist in AUFTRAG:GetTargetDistance() function! Returning 0")
|
|
||||||
end
|
|
||||||
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Get coordinate of target. First unit/group of the set is used.
|
--- Get coordinate of target. First unit/group of the set is used.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
@ -3100,10 +2959,10 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable)
|
|||||||
|
|
||||||
-- Done below as also other mission types use the orbit task.
|
-- Done below as also other mission types use the orbit task.
|
||||||
|
|
||||||
elseif self.type==AUFTRAG.Type.PATROL then
|
elseif self.type==AUFTRAG.Type.GCCAP then
|
||||||
|
|
||||||
--------------------
|
--------------------
|
||||||
-- PATROL Mission --
|
-- GCCAP Mission --
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
-- Done below as also other mission types use the orbit task.
|
-- Done below as also other mission types use the orbit task.
|
||||||
@ -3177,7 +3036,7 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable)
|
|||||||
|
|
||||||
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
|
-- We create a "fake" DCS task and pass the parameters to the FLIGHTGROUP.
|
||||||
local param={}
|
local param={}
|
||||||
param.unitname=self:GetTargetName()
|
param.unitname=self.carrier:GetName()
|
||||||
param.offsetX=200
|
param.offsetX=200
|
||||||
param.offsetZ=240
|
param.offsetZ=240
|
||||||
param.altitude=70
|
param.altitude=70
|
||||||
@ -3207,7 +3066,7 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable)
|
|||||||
if self.type==AUFTRAG.Type.ORBIT or
|
if self.type==AUFTRAG.Type.ORBIT or
|
||||||
self.type==AUFTRAG.Type.CAP or
|
self.type==AUFTRAG.Type.CAP or
|
||||||
self.type==AUFTRAG.Type.CAS or
|
self.type==AUFTRAG.Type.CAS or
|
||||||
self.type==AUFTRAG.Type.PATROL or
|
self.type==AUFTRAG.Type.GCCAP or
|
||||||
self.type==AUFTRAG.Type.AWACS or
|
self.type==AUFTRAG.Type.AWACS or
|
||||||
self.type==AUFTRAG.Type.TANKER then
|
self.type==AUFTRAG.Type.TANKER then
|
||||||
|
|
||||||
@ -3237,39 +3096,28 @@ end
|
|||||||
|
|
||||||
--- Get DCS task table for an attack group or unit task.
|
--- Get DCS task table for an attack group or unit task.
|
||||||
-- @param #AUFTRAG self
|
-- @param #AUFTRAG self
|
||||||
-- @param #AUFTRAG.TargetData target Target data.
|
-- @param Ops.Target#TARGET Target Target data.
|
||||||
-- @param #table DCStasks DCS DCS tasks table to which the task is added.
|
-- @param #table DCStasks DCS DCS tasks table to which the task is added.
|
||||||
-- @return DCS#Task The DCS task table.
|
-- @return DCS#Task The DCS task table.
|
||||||
function AUFTRAG:_GetDCSAttackTask(target, DCStasks)
|
function AUFTRAG:_GetDCSAttackTask(Target, DCStasks)
|
||||||
|
|
||||||
local DCStask=nil
|
DCStasks=DCStasks or {}
|
||||||
|
|
||||||
if target.Type==AUFTRAG.TargetType.GROUP then
|
for _,_target in pairs(Target.targets) do
|
||||||
|
local target=_target --Ops.Target#TARGET.Object
|
||||||
|
|
||||||
DCStask=CONTROLLABLE.TaskAttackGroup(nil, target.Target, self.engageWeaponType, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageAsGroup)
|
if target.Type==TARGET.ObjectType.GROUP then
|
||||||
|
|
||||||
table.insert(DCStasks, DCStask)
|
local DCStask=CONTROLLABLE.TaskAttackGroup(nil, target.Object, self.engageWeaponType, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageAsGroup)
|
||||||
|
|
||||||
elseif target.Type==AUFTRAG.TargetType.UNIT or target.Type==AUFTRAG.TargetType.STATIC then
|
|
||||||
|
|
||||||
DCStask=CONTROLLABLE.TaskAttackUnit(nil, target.Target, self.engageAsGroup, self.WeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
|
|
||||||
|
|
||||||
table.insert(DCStasks, DCStask)
|
|
||||||
|
|
||||||
elseif target.Type==AUFTRAG.TargetType.SETGROUP then
|
|
||||||
|
|
||||||
-- Add all groups.
|
|
||||||
for _,group in pairs(target.Target.Set or {}) do
|
|
||||||
DCStask=CONTROLLABLE.TaskAttackGroup(nil, group, self.engageWeaponType, self.engageWeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageAsGroup)
|
|
||||||
table.insert(DCStasks, DCStask)
|
table.insert(DCStasks, DCStask)
|
||||||
end
|
|
||||||
|
|
||||||
elseif target.Type==AUFTRAG.TargetType.SETUNIT then
|
elseif target.Type==TARGET.ObjectType.UNIT or target.Type==TARGET.ObjectType.STATIC then
|
||||||
|
|
||||||
|
local DCStask=CONTROLLABLE.TaskAttackUnit(nil, target.Object, self.engageAsGroup, self.WeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
|
||||||
|
|
||||||
-- Add tasks to attack all units.
|
|
||||||
for _,unit in pairs(target.Target.Set or {}) do
|
|
||||||
DCStask=CONTROLLABLE.TaskAttackUnit(nil, unit, self.engageAsGroup, self.WeaponExpend, self.engageQuantity, self.engageDirection, self.engageAltitude, self.engageWeaponType)
|
|
||||||
table.insert(DCStasks, DCStask)
|
table.insert(DCStasks, DCStask)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -3277,96 +3125,6 @@ function AUFTRAG:_GetDCSAttackTask(target, DCStasks)
|
|||||||
return DCStasks
|
return DCStasks
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Create target data from a given object.
|
|
||||||
-- @param #AUFTRAG self
|
|
||||||
-- @param Wrapper.Positionable#POSITIONABLE Object The target GROUP, UNIT, STATIC.
|
|
||||||
-- @return #AUFTRAG.TargetData Target.
|
|
||||||
function AUFTRAG:_TargetFromObject(Object)
|
|
||||||
|
|
||||||
local target={} --#AUFTRAG.TargetData
|
|
||||||
|
|
||||||
-- The object.
|
|
||||||
target.Target=Object
|
|
||||||
|
|
||||||
if Object:IsInstanceOf("GROUP") then
|
|
||||||
|
|
||||||
target.Type=AUFTRAG.TargetType.GROUP
|
|
||||||
|
|
||||||
local object=Object --Wrapper.Group#GROUP
|
|
||||||
|
|
||||||
target.Name=object:GetName()
|
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("UNIT") then
|
|
||||||
|
|
||||||
target.Type=AUFTRAG.TargetType.UNIT
|
|
||||||
|
|
||||||
local object=Object --Wrapper.Unit#UNIT
|
|
||||||
|
|
||||||
target.Name=object:GetName()
|
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("STATIC") then
|
|
||||||
|
|
||||||
target.Type=AUFTRAG.TargetType.STATIC
|
|
||||||
|
|
||||||
target.Name=Object:GetName()
|
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("COORDINATE") then
|
|
||||||
|
|
||||||
target.Type=AUFTRAG.TargetType.COORDINATE
|
|
||||||
|
|
||||||
local object=Object --Core.Point#COORDINATE
|
|
||||||
|
|
||||||
target.Name=object:ToStringLLDMS()
|
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("AIRBASE") then
|
|
||||||
|
|
||||||
target.Type=AUFTRAG.TargetType.AIRBASE
|
|
||||||
|
|
||||||
local object=Object --Wrapper.Airbase#AIRBASE
|
|
||||||
|
|
||||||
target.Name=object:GetName()
|
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("SET_GROUP") then
|
|
||||||
|
|
||||||
target.Type=AUFTRAG.TargetType.SETGROUP
|
|
||||||
|
|
||||||
local object=Object --Core.Set#SET_GROUP
|
|
||||||
|
|
||||||
target.Name=object:GetFirst():GetName()
|
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("SET_UNIT") then
|
|
||||||
|
|
||||||
target.Type=AUFTRAG.TargetType.SETUNIT
|
|
||||||
|
|
||||||
local object=Object --Core.Set#SET_UNIT
|
|
||||||
|
|
||||||
target.Name=object:GetFirst():GetName()
|
|
||||||
|
|
||||||
else
|
|
||||||
self:E(self.lid.."ERROR: Unknown object given as target. Needs to be a GROUP, UNIT, STATIC, COORDINATE")
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Number of initial targets.
|
|
||||||
local Ninitial=self:CountMissionTargets(target)
|
|
||||||
|
|
||||||
-- Initial total life point.
|
|
||||||
local Lifepoints=self:_GetTargetLife(target, true)
|
|
||||||
|
|
||||||
-- Set engage Target.
|
|
||||||
self.engageTarget=target
|
|
||||||
self.engageTarget.Ninital=Ninitial
|
|
||||||
self.engageTarget.Lifepoints=Lifepoints
|
|
||||||
|
|
||||||
-- TODO: get rid of this.
|
|
||||||
self.Ntargets=Ninitial
|
|
||||||
|
|
||||||
-- Debug info.
|
|
||||||
self:T(self.lid..string.format("Mission Target %s Type=%s, Ntargets=%d, Lifepoints=%d", target.Name, target.Type, Ninitial, Lifepoints))
|
|
||||||
|
|
||||||
return target
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -2624,6 +2624,9 @@ function FLIGHTGROUP:AddElementByName(unitname)
|
|||||||
element.status=OPSGROUP.ElementStatus.INUTERO
|
element.status=OPSGROUP.ElementStatus.INUTERO
|
||||||
element.group=unit:GetGroup()
|
element.group=unit:GetGroup()
|
||||||
|
|
||||||
|
-- TODO: this is wrong when grouping is used!
|
||||||
|
local unittemplate=element.unit:GetTemplate()
|
||||||
|
|
||||||
element.modex=element.unit:GetTemplate().onboard_num
|
element.modex=element.unit:GetTemplate().onboard_num
|
||||||
element.skill=element.unit:GetTemplate().skill
|
element.skill=element.unit:GetTemplate().skill
|
||||||
element.pylons=element.unit:GetTemplatePylons()
|
element.pylons=element.unit:GetTemplatePylons()
|
||||||
@ -2642,8 +2645,8 @@ function FLIGHTGROUP:AddElementByName(unitname)
|
|||||||
element.ai=true
|
element.ai=true
|
||||||
end
|
end
|
||||||
|
|
||||||
local text=string.format("Adding element %s: status=%s, skill=%s, modex=%s, fuelmass=%.1f (%d %%), category=%d, categoryname=%s, callsign=%s, ai=%s",
|
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))
|
element.name, element.status, element.skill, element.modex, element.fuelmass, element.fuelrel*100, element.category, element.categoryname, element.callsign, tostring(element.ai))
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Add element to table.
|
-- Add element to table.
|
||||||
|
|||||||
@ -1437,7 +1437,7 @@ end
|
|||||||
function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
|
function OPSGROUP:onafterTaskExecute(From, Event, To, Task)
|
||||||
|
|
||||||
-- Debug message.
|
-- Debug message.
|
||||||
local text=string.format("Task %s ID=%d execute.", tostring(Task.description), Task.id)
|
local text=string.format("Task %s ID=%d execute", tostring(Task.description), Task.id)
|
||||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
|
|
||||||
|
|||||||
@ -26,6 +26,8 @@
|
|||||||
-- @field #number ngrouping User defined number of units in the asset group.
|
-- @field #number ngrouping User defined number of units in the asset group.
|
||||||
-- @field #table assets Squadron assets.
|
-- @field #table assets Squadron assets.
|
||||||
-- @field #table missiontypes Capabilities (mission types and performances) of the squadron.
|
-- @field #table missiontypes Capabilities (mission types and performances) of the squadron.
|
||||||
|
-- @field #number maintenancetime Time in seconds needed for maintenance of a returned flight.
|
||||||
|
-- @field #number repairtime Time in seconds for each
|
||||||
-- @field #string livery Livery of the squadron.
|
-- @field #string livery Livery of the squadron.
|
||||||
-- @field #number skill Skill of squadron members.
|
-- @field #number skill Skill of squadron members.
|
||||||
-- @field #number modex Modex.
|
-- @field #number modex Modex.
|
||||||
@ -67,6 +69,8 @@ SQUADRON = {
|
|||||||
aircrafttype = nil,
|
aircrafttype = nil,
|
||||||
assets = {},
|
assets = {},
|
||||||
missiontypes = {},
|
missiontypes = {},
|
||||||
|
repairtime = 0,
|
||||||
|
maintenancetime= 0,
|
||||||
livery = nil,
|
livery = nil,
|
||||||
skill = nil,
|
skill = nil,
|
||||||
modex = nil,
|
modex = nil,
|
||||||
@ -233,6 +237,17 @@ function SQUADRON:SetSkill(Skill)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Set maintenance and repair time.
|
||||||
|
-- @param #SQUADRON self
|
||||||
|
-- @param #number MaintenanceTime Time in minutes it takes until a flight is combat ready again. Default is 0 min.
|
||||||
|
-- @param #number RepairTime Time in minutes it takes to repair a flight for each percent damage taken. Default is 0 min.
|
||||||
|
-- @return #SQUADRON self
|
||||||
|
function SQUADRON:SetMaintenanceTime(MaintenanceTime, RepairTime)
|
||||||
|
self.maintenancetime=MaintenanceTime and MaintenanceTime*60 or 0
|
||||||
|
self.repairtime=RepairTime and RepairTime*60 or 0
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set radio frequency and modulation the squad uses.
|
--- Set radio frequency and modulation the squad uses.
|
||||||
-- @param #SQUADRON self
|
-- @param #SQUADRON self
|
||||||
-- @param #number Frequency Radio frequency in MHz. Default 251 MHz.
|
-- @param #number Frequency Radio frequency in MHz. Default 251 MHz.
|
||||||
@ -683,12 +698,12 @@ function SQUADRON:RecruitAssets(Mission)
|
|||||||
-- Asset is already on a mission.
|
-- Asset is already on a mission.
|
||||||
---
|
---
|
||||||
|
|
||||||
-- Check if this asset is currently on a PATROL mission (STARTED or EXECUTING).
|
-- Check if this asset is currently on a GCCAP mission (STARTED or EXECUTING).
|
||||||
if self.airwing:IsAssetOnMission(asset, AUFTRAG.Type.PATROL) and Mission.type==AUFTRAG.Type.INTERCEPT then
|
if self.airwing:IsAssetOnMission(asset, AUFTRAG.Type.GCCAP) and Mission.type==AUFTRAG.Type.INTERCEPT then
|
||||||
|
|
||||||
-- Check if the payload of this asset is compatible with the mission.
|
-- Check if the payload of this asset is compatible with the mission.
|
||||||
-- Note: we do not check the payload as an asset that is on a PATROL mission should be able to do an INTERCEPT as well!
|
-- Note: we do not check the payload as an asset that is on a GCCAP mission should be able to do an INTERCEPT as well!
|
||||||
self:I(self.lid.."Adding asset on PATROL mission for an INTERCEPT mission")
|
self:I(self.lid.."Adding asset on GCCAP mission for an INTERCEPT mission")
|
||||||
table.insert(assets, asset)
|
table.insert(assets, asset)
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -696,7 +711,7 @@ function SQUADRON:RecruitAssets(Mission)
|
|||||||
else
|
else
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Asset as no current mission
|
-- Asset as NO current mission
|
||||||
---
|
---
|
||||||
|
|
||||||
if asset.spawned then
|
if asset.spawned then
|
||||||
@ -744,7 +759,7 @@ function SQUADRON:RecruitAssets(Mission)
|
|||||||
---
|
---
|
||||||
|
|
||||||
-- Check that asset is not already requested for another mission.
|
-- Check that asset is not already requested for another mission.
|
||||||
if Npayloads>0 and not asset.requested then
|
if Npayloads>0 and self:IsRepaired(asset) and (not asset.requested) then
|
||||||
|
|
||||||
-- Add this asset to the selection.
|
-- Add this asset to the selection.
|
||||||
table.insert(assets, asset)
|
table.insert(assets, asset)
|
||||||
@ -761,6 +776,26 @@ function SQUADRON:RecruitAssets(Mission)
|
|||||||
return assets
|
return assets
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Checks if a mission type is contained in a table of possible types.
|
||||||
|
-- @param #SQUADRON self
|
||||||
|
-- @param Ops.AirWing#AIRWING.SquadronAsset Asset The asset.
|
||||||
|
-- @return #boolean If true, the requested mission type is part of the possible mission types.
|
||||||
|
function SQUADRON:IsRepaired(Asset)
|
||||||
|
|
||||||
|
if Asset.Treturned then
|
||||||
|
local Tnow=timer.getAbsTime()
|
||||||
|
if Asset.Treturned+self.maintenancetime>=Tnow then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Checks if a mission type is contained in a table of possible types.
|
--- Checks if a mission type is contained in a table of possible types.
|
||||||
-- @param #SQUADRON self
|
-- @param #SQUADRON self
|
||||||
|
|||||||
@ -16,11 +16,15 @@
|
|||||||
-- @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 #boolean Debug Debug mode. Messages to all about status.
|
||||||
|
-- @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.
|
||||||
-- @field #number targetcounter Running number to generate target object IDs.
|
-- @field #number targetcounter Running number to generate target object IDs.
|
||||||
-- @field #number life Total life points on last status update.
|
-- @field #number life Total life points on last status update.
|
||||||
-- @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 category Target category (Ground, Air, Sea).
|
||||||
|
-- @field #number Ntargets0 Number of initial targets.
|
||||||
-- @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
|
||||||
@ -38,11 +42,14 @@
|
|||||||
TARGET = {
|
TARGET = {
|
||||||
ClassName = "TARGET",
|
ClassName = "TARGET",
|
||||||
Debug = nil,
|
Debug = nil,
|
||||||
|
verbose = 0,
|
||||||
lid = nil,
|
lid = nil,
|
||||||
targets = {},
|
targets = {},
|
||||||
targetcounter = 0,
|
targetcounter = 0,
|
||||||
life = 0,
|
life = 0,
|
||||||
life0 = 0,
|
life0 = 0,
|
||||||
|
Ntargets0 = 0,
|
||||||
|
threatlevel0 = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -60,7 +67,23 @@ TARGET.ObjectType={
|
|||||||
AIRBASE="Airbase",
|
AIRBASE="Airbase",
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Type.
|
|
||||||
|
--- Category.
|
||||||
|
-- @type TARGET.Category
|
||||||
|
-- @field #string AIRCRAFT
|
||||||
|
-- @field #string GROUND
|
||||||
|
-- @field #string NAVAL
|
||||||
|
-- @field #string AIRBASE
|
||||||
|
-- @field #string COORDINATE
|
||||||
|
TARGET.Category={
|
||||||
|
AIRCRAFT="Aircraft",
|
||||||
|
GROUND="Grund",
|
||||||
|
NAVAL="Naval",
|
||||||
|
AIRBASE="Airbase",
|
||||||
|
COORDINATE="Coordinate",
|
||||||
|
}
|
||||||
|
|
||||||
|
--- Object status.
|
||||||
-- @type TARGET.ObjectStatus
|
-- @type TARGET.ObjectStatus
|
||||||
-- @field #string ALIVE Object is alive.
|
-- @field #string ALIVE Object is alive.
|
||||||
-- @field #string DEAD Object is dead.
|
-- @field #string DEAD Object is dead.
|
||||||
@ -106,10 +129,15 @@ function TARGET:New(TargetObject)
|
|||||||
-- Increase counter.
|
-- Increase counter.
|
||||||
_TARGETID=_TARGETID+1
|
_TARGETID=_TARGETID+1
|
||||||
|
|
||||||
self.lid=string.format("TARGET #%03d | ", _TARGETID)
|
-- Add object.
|
||||||
|
|
||||||
self:AddObject(TargetObject)
|
self:AddObject(TargetObject)
|
||||||
|
|
||||||
|
local Target=self.targets[1] --#TARGET.Object
|
||||||
|
|
||||||
|
self.category=self:GetTargetCategory(Target)
|
||||||
|
|
||||||
|
self.lid=string.format("TARGET #%03d %s | ", _TARGETID, self.category)
|
||||||
|
|
||||||
-- Start state.
|
-- Start state.
|
||||||
self:SetStartState("Stopped")
|
self:SetStartState("Stopped")
|
||||||
|
|
||||||
@ -180,17 +208,11 @@ end
|
|||||||
-- @param Wrapper.Positionable#POSITIONABLE Object The target GROUP, UNIT, STATIC, AIRBASE or COORDINATE.
|
-- @param Wrapper.Positionable#POSITIONABLE Object The target GROUP, UNIT, STATIC, AIRBASE or COORDINATE.
|
||||||
function TARGET:AddObject(Object)
|
function TARGET:AddObject(Object)
|
||||||
|
|
||||||
if Object:IsInstanceOf("GROUP") then
|
if Object:IsInstanceOf("SET_GROUP") or Object:IsInstanceOf("SET_UNIT") then
|
||||||
|
|
||||||
local group=Object --Wrapper.Group#GROUP
|
---
|
||||||
|
-- Sets
|
||||||
local units=group:GetUnits()
|
---
|
||||||
|
|
||||||
for _,unit in pairs(units) do
|
|
||||||
self:_AddObject(unit)
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("SET_GROUP") or Object:IsInstanceOf("SET_UNIT") then
|
|
||||||
|
|
||||||
local set=Object --Core.Set#SET_GROUP
|
local set=Object --Core.Set#SET_GROUP
|
||||||
|
|
||||||
@ -198,11 +220,10 @@ function TARGET:AddObject(Object)
|
|||||||
self:AddObject(object)
|
self:AddObject(object)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Units, Statics, Airbases, Coordinates
|
-- Groups, Units, Statics, Airbases, Coordinates
|
||||||
---
|
---
|
||||||
|
|
||||||
self:_AddObject(Object)
|
self:_AddObject(Object)
|
||||||
@ -265,7 +286,7 @@ function TARGET:onafterStatus(From, Event, To)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Log output.
|
-- Log output.
|
||||||
local text=string.format("%s: Targets=%d/%d Life=%.1f/%.1f Damage=%.1f", fsmstate, self:CountTargets(), #self.targets, self:GetLife(), self:GetLife0(), self:GetDamage())
|
local text=string.format("%s: Targets=%d/%d Life=%.1f/%.1f Damage=%.1f", fsmstate, self:CountTargets(), self.Ntargets0, self:GetLife(), self:GetLife0(), self:GetDamage())
|
||||||
if damaged then
|
if damaged then
|
||||||
text=text.." Damaged!"
|
text=text.." Damaged!"
|
||||||
end
|
end
|
||||||
@ -277,7 +298,7 @@ function TARGET:onafterStatus(From, Event, To)
|
|||||||
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
|
||||||
local damage=(1-target.Life/target.Life0)*100
|
local damage=(1-target.Life/target.Life0)*100
|
||||||
text=text..string.format("\n[%d] %s %s: Life=%.1f/%.1f, Damage=%.1f", i, target.Name, target.Status, target.Life, target.Life0, damage)
|
text=text..string.format("\n[%d] %s %s %s: Life=%.1f/%.1f, Damage=%.1f", i, target.Type, target.Name, target.Status, target.Life, target.Life0, damage)
|
||||||
end
|
end
|
||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
end
|
end
|
||||||
@ -397,7 +418,30 @@ function TARGET:_AddObject(Object)
|
|||||||
|
|
||||||
local target={} --#TARGET.Object
|
local target={} --#TARGET.Object
|
||||||
|
|
||||||
if Object:IsInstanceOf("UNIT") then
|
if Object:IsInstanceOf("GROUP") then
|
||||||
|
|
||||||
|
local group=Object --Wrapper.Group#GROUP
|
||||||
|
|
||||||
|
target.Type=TARGET.ObjectType.GROUP
|
||||||
|
target.Name=group:GetName()
|
||||||
|
|
||||||
|
local units=group:GetUnits()
|
||||||
|
|
||||||
|
target.Life=0 ; target.Life0=0
|
||||||
|
for _,_unit in pairs(units or {}) do
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
local life=unit:GetLife()
|
||||||
|
|
||||||
|
target.Life=target.Life+life
|
||||||
|
target.Life0=target.Life0+math.max(unit:GetLife0(), life) -- There was an issue with ships that life is greater life0, which cannot be!
|
||||||
|
|
||||||
|
self.threatlevel0=self.threatlevel0+unit:GetThreatLevel()
|
||||||
|
|
||||||
|
self.Ntargets0=self.Ntargets0+1
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Object:IsInstanceOf("UNIT") then
|
||||||
|
|
||||||
local unit=Object --Wrapper.Unit#UNIT
|
local unit=Object --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
@ -407,6 +451,10 @@ function TARGET:_AddObject(Object)
|
|||||||
if unit and unit:IsAlive() then
|
if unit and unit:IsAlive() then
|
||||||
target.Life=unit:GetLife()
|
target.Life=unit:GetLife()
|
||||||
target.Life0=math.max(unit:GetLife0(), target.Life) -- There was an issue with ships that life is greater life0!
|
target.Life0=math.max(unit:GetLife0(), target.Life) -- There was an issue with ships that life is greater life0!
|
||||||
|
|
||||||
|
self.threatlevel0=self.threatlevel0+unit:GetThreatLevel()
|
||||||
|
|
||||||
|
self.Ntargets0=self.Ntargets0+1
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("STATIC") then
|
elseif Object:IsInstanceOf("STATIC") then
|
||||||
@ -419,6 +467,8 @@ function TARGET:_AddObject(Object)
|
|||||||
if static and static:IsAlive() then
|
if static and static:IsAlive() then
|
||||||
target.Life0=1
|
target.Life0=1
|
||||||
target.Life=1
|
target.Life=1
|
||||||
|
|
||||||
|
self.Ntargets0=self.Ntargets0+1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -432,6 +482,7 @@ function TARGET:_AddObject(Object)
|
|||||||
target.Life0=1
|
target.Life0=1
|
||||||
target.Life=1
|
target.Life=1
|
||||||
|
|
||||||
|
self.Ntargets0=self.Ntargets0+1
|
||||||
|
|
||||||
elseif Object:IsInstanceOf("COORDINATE") then
|
elseif Object:IsInstanceOf("COORDINATE") then
|
||||||
|
|
||||||
@ -443,6 +494,9 @@ function TARGET:_AddObject(Object)
|
|||||||
target.Life0=1
|
target.Life0=1
|
||||||
target.Life=1
|
target.Life=1
|
||||||
|
|
||||||
|
-- TODO: does this make sense for a coordinate?
|
||||||
|
--self.Ntargets0=self.Ntargets0+1
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E(self.lid.."ERROR: Unknown object type!")
|
self:E(self.lid.."ERROR: Unknown object type!")
|
||||||
return nil
|
return nil
|
||||||
@ -488,7 +542,24 @@ end
|
|||||||
-- @return #number Life points of target.
|
-- @return #number Life points of target.
|
||||||
function TARGET:GetTargetLife(Target)
|
function TARGET:GetTargetLife(Target)
|
||||||
|
|
||||||
if Target.Type==TARGET.ObjectType.UNIT then
|
if Target.Type==TARGET.ObjectType.GROUP then
|
||||||
|
|
||||||
|
if Target.Object and Target.Object:IsAlive() then
|
||||||
|
|
||||||
|
local units=Target.Object:GetUnits()
|
||||||
|
|
||||||
|
local life=0
|
||||||
|
for _,_unit in pairs(units or {}) do
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
life=life+unit:GetLife()
|
||||||
|
end
|
||||||
|
|
||||||
|
return life
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.UNIT then
|
||||||
|
|
||||||
if Target.Object and Target.Object:IsAlive() then
|
if Target.Object and Target.Object:IsAlive() then
|
||||||
return Target.Object:GetLife()
|
return Target.Object:GetLife()
|
||||||
@ -527,18 +598,6 @@ function TARGET:GetLife()
|
|||||||
|
|
||||||
local N=0
|
local N=0
|
||||||
|
|
||||||
local function _GetLife(unit)
|
|
||||||
local unit=unit --Wrapper.Unit#UNIT
|
|
||||||
if Healthy then
|
|
||||||
local life=unit:GetLife()
|
|
||||||
local life0=unit:GetLife0()
|
|
||||||
|
|
||||||
return math.max(life, life0)
|
|
||||||
else
|
|
||||||
return unit:GetLife()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for _,_target in pairs(self.targets) do
|
for _,_target in pairs(self.targets) do
|
||||||
local Target=_target --#TARGET.Object
|
local Target=_target --#TARGET.Object
|
||||||
|
|
||||||
@ -549,6 +608,132 @@ function TARGET:GetLife()
|
|||||||
return N
|
return N
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--- Get target coordinate.
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @param #TARGET.Object Target Target object.
|
||||||
|
-- @return Core.Point#COORDINATE Coordinate of the target.
|
||||||
|
function TARGET:GetTargetCoordinate(Target)
|
||||||
|
|
||||||
|
if Target.Type==TARGET.ObjectType.GROUP then
|
||||||
|
|
||||||
|
if Target.Object and Target.Object:IsAlive() then
|
||||||
|
|
||||||
|
return Target.Object:GetCoordinate()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.UNIT then
|
||||||
|
|
||||||
|
if Target.Object and Target.Object:IsAlive() then
|
||||||
|
return Target.Object:GetCoordinate()
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.STATIC then
|
||||||
|
|
||||||
|
if Target.Object and Target.Object:IsAlive() then
|
||||||
|
return Target.Object:GetCoordinate()
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.AIRBASE then
|
||||||
|
|
||||||
|
if Target.Status==TARGET.ObjectStatus.ALIVE then
|
||||||
|
return Target.Object:GetCoordinate()
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.COORDINATE then
|
||||||
|
|
||||||
|
return Target.Object
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get coordinate.
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @return Core.Point#COORDINATE Coordinate of the target.
|
||||||
|
function TARGET:GetCoordinate()
|
||||||
|
|
||||||
|
for _,_target in pairs(self.targets) do
|
||||||
|
local Target=_target --#TARGET.Object
|
||||||
|
|
||||||
|
local coordinate=self:GetTargetCoordinate(Target)
|
||||||
|
|
||||||
|
if coordinate then
|
||||||
|
return coordinate
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Get target category
|
||||||
|
-- @param #TARGET self
|
||||||
|
-- @param #TARGET.Object Target Target object.
|
||||||
|
-- @return #TARGET.Category Target category.
|
||||||
|
function TARGET:GetTargetCategory(Target)
|
||||||
|
|
||||||
|
local category=nil
|
||||||
|
|
||||||
|
if Target.Type==TARGET.ObjectType.GROUP then
|
||||||
|
|
||||||
|
if Target.Object and Target.Object:IsAlive()~=nil then
|
||||||
|
|
||||||
|
local group=Target.Object --Wrapper.Group#GROUP
|
||||||
|
|
||||||
|
local cat=group:GetCategory()
|
||||||
|
|
||||||
|
if cat==Group.Category.AIRPLANE or cat==Group.Category.HELICOPTER then
|
||||||
|
category=TARGET.Category.AIRCRAFT
|
||||||
|
elseif cat==Group.Category.GROUND or cat==Group.Category.TRAIN then
|
||||||
|
category=TARGET.Category.GROUND
|
||||||
|
elseif cat==Group.Category.SHIP then
|
||||||
|
category=TARGET.Category.NAVAL
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.UNIT then
|
||||||
|
|
||||||
|
if Target.Object and Target.Object:IsAlive() then
|
||||||
|
local unit=Target.Object --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
local group=unit:GetGroup()
|
||||||
|
|
||||||
|
local cat=group:GetCategory()
|
||||||
|
|
||||||
|
if cat==Group.Category.AIRPLANE or cat==Group.Category.HELICOPTER then
|
||||||
|
category=TARGET.Category.AIRCRAFT
|
||||||
|
elseif cat==Group.Category.GROUND or cat==Group.Category.TRAIN then
|
||||||
|
category=TARGET.Category.GROUND
|
||||||
|
elseif cat==Group.Category.SHIP then
|
||||||
|
category=TARGET.Category.NAVAL
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.STATIC then
|
||||||
|
|
||||||
|
return TARGET.Category.GROUND
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.AIRBASE then
|
||||||
|
|
||||||
|
return TARGET.Category.AIRBASE
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.COORDINATE then
|
||||||
|
|
||||||
|
return TARGET.Category.COORDINATE
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
return category
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Misc Functions
|
-- Misc Functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@ -580,7 +765,20 @@ function TARGET:CountTargets()
|
|||||||
for _,_target in pairs(self.targets) do
|
for _,_target in pairs(self.targets) do
|
||||||
local Target=_target --#TARGET.Object
|
local Target=_target --#TARGET.Object
|
||||||
|
|
||||||
if Target.Type==TARGET.ObjectType.UNIT then
|
if Target.Type==TARGET.ObjectType.GROUP then
|
||||||
|
|
||||||
|
local target=Target.Object --Wrapper.Group#GROUP
|
||||||
|
|
||||||
|
local units=target:GetUnits()
|
||||||
|
|
||||||
|
for _,_unit in pairs(units or {}) do
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
if unit and unit:IsAlive() and unit:GetLife()>1 then
|
||||||
|
N=N+1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif Target.Type==TARGET.ObjectType.UNIT then
|
||||||
|
|
||||||
local target=Target.Object --Wrapper.Unit#UNIT
|
local target=Target.Object --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
|||||||
@ -2213,6 +2213,45 @@ function GROUP:GetDCSDesc(n)
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get health of the group.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @return #number Health in percent.
|
||||||
|
function GROUP:GetHealth()
|
||||||
|
|
||||||
|
local lp=0
|
||||||
|
local lp0=0
|
||||||
|
|
||||||
|
local units=self:GetUnits()
|
||||||
|
|
||||||
|
for _,_unit in pairs(units or {}) do
|
||||||
|
local unit=_unit --Wrapper.Unit#UNIT
|
||||||
|
|
||||||
|
if unit and unit:IsAlive() then
|
||||||
|
local life=unit:GetLife()
|
||||||
|
local life0=unit:GetLife0()
|
||||||
|
life0=math.max(life0, life) --Issue with ships
|
||||||
|
|
||||||
|
lp=lp+life
|
||||||
|
lp0=lp0+life
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if lp0>0 then
|
||||||
|
return lp/lp0*100
|
||||||
|
else
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Get damage of the group.
|
||||||
|
-- @param #GROUP self
|
||||||
|
-- @return #number Damage in percent.
|
||||||
|
function GROUP:GetDamage()
|
||||||
|
return 100-self:GetHealth()
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Get the generalized attribute of a self.
|
--- Get the generalized attribute of a self.
|
||||||
-- Note that for a heterogenious self, the attribute is determined from the attribute of the first unit!
|
-- Note that for a heterogenious self, the attribute is determined from the attribute of the first unit!
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user