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
|
||||||
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.
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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
|
||||||
@ -1376,6 +1378,7 @@ function ARMYGROUP:_InitGroup(Template)
|
|||||||
for _,unit in pairs(units) do
|
for _,unit in pairs(units) do
|
||||||
self:_AddElementByName(unit:GetName())
|
self:_AddElementByName(unit:GetName())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Init done.
|
-- Init done.
|
||||||
self.groupinitialized=true
|
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 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
@ -116,12 +116,7 @@ function COHORT:New(TemplateGroupName, Ngroups, CohortName)
|
|||||||
self:E(self.lid..string.format("ERROR: Template group %s does not exist!", tostring(self.templatename)))
|
self:E(self.lid..string.format("ERROR: Template group %s does not exist!", tostring(self.templatename)))
|
||||||
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()
|
||||||
|
|
||||||
@ -130,7 +125,25 @@ 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
|
||||||
|
|
||||||
@ -913,6 +926,9 @@ function COHORT:RecruitAssets(MissionType, Npayloads)
|
|||||||
if flightgroup:IsCargo() or flightgroup:IsBoarding() or flightgroup:IsAwaitingLift() then
|
if flightgroup:IsCargo() or flightgroup:IsBoarding() or flightgroup:IsAwaitingLift() then
|
||||||
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
|
||||||
|
|||||||
@ -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
|
|
||||||
|
|
||||||
table.insert(self.missionqueue, Mission)
|
Mission.commander=self
|
||||||
|
|
||||||
|
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,13 +519,24 @@ 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)
|
||||||
self:AddMission(supplyzone.mission)
|
self:AddMission(supplyzone.mission)
|
||||||
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
|
||||||
@ -587,7 +687,10 @@ 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
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@ -794,50 +794,62 @@ function FLIGHTGROUP:Status()
|
|||||||
local fsmstate=self:GetState()
|
local fsmstate=self:GetState()
|
||||||
|
|
||||||
-- Is group alive?
|
-- Is group alive?
|
||||||
local alive=self:IsAlive()
|
local alive=self:IsAlive()
|
||||||
|
|
||||||
-- Update position.
|
|
||||||
self:_UpdatePosition()
|
|
||||||
|
|
||||||
-- Check if group has detected any units.
|
|
||||||
self:_CheckDetectedUnits()
|
|
||||||
|
|
||||||
-- Check ammo status.
|
if alive then
|
||||||
self:_CheckAmmoStatus()
|
|
||||||
|
-- Update position.
|
||||||
|
self:_UpdatePosition()
|
||||||
|
|
||||||
-- Check damage.
|
-- Check if group has detected any units.
|
||||||
self:_CheckDamage()
|
self:_CheckDetectedUnits()
|
||||||
|
|
||||||
---
|
-- Check ammo status.
|
||||||
-- Parking
|
self:_CheckAmmoStatus()
|
||||||
---
|
|
||||||
|
-- Check damage.
|
||||||
-- TODO: _CheckParking() function
|
self:_CheckDamage()
|
||||||
|
|
||||||
-- Check if flight began to taxi (if it was parking).
|
-- TODO: Check if group is waiting?
|
||||||
if self:IsParking() then
|
if self:IsWaiting() then
|
||||||
for _,_element in pairs(self.elements) do
|
if self.Twaiting and self.dTwait then
|
||||||
local element=_element --Ops.OpsGroup#OPSGROUP.Element
|
if timer.getAbsTime()>self.Twaiting+self.dTwait then
|
||||||
if element.parking then
|
--self.Twaiting=nil
|
||||||
|
--self.dTwait=nil
|
||||||
-- Get distance to assigned parking spot.
|
--self:Cruise()
|
||||||
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
|
||||||
|
|
||||||
---
|
---
|
||||||
-- Group
|
-- Group
|
||||||
---
|
---
|
||||||
|
|||||||
@ -77,7 +77,8 @@ function LEGION:New(WarehouseName, LegionName)
|
|||||||
self.lid=string.format("LEGION %s | ", self.alias)
|
self.lid=string.format("LEGION %s | ", self.alias)
|
||||||
|
|
||||||
-- 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
|
||||||
@ -929,6 +930,16 @@ function LEGION:onafterOpsOnMission(From, Event, To, OpsGroup, Mission)
|
|||||||
else
|
else
|
||||||
--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
|
||||||
|
|
||||||
|
|||||||
@ -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.
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
@ -529,6 +574,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
|
||||||
|
|
||||||
@ -550,6 +598,15 @@ function OPSZONE:onafterCaptured(From, Event, To, NewOwnerCoalition)
|
|||||||
-- Set owners.
|
-- Set owners.
|
||||||
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
|
||||||
|
|
||||||
@ -562,6 +619,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
|
||||||
|
|
||||||
@ -575,6 +638,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
|
||||||
|
|
||||||
@ -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
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user