- Lots of updates and improvements
This commit is contained in:
Frank 2021-10-01 12:04:15 +02:00
parent 3e30d15405
commit 2ae2ee64be
13 changed files with 1041 additions and 319 deletions

View File

@ -860,6 +860,20 @@ function DATABASE:GetGroupTemplateFromUnitName( UnitName )
end end
end end
--- Get group template from unit name.
-- @param #DATABASE self
-- @param #string UnitName Name of the unit.
-- @return #table Group template.
function DATABASE:GetUnitTemplateFromUnitName( UnitName )
if self.Templates.Units[UnitName] then
return self.Templates.Units[UnitName]
else
self:E("ERROR: Unit template does not exist for unit "..tostring(UnitName))
return nil
end
end
--- Get coalition ID from client name. --- Get coalition ID from client name.
-- @param #DATABASE self -- @param #DATABASE self
-- @param #string ClientName Name of the Client. -- @param #string ClientName Name of the Client.

View File

@ -107,14 +107,15 @@ _TIMERID=0
--- TIMER class version. --- TIMER class version.
-- @field #string version -- @field #string version
TIMER.version="0.1.1" TIMER.version="0.1.2"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list -- TODO list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Randomization.
-- TODO: Pause/unpause. -- TODO: Pause/unpause.
-- TODO: Write docs. -- DONE: Write docs.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor -- Constructor
@ -228,6 +229,15 @@ function TIMER:SetMaxFunctionCalls(Nmax)
return self return self
end end
--- Set time interval. Can also be set when the timer is already running and is applied after the next function call.
-- @param #TIMER self
-- @param #number dT Time interval in seconds.
-- @return #TIMER self
function TIMER:SetTimeInterval(dT)
self.dT=dT
return self
end
--- Check if the timer has been started and was not stopped. --- Check if the timer has been started and was not stopped.
-- @param #TIMER self -- @param #TIMER self
-- @return #boolean If `true`, the timer is running. -- @return #boolean If `true`, the timer is running.

View File

@ -139,6 +139,28 @@ AIRWING = {
-- @field #number noccupied Number of flights on this patrol point. -- @field #number noccupied Number of flights on this patrol point.
-- @field Wrapper.Marker#MARKER marker F10 marker. -- @field Wrapper.Marker#MARKER marker F10 marker.
--- AWACS zone.
-- @type AIRWING.AwacsZone
-- @field Core.Zone#ZONE zone Zone.
-- @field #number altitude Altitude in feet.
-- @field #number heading Heading in degrees.
-- @field #number leg Leg length in NM.
-- @field #number speed Speed in knots.
-- @field #number refuelsystem Refueling system type: `0=Unit.RefuelingSystem.BOOM_AND_RECEPTACLE`, `1=Unit.RefuelingSystem.PROBE_AND_DROGUE`.
-- @field Ops.Auftrag#AUFTRAG mission Mission assigned.
-- @field Wrapper.Marker#MARKER marker F10 marker.
--- Tanker zone.
-- @type AIRWING.TankerZone
-- @field Core.Point#COORDINATE coord Patrol coordinate.
-- @field #number altitude Altitude in feet.
-- @field #number heading Heading in degrees.
-- @field #number leg Leg length in NM.
-- @field #number speed Speed in knots.
-- @field #number refuelsystem Refueling system type: `0=Unit.RefuelingSystem.BOOM_AND_RECEPTACLE`, `1=Unit.RefuelingSystem.PROBE_AND_DROGUE`.
-- @field Ops.Auftrag#AUFTRAG mission Mission assigned.
-- @field Wrapper.Marker#MARKER marker F10 marker.
--- AIRWING class version. --- AIRWING class version.
-- @field #string version -- @field #string version
AIRWING.version="0.9.0" AIRWING.version="0.9.0"

View File

@ -361,6 +361,7 @@ function ARMYGROUP:Status()
-- Is group alive? -- Is group alive?
local alive=self:IsAlive() local alive=self:IsAlive()
-- Check that group EXISTS and is ACTIVE.
if alive then if alive then
-- Update position etc. -- Update position etc.
@ -396,6 +397,7 @@ function ARMYGROUP:Status()
end end
-- Check that group EXISTS.
if alive~=nil then if alive~=nil then
if self.verbose>=1 then if self.verbose>=1 then
@ -1377,6 +1379,7 @@ function ARMYGROUP:_InitGroup(Template)
self:_AddElementByName(unit:GetName()) self:_AddElementByName(unit:GetName())
end end
-- Init done. -- Init done.
self.groupinitialized=true self.groupinitialized=true

View File

@ -1130,7 +1130,7 @@ end
-- @param Core.Point#COORDINATE Coordinate Where to orbit. Default is the center of the CAS zone. -- @param Core.Point#COORDINATE Coordinate Where to orbit. Default is the center of the CAS zone.
-- @param #number Heading Heading of race-track pattern in degrees. If not specified, a simple circular orbit is performed. -- @param #number Heading Heading of race-track pattern in degrees. If not specified, a simple circular orbit is performed.
-- @param #number Leg Length of race-track in NM. If not specified, a simple circular orbit is performed. -- @param #number Leg Length of race-track in NM. If not specified, a simple circular orbit is performed.
-- @param #table TargetTypes (Optional) Table of target types. Default {"Helicopters", "Ground Units", "Light armed ships"}. -- @param #table TargetTypes (Optional) Table of target types. Default `{"Helicopters", "Ground Units", "Light armed ships"}`.
-- @return #AUFTRAG self -- @return #AUFTRAG self
function AUFTRAG:NewCAS(ZoneCAS, Altitude, Speed, Coordinate, Heading, Leg, TargetTypes) function AUFTRAG:NewCAS(ZoneCAS, Altitude, Speed, Coordinate, Heading, Leg, TargetTypes)
@ -1718,7 +1718,7 @@ function AUFTRAG:NewONGUARD(Coordinate)
mission:_TargetFromObject(Coordinate) mission:_TargetFromObject(Coordinate)
mission.optionROE=ENUMS.ROE.OpenFire mission.optionROE=ENUMS.ROE.OpenFire
mission.optionAlarm=ENUMS.AlarmState.Red mission.optionAlarm=ENUMS.AlarmState.Auto
mission.missionFraction=1.0 mission.missionFraction=1.0

File diff suppressed because it is too large Load Diff

View File

@ -117,11 +117,6 @@ function COHORT:New(TemplateGroupName, Ngroups, CohortName)
return nil return nil
end end
-- Defaults.
self.Ngroups=Ngroups or 3
self:SetMissionRange()
self:SetSkill(AI.Skill.GOOD)
-- Generalized attribute. -- Generalized attribute.
self.attribute=self.templategroup:GetAttribute() self.attribute=self.templategroup:GetAttribute()
@ -131,6 +126,24 @@ function COHORT:New(TemplateGroupName, Ngroups, CohortName)
-- Aircraft type. -- Aircraft type.
self.aircrafttype=self.templategroup:GetTypeName() self.aircrafttype=self.templategroup:GetTypeName()
-- Defaults.
self.Ngroups=Ngroups or 3
self:SetSkill(AI.Skill.GOOD)
-- Mission range depends on
if self.category==Group.Category.AIRPLANE then
self:SetMissionRange(150)
elseif self.category==Group.Category.HELICOPTER then
self:SetMissionRange(150)
elseif self.category==Group.Category.GROUND then
self:SetMissionRange(75)
elseif self.category==Group.Category.SHIP then
self:SetMissionRange(100)
elseif self.category==Group.Category.TRAIN then
self:SetMissionRange(100)
end
-- Units.
local units=self.templategroup:GetUnits() local units=self.templategroup:GetUnits()
-- Weight of the whole group. -- Weight of the whole group.
@ -346,10 +359,10 @@ end
--- Set max mission range. Only missions in a circle of this radius around the cohort base are executed. --- Set max mission range. Only missions in a circle of this radius around the cohort base are executed.
-- @param #COHORT self -- @param #COHORT self
-- @param #number Range Range in NM. Default 100 NM. -- @param #number Range Range in NM. Default 150 NM.
-- @return #COHORT self -- @return #COHORT self
function COHORT:SetMissionRange(Range) function COHORT:SetMissionRange(Range)
self.engageRange=UTILS.NMToMeters(Range or 100) self.engageRange=UTILS.NMToMeters(Range or 150)
return self return self
end end
@ -914,6 +927,9 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
combatready=false combatready=false
end end
-- Disable this for now as it can cause problems - at least with transport and cargo assets.
combatready=false
-- This asset is "combatready". -- This asset is "combatready".
if combatready then if combatready then
self:I(self.lid.."Adding SPAWNED asset to ANOTHER mission as it is COMBATREADY") self:I(self.lid.."Adding SPAWNED asset to ANOTHER mission as it is COMBATREADY")

View File

@ -17,11 +17,14 @@
-- @field #string ClassName Name of the class. -- @field #string ClassName Name of the class.
-- @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 #number coalition Coalition side of the commander.
-- @field #string alias Alias name.
-- @field #table legions Table of legions which are commanded. -- @field #table legions Table of legions which are commanded.
-- @field #table missionqueue Mission queue. -- @field #table missionqueue Mission queue.
-- @field #table transportqueue Transport queue. -- @field #table transportqueue Transport queue.
-- @field #table rearmingZones Rearming zones. Each element is of type `#BRIGADE.SupplyZone`. -- @field #table rearmingZones Rearming zones. Each element is of type `#BRIGADE.SupplyZone`.
-- @field #table refuellingZones Refuelling zones. Each element is of type `#BRIGADE.SupplyZone`. -- @field #table refuellingZones Refuelling zones. Each element is of type `#BRIGADE.SupplyZone`.
-- @field #table awacsZones AWACS zones. Each element is of type `#AIRWING.AwacsZone`.
-- @field Ops.Chief#CHIEF chief Chief of staff. -- @field Ops.Chief#CHIEF chief Chief of staff.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
@ -38,11 +41,13 @@
COMMANDER = { COMMANDER = {
ClassName = "COMMANDER", ClassName = "COMMANDER",
verbose = 0, verbose = 0,
coalition = nil,
legions = {}, legions = {},
missionqueue = {}, missionqueue = {},
transportqueue = {}, transportqueue = {},
rearmingZones = {}, rearmingZones = {},
refuellingZones = {}, refuellingZones = {},
awacsZones = {},
} }
--- COMMANDER class version. --- COMMANDER class version.
@ -53,9 +58,9 @@ COMMANDER.version="0.1.0"
-- TODO list -- TODO list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Improve legion selection. Mostly done! -- DONE: Improve legion selection. Mostly done!
-- TODO: Find solution for missions, which require a transport. This is not as easy as it sounds since the selected mission assets restrict the possible transport assets. -- DONE: Find solution for missions, which require a transport. This is not as easy as it sounds since the selected mission assets restrict the possible transport assets.
-- TODO: Add ops transports. -- DONE: Add ops transports.
-- DONE: Allow multiple Legions for one mission. -- DONE: Allow multiple Legions for one mission.
-- NOGO: Maybe it's possible to preselect the assets for the mission. -- NOGO: Maybe it's possible to preselect the assets for the mission.
@ -65,14 +70,21 @@ COMMANDER.version="0.1.0"
--- Create a new COMMANDER object and start the FSM. --- Create a new COMMANDER object and start the FSM.
-- @param #COMMANDER self -- @param #COMMANDER self
-- @param #number Coalition Coaliton of the commander.
-- @param #string Alias Some name you want the commander to be called.
-- @return #COMMANDER self -- @return #COMMANDER self
function COMMANDER:New() function COMMANDER:New(Coalition, Alias)
-- Inherit everything from INTEL class. -- Inherit everything from INTEL class.
local self=BASE:Inherit(self, FSM:New()) --#COMMANDER local self=BASE:Inherit(self, FSM:New()) --#COMMANDER
-- Set coaliton.
self.coalition=Coalition
-- Alias name.
self.alias=Alias or string.format("Jon Doe")
-- Log ID. -- Log ID.
self.lid="COMMANDER | " self.lid=string.format("COMMANDER %s [%s] | ", self.alias, UTILS.GetCoalitionName(self.coalition))
-- Start state. -- Start state.
self:SetStartState("NotReadyYet") self:SetStartState("NotReadyYet")
@ -89,6 +101,8 @@ function COMMANDER:New()
self:AddTransition("*", "TransportAssign", "*") -- Transport is assigned to a or multiple LEGIONs. self:AddTransition("*", "TransportAssign", "*") -- Transport is assigned to a or multiple LEGIONs.
self:AddTransition("*", "TransportCancel", "*") -- COMMANDER cancels a Transport. self:AddTransition("*", "TransportCancel", "*") -- COMMANDER cancels a Transport.
self:AddTransition("*", "OpsOnMission", "*") -- An OPSGROUP was send on a Mission (AUFTRAG).
------------------------ ------------------------
--- Pseudo Functions --- --- Pseudo Functions ---
------------------------ ------------------------
@ -207,6 +221,29 @@ function COMMANDER:New()
-- @param #string To To state. -- @param #string To To state.
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport. -- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
--- Triggers the FSM event "OpsOnMission".
-- @function [parent=#COMMANDER] OpsOnMission
-- @param #COMMANDER self
-- @param Ops.OpsGroup#OPSGROUP OpsGroup The OPS group on mission.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
--- Triggers the FSM event "OpsOnMission" after a delay.
-- @function [parent=#COMMANDER] __OpsOnMission
-- @param #COMMANDER self
-- @param #number delay Delay in seconds.
-- @param Ops.OpsGroup#OPSGROUP OpsGroup The OPS group on mission.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
--- On after "OpsOnMission" event.
-- @function [parent=#COMMANDER] OnAfterOpsOnMission
-- @param #COMMANDER self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.OpsGroup#OPSGROUP OpsGroup The OPS group on mission.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
return self return self
end end
@ -223,6 +260,13 @@ function COMMANDER:SetVerbosity(VerbosityLevel)
return self return self
end end
--- Get coalition.
-- @param #COMMANDER self
-- @return #number Coalition.
function COMMANDER:GetCoalition()
return self.coalition
end
--- Add an AIRWING to the commander. --- Add an AIRWING to the commander.
-- @param #COMMANDER self -- @param #COMMANDER self
-- @param Ops.AirWing#AIRWING Airwing The airwing to add. -- @param Ops.AirWing#AIRWING Airwing The airwing to add.
@ -268,11 +312,15 @@ end
-- @return #COMMANDER self -- @return #COMMANDER self
function COMMANDER:AddMission(Mission) function COMMANDER:AddMission(Mission)
Mission.commander=self if not self:IsMission(Mission) then
Mission.statusCommander=AUFTRAG.Status.PLANNED Mission.commander=self
table.insert(self.missionqueue, Mission) Mission.statusCommander=AUFTRAG.Status.PLANNED
table.insert(self.missionqueue, Mission)
end
return self return self
end end
@ -368,6 +416,47 @@ function COMMANDER:AddRefuellingZone(RefuellingZone)
return rearmingzone return rearmingzone
end end
--- Add an AWACS zone.
-- @param #COMMANDER self
-- @param Core.Zone#ZONE AwacsZone Zone.
-- @param #number Altitude Orbit altitude in feet. Default is 12,0000 feet.
-- @param #number Speed Orbit speed in KIAS. Default 350 kts.
-- @param #number Heading Heading of race-track pattern in degrees. Default 270 (East to West).
-- @param #number Leg Length of race-track in NM. Default 30 NM.
-- @return Ops.AirWing#AIRWING.AwacsZone The AWACS zone.
function COMMANDER:AddAwacsZone(AwacsZone, Altitude, Speed, Heading, Leg)
local awacszone={} --Ops.AirWing#AIRWING.AwacsZone
awacszone.zone=AwacsZone
awacszone.altitude=Altitude or 12000
awacszone.heading=Heading or 270
awacszone.speed=UTILS.KnotsToAltKIAS(Speed or 350, awacszone.altitude)
awacszone.leg=Leg or 30
awacszone.mission=nil
awacszone.marker=MARKER:New(awacszone.zone:GetCoordinate(), "AWACS Zone"):ToCoalition(self:GetCoalition())
table.insert(self.awacsZones, awacszone)
return awacszone
end
--- Check if this mission is already in the queue.
-- @param #COMMANDER self
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @return #boolean If `true`, this mission is in the queue.
function COMMANDER:IsMission(Mission)
for _,_mission in pairs(self.missionqueue) do
local mission=_mission --Ops.Auftrag#AUFTRAG
if mission.auftragsnummer==Mission.auftragsnummer then
return true
end
end
return false
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Start & Status -- Start & Status
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -420,7 +509,7 @@ function COMMANDER:onafterStatus(From, Event, To)
-- Check rearming zones. -- Check rearming zones.
for _,_rearmingzone in pairs(self.rearmingZones) do for _,_rearmingzone in pairs(self.rearmingZones) do
local rearmingzone=_rearmingzone --#BRIGADE.SupplyZone local rearmingzone=_rearmingzone --Ops.Brigade#BRIGADE.SupplyZone
-- Check if mission is nil or over. -- Check if mission is nil or over.
if (not rearmingzone.mission) or rearmingzone.mission:IsOver() then if (not rearmingzone.mission) or rearmingzone.mission:IsOver() then
rearmingzone.mission=AUFTRAG:NewAMMOSUPPLY(rearmingzone.zone) rearmingzone.mission=AUFTRAG:NewAMMOSUPPLY(rearmingzone.zone)
@ -430,7 +519,7 @@ function COMMANDER:onafterStatus(From, Event, To)
-- Check refuelling zones. -- Check refuelling zones.
for _,_supplyzone in pairs(self.refuellingZones) do for _,_supplyzone in pairs(self.refuellingZones) do
local supplyzone=_supplyzone --#BRIGADE.SupplyZone local supplyzone=_supplyzone --Ops.Brigade#BRIGADE.SupplyZone
-- Check if mission is nil or over. -- Check if mission is nil or over.
if (not supplyzone.mission) or supplyzone.mission:IsOver() then if (not supplyzone.mission) or supplyzone.mission:IsOver() then
supplyzone.mission=AUFTRAG:NewFUELSUPPLY(supplyzone.zone) supplyzone.mission=AUFTRAG:NewFUELSUPPLY(supplyzone.zone)
@ -438,6 +527,17 @@ function COMMANDER:onafterStatus(From, Event, To)
end end
end end
-- Check AWACS zones.
for _,_awacszone in pairs(self.awacsZones) do
local awacszone=_awacszone --Ops.AirWing#AIRWING.AwacsZone
-- Check if mission is nil or over.
if (not awacszone.mission) or awacszone.mission:IsOver() then
local Coordinate=awacszone.zone:GetCoordinate()
awacszone.mission=AUFTRAG:NewAWACS(Coordinate, awacszone.altitude, awacszone.speed, awacszone.heading, awacszone.leg)
self:AddMission(awacszone.mission)
end
end
--- ---
-- LEGIONS -- LEGIONS
--- ---
@ -588,6 +688,9 @@ function COMMANDER:onafterMissionAssign(From, Event, To, Legion, Mission)
-- Debug info. -- Debug info.
self:I(self.lid..string.format("Assigning mission %s (%s) to legion %s", Mission.name, Mission.type, Legion.alias)) self:I(self.lid..string.format("Assigning mission %s (%s) to legion %s", Mission.name, Mission.type, Legion.alias))
-- Add mission to queue.
self:AddMission(Mission)
-- Set mission commander status to QUEUED as it is now queued at a legion. -- Set mission commander status to QUEUED as it is now queued at a legion.
Mission.statusCommander=AUFTRAG.Status.QUEUED Mission.statusCommander=AUFTRAG.Status.QUEUED
@ -696,6 +799,18 @@ function COMMANDER:onafterTransportCancel(From, Event, To, Transport)
end end
--- On after "OpsOnMission".
-- @param #COMMANDER self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.OpsGroup#OPSGROUP OpsGroup Ops group on mission
-- @param Ops.Auftrag#AUFTRAG Mission The requested mission.
function COMMANDER:onafterOpsOnMission(From, Event, To, OpsGroup, Mission)
-- Debug info.
self:T2(self.lid..string.format("Group %s on %s mission %s", OpsGroup:GetName(), Mission:GetType(), Mission:GetName()))
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Mission Functions -- Mission Functions
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -796,46 +796,58 @@ function FLIGHTGROUP:Status()
-- Is group alive? -- Is group alive?
local alive=self:IsAlive() local alive=self:IsAlive()
-- Update position. if alive then
self:_UpdatePosition()
-- Check if group has detected any units. -- Update position.
self:_CheckDetectedUnits() self:_UpdatePosition()
-- Check ammo status. -- Check if group has detected any units.
self:_CheckAmmoStatus() self:_CheckDetectedUnits()
-- Check damage. -- Check ammo status.
self:_CheckDamage() self:_CheckAmmoStatus()
--- -- Check damage.
-- Parking self:_CheckDamage()
---
-- TODO: _CheckParking() function -- TODO: Check if group is waiting?
if self:IsWaiting() then
-- Check if flight began to taxi (if it was parking). if self.Twaiting and self.dTwait then
if self:IsParking() then if timer.getAbsTime()>self.Twaiting+self.dTwait then
for _,_element in pairs(self.elements) do --self.Twaiting=nil
local element=_element --Ops.OpsGroup#OPSGROUP.Element --self.dTwait=nil
if element.parking then --self:Cruise()
-- Get distance to assigned parking spot.
local dist=element.unit:GetCoordinate():Get2DDistance(element.parking.Coordinate)
-- If distance >10 meters, we consider the unit as taxiing.
-- TODO: Check distance threshold! If element is taxiing, the parking spot is free again.
-- When the next plane is spawned on this spot, collisions should be avoided!
if dist>10 then
if element.status==OPSGROUP.ElementStatus.ENGINEON then
self:ElementTaxiing(element)
end
end end
else
--self:E(self.lid..string.format("Element %s is in PARKING queue but has no parking spot assigned!", element.name))
end end
end end
-- TODO: _CheckParking() function
-- Check if flight began to taxi (if it was parking).
if self:IsParking() then
for _,_element in pairs(self.elements) do
local element=_element --Ops.OpsGroup#OPSGROUP.Element
if element.parking then
-- Get distance to assigned parking spot.
local dist=element.unit:GetCoordinate():Get2DDistance(element.parking.Coordinate)
-- If distance >10 meters, we consider the unit as taxiing.
-- TODO: Check distance threshold! If element is taxiing, the parking spot is free again.
-- When the next plane is spawned on this spot, collisions should be avoided!
if dist>10 then
if element.status==OPSGROUP.ElementStatus.ENGINEON then
self:ElementTaxiing(element)
end
end
else
--self:E(self.lid..string.format("Element %s is in PARKING queue but has no parking spot assigned!", element.name))
end
end
end
end end
--- ---

View File

@ -78,6 +78,7 @@ function LEGION:New(WarehouseName, LegionName)
-- Defaults: -- Defaults:
-- TODO: What? -- TODO: What?
self:SetMarker(false)
-- Add FSM transitions. -- Add FSM transitions.
-- From State --> Event --> To State -- From State --> Event --> To State
@ -930,6 +931,16 @@ function LEGION:onafterOpsOnMission(From, Event, To, OpsGroup, Mission)
--TODO: Flotilla --TODO: Flotilla
end end
-- Trigger event for chief.
if self.chief then
self.chief:OpsOnMission(OpsGroup, Mission)
end
-- Trigger event for commander.
if self.commander then
self.commander:OpsOnMission(OpsGroup, Mission)
end
end end
--- On after "NewAsset" event. Asset is added to the given cohort (asset assignment). --- On after "NewAsset" event. Asset is added to the given cohort (asset assignment).

View File

@ -477,13 +477,12 @@ OPSGROUP.version="0.7.5"
-- TODO: Invisible/immortal. -- TODO: Invisible/immortal.
-- TODO: F10 menu. -- TODO: F10 menu.
-- TODO: Add pseudo function. -- TODO: Add pseudo function.
-- TODO: Afterburner restrict -- TODO: Afterburner restrict.
-- TODO: What more options? -- TODO: What more options?
-- TODO: Damage? -- TODO: Damage?
-- TODO: Shot events? -- TODO: Shot events?
-- TODO: Marks to add waypoints/tasks on-the-fly. -- TODO: Marks to add waypoints/tasks on-the-fly.
-- DONE: Options EPLRS -- DONE: Options EPLRS
-- DONE: A lot.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor -- Constructor
@ -849,6 +848,7 @@ function OPSGROUP:GetLifePoints(Element)
if unit then if unit then
life=unit:GetLife() life=unit:GetLife()
life0=unit:GetLife0() life0=unit:GetLife0()
life=math.min(life, life0) -- Some units have more life than life0 returns!
end end
else else
@ -5901,6 +5901,33 @@ function OPSGROUP:onafterInUtero(From, Event, To)
--TODO: set element status to inutero --TODO: set element status to inutero
end end
--- On after "Damaged" event.
-- @param #OPSGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function OPSGROUP:onafterDamaged(From, Event, To)
self:T(self.lid..string.format("Group damaged at t=%.3f", timer.getTime()))
--[[
local lifemin=nil
for _,_element in pairs(self.elements) do
local element=_element --#OPSGROUP.Element
if element.status~=OPSGROUP.ElementStatus.DEAD and element.status~=OPSGROUP.ElementStatus.INUTERO then
local life, life0=self:GetLifePoints(element)
if lifemin==nil or life<lifemin then
lifemin=life
end
end
end
if lifemin and lifemin/self.life<0.5 then
self:RTB()
end
]]
end
--- On after "Destroyed" event. --- On after "Destroyed" event.
-- @param #OPSGROUP self -- @param #OPSGROUP self
-- @param #string From From state. -- @param #string From From state.
@ -7064,16 +7091,19 @@ function OPSGROUP:onafterPickup(From, Event, To)
-- Get a (random) pre-defined transport path. -- Get a (random) pre-defined transport path.
local path=self.cargoTransport:_GetPathPickup(self.cargoTZC) local path=self.cargoTransport:_GetPathPickup(self.cargoTZC)
-- Formation used to go to the pickup zone..
local Formation=self.cargoTransport:_GetFormationPickup(self.cargoTZC)
if path then if path then
-- Loop over coordinates. -- Loop over coordinates.
for i,coordinate in pairs(path) do for i,coordinate in pairs(path) do
local waypoint=ARMYGROUP.AddWaypoint(self, coordinate, nil, uid) ; waypoint.temp=true local waypoint=ARMYGROUP.AddWaypoint(self, coordinate, nil, uid, Formation) ; waypoint.temp=true
uid=waypoint.uid uid=waypoint.uid
end end
end end
-- ARMYGROUP -- ARMYGROUP
local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, nil, uid) ; waypoint.detour=1 local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, nil, uid, Formation) ; waypoint.detour=1
-- Give cruise command. -- Give cruise command.
self:__Cruise(-2) self:__Cruise(-2)
@ -7404,16 +7434,19 @@ function OPSGROUP:onafterTransport(From, Event, To)
-- Get transport path. -- Get transport path.
local path=self.cargoTransport:_GetPathTransport(self.cargoTZC) local path=self.cargoTransport:_GetPathTransport(self.cargoTZC)
-- Formation used for transporting.
local Formation=self.cargoTransport:_GetFormationTransport(self.cargoTZC)
if path then if path then
-- Loop over coordinates. -- Loop over coordinates.
for i,coordinate in pairs(path) do for i,coordinate in pairs(path) do
local waypoint=ARMYGROUP.AddWaypoint(self, coordinate, nil, uid) ; waypoint.temp=true local waypoint=ARMYGROUP.AddWaypoint(self, coordinate, nil, uid, Formation) ; waypoint.temp=true
uid=waypoint.uid uid=waypoint.uid
end end
end end
-- ARMYGROUP -- ARMYGROUP
local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, ENUMS.Formation.Vehicle.OnRoad) ; waypoint.detour=1 local waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, nil, self:GetWaypointCurrent().uid, Formation) ; waypoint.detour=1
-- Give cruise command. -- Give cruise command.
self:Cruise() self:Cruise()
@ -8022,7 +8055,7 @@ function OPSGROUP:onafterBoard(From, Event, To, CarrierGroup, Carrier)
self:T(self.lid.."Carrier not ready for boarding yet ==> repeating boarding call in 10 sec") self:T(self.lid.."Carrier not ready for boarding yet ==> repeating boarding call in 10 sec")
self:__Board(-10, CarrierGroup, Carrier) self:__Board(-10, CarrierGroup, Carrier)
-- Set carrier. As long as the group is not loaded, we only reserve the cargo space.´ -- Set carrier. As long as the group is not loaded, we only reserve the cargo space.<EFBFBD>
CarrierGroup:_AddCargobay(self, Carrier, true) CarrierGroup:_AddCargobay(self, Carrier, true)
end end
@ -10767,7 +10800,8 @@ function OPSGROUP:_AddElementByName(unitname)
if unit then if unit then
-- Get unit template. -- Get unit template.
local unittemplate=unit:GetTemplate() --local unittemplate=unit:GetTemplate()
local unittemplate=_DATABASE:GetUnitTemplateFromUnitName(unitname)
-- Element table. -- Element table.
local element={} --#OPSGROUP.Element local element={} --#OPSGROUP.Element
@ -10781,7 +10815,7 @@ function OPSGROUP:_AddElementByName(unitname)
element.DCSunit=Unit.getByName(unitname) element.DCSunit=Unit.getByName(unitname)
element.gid=element.DCSunit:getNumber() element.gid=element.DCSunit:getNumber()
element.uid=element.DCSunit:getID() element.uid=element.DCSunit:getID()
element.group=unit:GetGroup() --element.group=unit:GetGroup()
element.opsgroup=self element.opsgroup=self
-- Skill etc. -- Skill etc.

View File

@ -171,6 +171,8 @@ OPSTRANSPORT.Status={
-- @field #boolean disembarkActivation If true, troops are spawned in late activated state when disembarked from carrier. -- @field #boolean disembarkActivation If true, troops are spawned in late activated state when disembarked from carrier.
-- @field #boolean disembarkInUtero If true, troops are disembarked "in utero". -- @field #boolean disembarkInUtero If true, troops are disembarked "in utero".
-- @field #boolean assets Cargo assets. -- @field #boolean assets Cargo assets.
-- @field #number PickupFormation Formation used to pickup.
-- @field #number TransportFormation Formation used to transport.
--- Path used for pickup or transport. --- Path used for pickup or transport.
-- @type OPSTRANSPORT.Path -- @type OPSTRANSPORT.Path
@ -194,6 +196,7 @@ OPSTRANSPORT.version="0.5.0"
-- TODO list -- TODO list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Trains.
-- TODO: Special transport cohorts/legions. Similar to mission. -- TODO: Special transport cohorts/legions. Similar to mission.
-- TODO: Stop/abort transport. -- TODO: Stop/abort transport.
-- DONE: Allow multiple pickup/depoly zones. -- DONE: Allow multiple pickup/depoly zones.
@ -749,6 +752,61 @@ function OPSTRANSPORT:GetDisembarkInUtero(TransportZoneCombo)
return TransportZoneCombo.disembarkInUtero return TransportZoneCombo.disembarkInUtero
end end
--- Set pickup formation.
-- @param #OPSTRANSPORT self
-- @param #number Formation Pickup formation.
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
-- @return #OPSTRANSPORT self
function OPSTRANSPORT:SetFormationPickup(Formation, TransportZoneCombo)
-- Use default TZC if no transport zone combo is provided.
TransportZoneCombo=TransportZoneCombo or self.tzcDefault
TransportZoneCombo.PickupFormation=Formation
return self
end
--- Get pickup formation.
-- @param #OPSTRANSPORT self
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
-- @return #number Formation.
function OPSTRANSPORT:_GetFormationPickup(TransportZoneCombo)
-- Use default TZC if no transport zone combo is provided.
TransportZoneCombo=TransportZoneCombo or self.tzcDefault
return TransportZoneCombo.PickupFormation
end
--- Set transport formation.
-- @param #OPSTRANSPORT self
-- @param #number Formation Pickup formation.
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
-- @return #OPSTRANSPORT self
function OPSTRANSPORT:SetFormationTransport(Formation, TransportZoneCombo)
-- Use default TZC if no transport zone combo is provided.
TransportZoneCombo=TransportZoneCombo or self.tzcDefault
TransportZoneCombo.TransportFormation=Formation
return self
end
--- Get transport formation.
-- @param #OPSTRANSPORT self
-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo.
-- @return #number Formation.
function OPSTRANSPORT:_GetFormationTransport(TransportZoneCombo)
-- Use default TZC if no transport zone combo is provided.
TransportZoneCombo=TransportZoneCombo or self.tzcDefault
return TransportZoneCombo.TransportFormation
end
--- Set required cargo. This is a list of cargo groups that need to be loaded before the **first** transport will start. --- Set required cargo. This is a list of cargo groups that need to be loaded before the **first** transport will start.
-- @param #OPSTRANSPORT self -- @param #OPSTRANSPORT self

View File

@ -36,8 +36,9 @@
-- @field #boolean neutralCanCapture Neutral units can capture. Default `false`. -- @field #boolean neutralCanCapture Neutral units can capture. Default `false`.
-- @field #boolean drawZone If `true`, draw the zone on the F10 map. -- @field #boolean drawZone If `true`, draw the zone on the F10 map.
-- @field #boolean markZone If `true`, mark the zone on the F10 map. -- @field #boolean markZone If `true`, mark the zone on the F10 map.
-- @field #number prio Priority of the zone (for CHIEF queue). -- @field Wrapper.Marker#MARKER marker Marker on the F10 map.
-- @field #number importance Importance of the zone (for CHIEF queue). -- @field #string markerText Text shown in the maker.
-- @field #table chiefs Chiefs that monitor this zone.
-- @extends Core.Fsm#FSM -- @extends Core.Fsm#FSM
--- Be surprised! --- Be surprised!
@ -59,23 +60,24 @@ OPSZONE = {
Nred = 0, Nred = 0,
Nblu = 0, Nblu = 0,
Nnut = 0, Nnut = 0,
chiefs = {},
} }
--- OPSZONE class version. --- OPSZONE class version.
-- @field #string version -- @field #string version
OPSZONE.version="0.1.0" OPSZONE.version="0.2.0"
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- ToDo list -- ToDo list
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Capture airbases.
-- TODO: Pause/unpause evaluations. -- TODO: Pause/unpause evaluations.
-- TODO: Capture time, i.e. time how long a single coalition has to be inside the zone to capture it. -- TODO: Capture time, i.e. time how long a single coalition has to be inside the zone to capture it.
-- TODO: Can neutrals capture? No, since they are _neutral_! -- TODO: Can neutrals capture? No, since they are _neutral_!
-- TODO: Can statics capture or hold a zone? No, unless explicitly requested by mission designer.
-- TODO: Differentiate between ground attack and boming by air or arty. -- TODO: Differentiate between ground attack and boming by air or arty.
-- DONE: Capture airbases.
-- DONE: Can statics capture or hold a zone? No, unless explicitly requested by mission designer.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- Constructor -- Constructor
@ -136,22 +138,22 @@ function OPSZONE:New(Zone, CoalitionOwner)
self.ownerCurrent=CoalitionOwner or coalition.side.NEUTRAL self.ownerCurrent=CoalitionOwner or coalition.side.NEUTRAL
self.ownerPrevious=CoalitionOwner or coalition.side.NEUTRAL self.ownerPrevious=CoalitionOwner or coalition.side.NEUTRAL
-- Contested.
self.isContested=false
-- We take the airbase coalition. -- We take the airbase coalition.
if self.airbase then if self.airbase then
self.ownerCurrent=self.airbase:GetCoalition() self.ownerCurrent=self.airbase:GetCoalition()
self.ownerPrevious=self.airbase:GetCoalition() self.ownerPrevious=self.airbase:GetCoalition()
end end
-- Set priority (default 50) and importance (default nil).
self:SetPriority()
self:SetImportance()
-- Set object categories. -- Set object categories.
self:SetObjectCategories() self:SetObjectCategories()
self:SetUnitCategories() self:SetUnitCategories()
-- TODO: make input function -- Draw zone. Default is on.
self.drawZone=true self:SetDrawZone()
self:SetMarkZone(true)
-- Status timer. -- Status timer.
self.timerStatus=TIMER:New(OPSZONE.Status, self) self.timerStatus=TIMER:New(OPSZONE.Status, self)
@ -307,8 +309,14 @@ function OPSZONE:SetVerbosity(VerbosityLevel)
end end
--- Set categories of objects that can capture or hold the zone. --- Set categories of objects that can capture or hold the zone.
--
-- * Default is {Object.Category.UNIT} so only units can capture and hold zones.
-- * Set to `{Object.Category.UNIT, Object.Category.STATIC}` if static objects can capture and hold zones
--
-- Which units can capture zones can be further refined by `:SetUnitCategories()`.
--
-- @param #OPSZONE self -- @param #OPSZONE self
-- @param #table Categories Object categories. Default is `{Object.Category.UNIT, Object.Category.STATIC}`, i.e. UNITs and STATICs. -- @param #table Categories Object categories. Default is `{Object.Category.UNIT}`.
-- @return #OPSZONE self -- @return #OPSZONE self
function OPSZONE:SetObjectCategories(Categories) function OPSZONE:SetObjectCategories(Categories)
@ -349,21 +357,43 @@ function OPSZONE:SetNeutralCanCapture(CanCapture)
return self return self
end end
--- **[CHIEF]** Set mission priority. --- Set if zone is drawn on the F10 map. Color will change depending on current owning coalition.
-- @param #OPSZONE self -- @param #OPSZONE self
-- @param #number Prio Priority 1=high, 100=low. Default 50. -- @param #boolean Switch If `true` or `nil`, draw zone. If `false`, zone is not drawn.
-- @return #OPSZONE self -- @return #OPSZONE self
function OPSZONE:SetPriority(Prio) function OPSZONE:SetDrawZone(Switch)
self.prio=Prio or 50 if Switch==false then
self.drawZone=false
else
self.drawZone=true
end
return self return self
end end
--- **[CHIEF]** Set importance. --- Set if a marker on the F10 map shows the current zone status.
-- @param #OPSZONE self -- @param #OPSZONE self
-- @param #number Importance Number 1-10. If missions with lower value are in the queue, these have to be finished first. Default is `nil`. -- @param #boolean Switch If `true`, zone is marked. If `false` or `nil`, zone is not marked.
-- @param #boolean ReadOnly If `true` or `nil` then mark is read only.
-- @return #OPSZONE self -- @return #OPSZONE self
function OPSZONE:SetImportance(Importance) function OPSZONE:SetMarkZone(Switch, ReadOnly)
self.importance=Importance if Switch then
self.markZone=true
local Coordinate=self:GetCoordinate()
self.markerText=self:_GetMarkerText()
self.marker=self.marker or MARKER:New(Coordinate, self.markerText)
if ReadOnly==false then
self.marker.readonly=false
else
self.marker.readonly=true
end
self.marker:ToAll()
else
if self.marker then
self.marker:Remove()
end
self.marker=nil
self.marker=false
end
return self return self
end end
@ -375,6 +405,21 @@ function OPSZONE:GetOwner()
return self.ownerCurrent return self.ownerCurrent
end end
--- Get coordinate of zone.
-- @param #OPSZONE self
-- @return Core.Point#COORDINATE Coordinate of the zone.
function OPSZONE:GetCoordinate()
local coordinate=self.zone:GetCoordinate()
return coordinate
end
--- Get name.
-- @param #OPSZONE self
-- @return #string Name of the zone.
function OPSZONE:GetName()
return self.zoneName
end
--- Get previous owner of the zone. --- Get previous owner of the zone.
-- @param #OPSZONE self -- @param #OPSZONE self
-- @return #number Previous owner coalition. -- @return #number Previous owner coalition.
@ -477,7 +522,7 @@ function OPSZONE:onafterStart(From, Event, To)
self.timerStatus=self.timerStatus or TIMER:New(OPSZONE.Status, self) self.timerStatus=self.timerStatus or TIMER:New(OPSZONE.Status, self)
-- Status update. -- Status update.
self.timerStatus:Start(1, 60) self.timerStatus:Start(1, 120)
-- Handle base captured event. -- Handle base captured event.
if self.airbase then if self.airbase then
@ -530,6 +575,9 @@ function OPSZONE:Status()
-- Evaluate the scan result. -- Evaluate the scan result.
self:EvaluateZone() self:EvaluateZone()
-- Update F10 marker (only if enabled).
self:_UpdateMarker()
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -551,6 +599,15 @@ function OPSZONE:onafterCaptured(From, Event, To, NewOwnerCoalition)
self.ownerPrevious=self.ownerCurrent self.ownerPrevious=self.ownerCurrent
self.ownerCurrent=NewOwnerCoalition self.ownerCurrent=NewOwnerCoalition
for _,_chief in pairs(self.chiefs) do
local chief=_chief --Ops.Chief#CHIEF
if chief.coalition==self.ownerCurrent then
chief:ZoneCaptured(self)
else
chief:ZoneLost(self)
end
end
end end
--- On after "Empty" event. --- On after "Empty" event.
@ -563,6 +620,12 @@ function OPSZONE:onafterEmpty(From, Event, To)
-- Debug info. -- Debug info.
self:T(self.lid..string.format("Zone is empty EVENT")) self:T(self.lid..string.format("Zone is empty EVENT"))
-- Inform chief.
for _,_chief in pairs(self.chiefs) do
local chief=_chief --Ops.Chief#CHIEF
chief:ZoneEmpty(self)
end
end end
--- On after "Attacked" event. --- On after "Attacked" event.
@ -576,6 +639,16 @@ function OPSZONE:onafterAttacked(From, Event, To, AttackerCoalition)
-- Debug info. -- Debug info.
self:T(self.lid..string.format("Zone is being attacked by coalition=%s!", tostring(AttackerCoalition))) self:T(self.lid..string.format("Zone is being attacked by coalition=%s!", tostring(AttackerCoalition)))
-- Inform chief.
if AttackerCoalition then
for _,_chief in pairs(self.chiefs) do
local chief=_chief --Ops.Chief#CHIEF
if chief.coalition~=AttackerCoalition then
chief:ZoneAttacked(self)
end
end
end
end end
--- On after "Defeated" event. --- On after "Defeated" event.
@ -630,12 +703,14 @@ function OPSZONE:onenterAttacked(From, Event, To)
-- Time stamp when the attack started. -- Time stamp when the attack started.
self.Tattacked=timer.getAbsTime() self.Tattacked=timer.getAbsTime()
-- Draw zone?
if self.drawZone then if self.drawZone then
self.zone:UndrawZone() self.zone:UndrawZone()
-- Color.
local color={1, 204/255, 204/255}
local color={1,204/255,204/255} -- Draw zone.
self.zone:DrawZone(nil, color, 1.0, color, 0.5) self.zone:DrawZone(nil, color, 1.0, color, 0.5)
end end
@ -947,9 +1022,10 @@ function OPSZONE:EvaluateZone()
-- No neutral units in neutral zone any more. -- No neutral units in neutral zone any more.
if Nred>0 and Nblu>0 then if Nred>0 and Nblu>0 then
env.info(self.lid.."FF neutrals left neutral zone and red and blue are present! What to do?") self:T(self.lid.."FF neutrals left neutral zone and red and blue are present! What to do?")
-- TODO Contested! if not self:IsAttacked() then
self:Attacked() self:Attacked()
end
self.isContested=true self.isContested=true
elseif Nred>0 then elseif Nred>0 then
-- Red captured neutral zone. -- Red captured neutral zone.
@ -964,17 +1040,30 @@ function OPSZONE:EvaluateZone()
else else
-- Neutral zone is empty now. -- Neutral zone is empty now.
if not self:IsEmpty() then if not self:IsEmpty() then
self:Emtpy() self:Empty()
end end
end end
--end --end
else else
self:E(self.lid.."ERROR!") self:E(self.lid.."ERROR: Unknown coaliton!")
end end
-- Finally, check airbase coalition
if self.airbase then
-- Current coalition.
local airbasecoalition=self.airbase:GetCoalition()
if airbasecoalition~=self.ownerCurrent then
self:T(self.lid..string.format("Captured airbase %s: Coaltion %d-->%d", self.airbaseName, self.ownerCurrent, airbasecoalition))
self:Captured(airbasecoalition)
end
end
end end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -1062,6 +1151,53 @@ function OPSZONE:_GetZoneColor()
return color return color
end end
--- Update marker on the F10 map.
-- @param #OPSZONE self
function OPSZONE:_UpdateMarker()
if self.markZone then
-- Get marker text.
local text=self:_GetMarkerText()
-- Chck if marker text changed and if so, update the marker.
if text~=self.markerText then
self.markerText=text
self.marker:UpdateText(self.markerText)
end
--TODO: Update position if changed.
end
end
--- Get marker text
-- @param #OPSZONE self
-- @return #string Marker text.
function OPSZONE:_GetMarkerText()
local owner=UTILS.GetCoalitionName(self.ownerCurrent)
local prevowner=UTILS.GetCoalitionName(self.ownerPrevious)
-- Get marker text.
local text=string.format("%s: Owner=%s [%s]\nState=%s [Contested=%s]\nBlue=%d, Red=%d, Neutral=%d",
self.zoneName, owner, prevowner, self:GetState(), tostring(self:IsContested()), self.Nblu, self.Nred, self.Nnut)
return text
end
--- Add a chief that monitors this zone. Chief will be informed about capturing etc.
-- @param #OPSZONE self
-- @param Ops.Chief#CHIEF Chief The chief.
-- @return #table RGB color.
function OPSZONE:_AddChief(Chief)
-- Add chief.
table.insert(self.chiefs, Chief)
end
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------