mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
OPS
- Lots of updates and improvements
This commit is contained in:
parent
3e30d15405
commit
2ae2ee64be
@ -860,6 +860,20 @@ function DATABASE:GetGroupTemplateFromUnitName( UnitName )
|
||||
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.
|
||||
-- @param #DATABASE self
|
||||
-- @param #string ClientName Name of the Client.
|
||||
|
||||
@ -107,14 +107,15 @@ _TIMERID=0
|
||||
|
||||
--- TIMER class version.
|
||||
-- @field #string version
|
||||
TIMER.version="0.1.1"
|
||||
TIMER.version="0.1.2"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: Randomization.
|
||||
-- TODO: Pause/unpause.
|
||||
-- TODO: Write docs.
|
||||
-- DONE: Write docs.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@ -228,6 +229,15 @@ function TIMER:SetMaxFunctionCalls(Nmax)
|
||||
return self
|
||||
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.
|
||||
-- @param #TIMER self
|
||||
-- @return #boolean If `true`, the timer is running.
|
||||
|
||||
@ -139,6 +139,28 @@ AIRWING = {
|
||||
-- @field #number noccupied Number of flights on this patrol point.
|
||||
-- @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.
|
||||
-- @field #string version
|
||||
AIRWING.version="0.9.0"
|
||||
|
||||
@ -361,6 +361,7 @@ function ARMYGROUP:Status()
|
||||
-- Is group alive?
|
||||
local alive=self:IsAlive()
|
||||
|
||||
-- Check that group EXISTS and is ACTIVE.
|
||||
if alive then
|
||||
|
||||
-- Update position etc.
|
||||
@ -396,6 +397,7 @@ function ARMYGROUP:Status()
|
||||
|
||||
end
|
||||
|
||||
-- Check that group EXISTS.
|
||||
if alive~=nil then
|
||||
|
||||
if self.verbose>=1 then
|
||||
@ -1377,6 +1379,7 @@ function ARMYGROUP:_InitGroup(Template)
|
||||
self:_AddElementByName(unit:GetName())
|
||||
end
|
||||
|
||||
|
||||
-- Init done.
|
||||
self.groupinitialized=true
|
||||
|
||||
|
||||
@ -1130,7 +1130,7 @@ end
|
||||
-- @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 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
|
||||
function AUFTRAG:NewCAS(ZoneCAS, Altitude, Speed, Coordinate, Heading, Leg, TargetTypes)
|
||||
|
||||
@ -1718,7 +1718,7 @@ function AUFTRAG:NewONGUARD(Coordinate)
|
||||
mission:_TargetFromObject(Coordinate)
|
||||
|
||||
mission.optionROE=ENUMS.ROE.OpenFire
|
||||
mission.optionAlarm=ENUMS.AlarmState.Red
|
||||
mission.optionAlarm=ENUMS.AlarmState.Auto
|
||||
|
||||
mission.missionFraction=1.0
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -117,11 +117,6 @@ function COHORT:New(TemplateGroupName, Ngroups, CohortName)
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Defaults.
|
||||
self.Ngroups=Ngroups or 3
|
||||
self:SetMissionRange()
|
||||
self:SetSkill(AI.Skill.GOOD)
|
||||
|
||||
-- Generalized attribute.
|
||||
self.attribute=self.templategroup:GetAttribute()
|
||||
|
||||
@ -131,6 +126,24 @@ function COHORT:New(TemplateGroupName, Ngroups, CohortName)
|
||||
-- Aircraft type.
|
||||
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()
|
||||
|
||||
-- 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.
|
||||
-- @param #COHORT self
|
||||
-- @param #number Range Range in NM. Default 100 NM.
|
||||
-- @param #number Range Range in NM. Default 150 NM.
|
||||
-- @return #COHORT self
|
||||
function COHORT:SetMissionRange(Range)
|
||||
self.engageRange=UTILS.NMToMeters(Range or 100)
|
||||
self.engageRange=UTILS.NMToMeters(Range or 150)
|
||||
return self
|
||||
end
|
||||
|
||||
@ -914,6 +927,9 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
|
||||
combatready=false
|
||||
end
|
||||
|
||||
-- Disable this for now as it can cause problems - at least with transport and cargo assets.
|
||||
combatready=false
|
||||
|
||||
-- This asset is "combatready".
|
||||
if combatready then
|
||||
self:I(self.lid.."Adding SPAWNED asset to ANOTHER mission as it is COMBATREADY")
|
||||
|
||||
@ -17,11 +17,14 @@
|
||||
-- @field #string ClassName Name of the class.
|
||||
-- @field #number verbose Verbosity level.
|
||||
-- @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 missionqueue Mission queue.
|
||||
-- @field #table transportqueue Transport queue.
|
||||
-- @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 awacsZones AWACS zones. Each element is of type `#AIRWING.AwacsZone`.
|
||||
-- @field Ops.Chief#CHIEF chief Chief of staff.
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
@ -38,11 +41,13 @@
|
||||
COMMANDER = {
|
||||
ClassName = "COMMANDER",
|
||||
verbose = 0,
|
||||
coalition = nil,
|
||||
legions = {},
|
||||
missionqueue = {},
|
||||
transportqueue = {},
|
||||
rearmingZones = {},
|
||||
refuellingZones = {},
|
||||
awacsZones = {},
|
||||
}
|
||||
|
||||
--- COMMANDER class version.
|
||||
@ -53,9 +58,9 @@ COMMANDER.version="0.1.0"
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: 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.
|
||||
-- TODO: Add ops transports.
|
||||
-- DONE: Improve legion selection. Mostly done!
|
||||
-- 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.
|
||||
-- DONE: Add ops transports.
|
||||
-- DONE: Allow multiple Legions for one 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.
|
||||
-- @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
|
||||
function COMMANDER:New()
|
||||
function COMMANDER:New(Coalition, Alias)
|
||||
|
||||
-- Inherit everything from INTEL class.
|
||||
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.
|
||||
self.lid="COMMANDER | "
|
||||
self.lid=string.format("COMMANDER %s [%s] | ", self.alias, UTILS.GetCoalitionName(self.coalition))
|
||||
|
||||
-- Start state.
|
||||
self:SetStartState("NotReadyYet")
|
||||
@ -89,6 +101,8 @@ function COMMANDER:New()
|
||||
self:AddTransition("*", "TransportAssign", "*") -- Transport is assigned to a or multiple LEGIONs.
|
||||
self:AddTransition("*", "TransportCancel", "*") -- COMMANDER cancels a Transport.
|
||||
|
||||
self:AddTransition("*", "OpsOnMission", "*") -- An OPSGROUP was send on a Mission (AUFTRAG).
|
||||
|
||||
------------------------
|
||||
--- Pseudo Functions ---
|
||||
------------------------
|
||||
@ -207,6 +221,29 @@ function COMMANDER:New()
|
||||
-- @param #string To To state.
|
||||
-- @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
|
||||
end
|
||||
|
||||
@ -223,6 +260,13 @@ function COMMANDER:SetVerbosity(VerbosityLevel)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Get coalition.
|
||||
-- @param #COMMANDER self
|
||||
-- @return #number Coalition.
|
||||
function COMMANDER:GetCoalition()
|
||||
return self.coalition
|
||||
end
|
||||
|
||||
--- Add an AIRWING to the commander.
|
||||
-- @param #COMMANDER self
|
||||
-- @param Ops.AirWing#AIRWING Airwing The airwing to add.
|
||||
@ -268,12 +312,16 @@ end
|
||||
-- @return #COMMANDER self
|
||||
function COMMANDER:AddMission(Mission)
|
||||
|
||||
if not self:IsMission(Mission) then
|
||||
|
||||
Mission.commander=self
|
||||
|
||||
Mission.statusCommander=AUFTRAG.Status.PLANNED
|
||||
|
||||
table.insert(self.missionqueue, Mission)
|
||||
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -368,6 +416,47 @@ function COMMANDER:AddRefuellingZone(RefuellingZone)
|
||||
return rearmingzone
|
||||
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
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -420,7 +509,7 @@ function COMMANDER:onafterStatus(From, Event, To)
|
||||
|
||||
-- Check rearming zones.
|
||||
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.
|
||||
if (not rearmingzone.mission) or rearmingzone.mission:IsOver() then
|
||||
rearmingzone.mission=AUFTRAG:NewAMMOSUPPLY(rearmingzone.zone)
|
||||
@ -430,7 +519,7 @@ function COMMANDER:onafterStatus(From, Event, To)
|
||||
|
||||
-- Check refuelling zones.
|
||||
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.
|
||||
if (not supplyzone.mission) or supplyzone.mission:IsOver() then
|
||||
supplyzone.mission=AUFTRAG:NewFUELSUPPLY(supplyzone.zone)
|
||||
@ -438,6 +527,17 @@ function COMMANDER:onafterStatus(From, Event, To)
|
||||
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
|
||||
---
|
||||
@ -588,6 +688,9 @@ function COMMANDER:onafterMissionAssign(From, Event, To, Legion, Mission)
|
||||
-- Debug info.
|
||||
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.
|
||||
Mission.statusCommander=AUFTRAG.Status.QUEUED
|
||||
|
||||
@ -696,6 +799,18 @@ function COMMANDER:onafterTransportCancel(From, Event, To, Transport)
|
||||
|
||||
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
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@ -796,6 +796,8 @@ function FLIGHTGROUP:Status()
|
||||
-- Is group alive?
|
||||
local alive=self:IsAlive()
|
||||
|
||||
if alive then
|
||||
|
||||
-- Update position.
|
||||
self:_UpdatePosition()
|
||||
|
||||
@ -808,9 +810,17 @@ function FLIGHTGROUP:Status()
|
||||
-- Check damage.
|
||||
self:_CheckDamage()
|
||||
|
||||
---
|
||||
-- Parking
|
||||
---
|
||||
-- TODO: Check if group is waiting?
|
||||
if self:IsWaiting() then
|
||||
if self.Twaiting and self.dTwait then
|
||||
if timer.getAbsTime()>self.Twaiting+self.dTwait then
|
||||
--self.Twaiting=nil
|
||||
--self.dTwait=nil
|
||||
--self:Cruise()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- TODO: _CheckParking() function
|
||||
|
||||
@ -838,6 +848,8 @@ function FLIGHTGROUP:Status()
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
---
|
||||
-- Group
|
||||
---
|
||||
|
||||
@ -78,6 +78,7 @@ function LEGION:New(WarehouseName, LegionName)
|
||||
|
||||
-- Defaults:
|
||||
-- TODO: What?
|
||||
self:SetMarker(false)
|
||||
|
||||
-- Add FSM transitions.
|
||||
-- From State --> Event --> To State
|
||||
@ -930,6 +931,16 @@ function LEGION:onafterOpsOnMission(From, Event, To, OpsGroup, Mission)
|
||||
--TODO: Flotilla
|
||||
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
|
||||
|
||||
--- On after "NewAsset" event. Asset is added to the given cohort (asset assignment).
|
||||
|
||||
@ -477,13 +477,12 @@ OPSGROUP.version="0.7.5"
|
||||
-- TODO: Invisible/immortal.
|
||||
-- TODO: F10 menu.
|
||||
-- TODO: Add pseudo function.
|
||||
-- TODO: Afterburner restrict
|
||||
-- TODO: Afterburner restrict.
|
||||
-- TODO: What more options?
|
||||
-- TODO: Damage?
|
||||
-- TODO: Shot events?
|
||||
-- TODO: Marks to add waypoints/tasks on-the-fly.
|
||||
-- DONE: Options EPLRS
|
||||
-- DONE: A lot.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@ -849,6 +848,7 @@ function OPSGROUP:GetLifePoints(Element)
|
||||
if unit then
|
||||
life=unit:GetLife()
|
||||
life0=unit:GetLife0()
|
||||
life=math.min(life, life0) -- Some units have more life than life0 returns!
|
||||
end
|
||||
|
||||
else
|
||||
@ -5901,6 +5901,33 @@ function OPSGROUP:onafterInUtero(From, Event, To)
|
||||
--TODO: set element status to inutero
|
||||
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.
|
||||
-- @param #OPSGROUP self
|
||||
-- @param #string From From state.
|
||||
@ -7064,16 +7091,19 @@ function OPSGROUP:onafterPickup(From, Event, To)
|
||||
-- Get a (random) pre-defined transport path.
|
||||
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
|
||||
-- Loop over coordinates.
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
-- 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.
|
||||
self:__Cruise(-2)
|
||||
@ -7404,16 +7434,19 @@ function OPSGROUP:onafterTransport(From, Event, To)
|
||||
-- Get transport path.
|
||||
local path=self.cargoTransport:_GetPathTransport(self.cargoTZC)
|
||||
|
||||
-- Formation used for transporting.
|
||||
local Formation=self.cargoTransport:_GetFormationTransport(self.cargoTZC)
|
||||
|
||||
if path then
|
||||
-- Loop over coordinates.
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
-- 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.
|
||||
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:__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)
|
||||
|
||||
end
|
||||
@ -10767,7 +10800,8 @@ function OPSGROUP:_AddElementByName(unitname)
|
||||
if unit then
|
||||
|
||||
-- Get unit template.
|
||||
local unittemplate=unit:GetTemplate()
|
||||
--local unittemplate=unit:GetTemplate()
|
||||
local unittemplate=_DATABASE:GetUnitTemplateFromUnitName(unitname)
|
||||
|
||||
-- Element table.
|
||||
local element={} --#OPSGROUP.Element
|
||||
@ -10781,7 +10815,7 @@ function OPSGROUP:_AddElementByName(unitname)
|
||||
element.DCSunit=Unit.getByName(unitname)
|
||||
element.gid=element.DCSunit:getNumber()
|
||||
element.uid=element.DCSunit:getID()
|
||||
element.group=unit:GetGroup()
|
||||
--element.group=unit:GetGroup()
|
||||
element.opsgroup=self
|
||||
|
||||
-- Skill etc.
|
||||
|
||||
@ -171,6 +171,8 @@ OPSTRANSPORT.Status={
|
||||
-- @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 assets Cargo assets.
|
||||
-- @field #number PickupFormation Formation used to pickup.
|
||||
-- @field #number TransportFormation Formation used to transport.
|
||||
|
||||
--- Path used for pickup or transport.
|
||||
-- @type OPSTRANSPORT.Path
|
||||
@ -194,6 +196,7 @@ OPSTRANSPORT.version="0.5.0"
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: Trains.
|
||||
-- TODO: Special transport cohorts/legions. Similar to mission.
|
||||
-- TODO: Stop/abort transport.
|
||||
-- DONE: Allow multiple pickup/depoly zones.
|
||||
@ -749,6 +752,61 @@ function OPSTRANSPORT:GetDisembarkInUtero(TransportZoneCombo)
|
||||
return TransportZoneCombo.disembarkInUtero
|
||||
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.
|
||||
-- @param #OPSTRANSPORT self
|
||||
|
||||
@ -36,8 +36,9 @@
|
||||
-- @field #boolean neutralCanCapture Neutral units can capture. Default `false`.
|
||||
-- @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 #number prio Priority of the zone (for CHIEF queue).
|
||||
-- @field #number importance Importance of the zone (for CHIEF queue).
|
||||
-- @field Wrapper.Marker#MARKER marker Marker on the F10 map.
|
||||
-- @field #string markerText Text shown in the maker.
|
||||
-- @field #table chiefs Chiefs that monitor this zone.
|
||||
-- @extends Core.Fsm#FSM
|
||||
|
||||
--- Be surprised!
|
||||
@ -59,23 +60,24 @@ OPSZONE = {
|
||||
Nred = 0,
|
||||
Nblu = 0,
|
||||
Nnut = 0,
|
||||
chiefs = {},
|
||||
}
|
||||
|
||||
|
||||
--- OPSZONE class version.
|
||||
-- @field #string version
|
||||
OPSZONE.version="0.1.0"
|
||||
OPSZONE.version="0.2.0"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- ToDo list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: Capture airbases.
|
||||
-- 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: 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.
|
||||
-- DONE: Capture airbases.
|
||||
-- DONE: Can statics capture or hold a zone? No, unless explicitly requested by mission designer.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@ -136,22 +138,22 @@ function OPSZONE:New(Zone, CoalitionOwner)
|
||||
self.ownerCurrent=CoalitionOwner or coalition.side.NEUTRAL
|
||||
self.ownerPrevious=CoalitionOwner or coalition.side.NEUTRAL
|
||||
|
||||
-- Contested.
|
||||
self.isContested=false
|
||||
|
||||
-- We take the airbase coalition.
|
||||
if self.airbase then
|
||||
self.ownerCurrent=self.airbase:GetCoalition()
|
||||
self.ownerPrevious=self.airbase:GetCoalition()
|
||||
end
|
||||
|
||||
-- Set priority (default 50) and importance (default nil).
|
||||
self:SetPriority()
|
||||
self:SetImportance()
|
||||
|
||||
-- Set object categories.
|
||||
self:SetObjectCategories()
|
||||
self:SetUnitCategories()
|
||||
|
||||
-- TODO: make input function
|
||||
self.drawZone=true
|
||||
-- Draw zone. Default is on.
|
||||
self:SetDrawZone()
|
||||
self:SetMarkZone(true)
|
||||
|
||||
-- Status timer.
|
||||
self.timerStatus=TIMER:New(OPSZONE.Status, self)
|
||||
@ -307,8 +309,14 @@ function OPSZONE:SetVerbosity(VerbosityLevel)
|
||||
end
|
||||
|
||||
--- 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 #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
|
||||
function OPSZONE:SetObjectCategories(Categories)
|
||||
|
||||
@ -349,21 +357,43 @@ function OPSZONE:SetNeutralCanCapture(CanCapture)
|
||||
return self
|
||||
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 #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
|
||||
function OPSZONE:SetPriority(Prio)
|
||||
self.prio=Prio or 50
|
||||
function OPSZONE:SetDrawZone(Switch)
|
||||
if Switch==false then
|
||||
self.drawZone=false
|
||||
else
|
||||
self.drawZone=true
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
--- **[CHIEF]** Set importance.
|
||||
--- Set if a marker on the F10 map shows the current zone status.
|
||||
-- @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
|
||||
function OPSZONE:SetImportance(Importance)
|
||||
self.importance=Importance
|
||||
function OPSZONE:SetMarkZone(Switch, ReadOnly)
|
||||
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
|
||||
end
|
||||
|
||||
@ -375,6 +405,21 @@ function OPSZONE:GetOwner()
|
||||
return self.ownerCurrent
|
||||
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.
|
||||
-- @param #OPSZONE self
|
||||
-- @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)
|
||||
|
||||
-- Status update.
|
||||
self.timerStatus:Start(1, 60)
|
||||
self.timerStatus:Start(1, 120)
|
||||
|
||||
-- Handle base captured event.
|
||||
if self.airbase then
|
||||
@ -530,6 +575,9 @@ function OPSZONE:Status()
|
||||
-- Evaluate the scan result.
|
||||
self:EvaluateZone()
|
||||
|
||||
-- Update F10 marker (only if enabled).
|
||||
self:_UpdateMarker()
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -551,6 +599,15 @@ function OPSZONE:onafterCaptured(From, Event, To, NewOwnerCoalition)
|
||||
self.ownerPrevious=self.ownerCurrent
|
||||
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
|
||||
|
||||
--- On after "Empty" event.
|
||||
@ -563,6 +620,12 @@ function OPSZONE:onafterEmpty(From, Event, To)
|
||||
-- Debug info.
|
||||
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
|
||||
|
||||
--- On after "Attacked" event.
|
||||
@ -576,6 +639,16 @@ function OPSZONE:onafterAttacked(From, Event, To, AttackerCoalition)
|
||||
-- Debug info.
|
||||
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
|
||||
|
||||
--- On after "Defeated" event.
|
||||
@ -630,12 +703,14 @@ function OPSZONE:onenterAttacked(From, Event, To)
|
||||
-- Time stamp when the attack started.
|
||||
self.Tattacked=timer.getAbsTime()
|
||||
|
||||
-- Draw zone?
|
||||
if self.drawZone then
|
||||
self.zone:UndrawZone()
|
||||
|
||||
|
||||
-- Color.
|
||||
local color={1, 204/255, 204/255}
|
||||
|
||||
-- Draw zone.
|
||||
self.zone:DrawZone(nil, color, 1.0, color, 0.5)
|
||||
end
|
||||
|
||||
@ -947,9 +1022,10 @@ function OPSZONE:EvaluateZone()
|
||||
-- No neutral units in neutral zone any more.
|
||||
|
||||
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?")
|
||||
-- TODO Contested!
|
||||
self:T(self.lid.."FF neutrals left neutral zone and red and blue are present! What to do?")
|
||||
if not self:IsAttacked() then
|
||||
self:Attacked()
|
||||
end
|
||||
self.isContested=true
|
||||
elseif Nred>0 then
|
||||
-- Red captured neutral zone.
|
||||
@ -964,17 +1040,30 @@ function OPSZONE:EvaluateZone()
|
||||
else
|
||||
-- Neutral zone is empty now.
|
||||
if not self:IsEmpty() then
|
||||
self:Emtpy()
|
||||
self:Empty()
|
||||
end
|
||||
end
|
||||
|
||||
--end
|
||||
|
||||
else
|
||||
self:E(self.lid.."ERROR!")
|
||||
self:E(self.lid.."ERROR: Unknown coaliton!")
|
||||
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
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@ -1062,6 +1151,53 @@ function OPSZONE:_GetZoneColor()
|
||||
return color
|
||||
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
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user