- Changed mission, legion in MissionAssign functions (LEGION, COMMANDER, CHIEF)
- OPSTRANSPORT: improved TZC selection
- ARMYGROUP needs to
This commit is contained in:
Frank 2021-10-11 21:28:35 +02:00
parent f6dce02203
commit 0f4d466953
8 changed files with 602 additions and 183 deletions

View File

@ -134,17 +134,234 @@ function ARMYGROUP:New(group)
------------------------
--- Pseudo Functions ---
------------------------
--- Triggers the FSM event "Stop". Stops the ARMYGROUP and all its event handlers.
--- Triggers the FSM event "Cruise".
-- @function [parent=#ARMYGROUP] Cruise
-- @param #ARMYGROUP self
-- @param #number Speed Speed in knots until next waypoint is reached.
-- @param #number Formation Formation.
--- Triggers the FSM event "Stop" after a delay. Stops the ARMYGROUP and all its event handlers.
-- @function [parent=#ARMYGROUP] __Stop
--- Triggers the FSM event "Cruise" after a delay.
-- @function [parent=#ARMYGROUP] __Cruise
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
-- TODO: Add pseudo functions.
-- @param #number Speed Speed in knots until next waypoint is reached.
-- @param #number Formation Formation.
--- On after "Cruise" event.
-- @function [parent=#ARMYGROUP] OnAfterCruise
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #number Speed Speed in knots until next waypoint is reached.
-- @param #number Formation Formation.
--- Triggers the FSM event "FullStop".
-- @function [parent=#ARMYGROUP] FullStop
-- @param #ARMYGROUP self
--- Triggers the FSM event "FullStop" after a delay.
-- @function [parent=#ARMYGROUP] __FullStop
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "FullStop" event.
-- @function [parent=#ARMYGROUP] OnAfterFullStop
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "RTZ".
-- @function [parent=#ARMYGROUP] RTZ
-- @param #ARMYGROUP self
--- Triggers the FSM event "RTZ" after a delay.
-- @function [parent=#ARMYGROUP] __RTZ
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "RTZ" event.
-- @function [parent=#ARMYGROUP] OnAfterRTZ
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Returned".
-- @function [parent=#ARMYGROUP] Returned
-- @param #ARMYGROUP self
--- Triggers the FSM event "Returned" after a delay.
-- @function [parent=#ARMYGROUP] __Returned
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "Returned" event.
-- @function [parent=#ARMYGROUP] OnAfterReturned
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Detour".
-- @function [parent=#ARMYGROUP] Detour
-- @param #ARMYGROUP self
--- Triggers the FSM event "Detour" after a delay.
-- @function [parent=#ARMYGROUP] __Detour
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "Detour" event.
-- @function [parent=#ARMYGROUP] OnAfterDetour
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "DetourReached".
-- @function [parent=#ARMYGROUP] DetourReached
-- @param #ARMYGROUP self
--- Triggers the FSM event "DetourReached" after a delay.
-- @function [parent=#ARMYGROUP] __DetourReached
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "DetourReached" event.
-- @function [parent=#ARMYGROUP] OnAfterDetourReached
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Retreat".
-- @function [parent=#ARMYGROUP] Retreat
-- @param #ARMYGROUP self
--- Triggers the FSM event "Retreat" after a delay.
-- @function [parent=#ARMYGROUP] __Retreat
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "Retreat" event.
-- @function [parent=#ARMYGROUP] OnAfterRetreat
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Retreated".
-- @function [parent=#ARMYGROUP] Retreated
-- @param #ARMYGROUP self
--- Triggers the FSM event "Retreated" after a delay.
-- @function [parent=#ARMYGROUP] __Retreated
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "Retreated" event.
-- @function [parent=#ARMYGROUP] OnAfterRetreated
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "EngageTarget".
-- @function [parent=#ARMYGROUP] EngageTarget
-- @param #ARMYGROUP self
--- Triggers the FSM event "EngageTarget" after a delay.
-- @function [parent=#ARMYGROUP] __EngageTarget
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "EngageTarget" event.
-- @function [parent=#ARMYGROUP] OnAfterEngageTarget
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Disengage".
-- @function [parent=#ARMYGROUP] Disengage
-- @param #ARMYGROUP self
--- Triggers the FSM event "Disengage" after a delay.
-- @function [parent=#ARMYGROUP] __Disengage
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "Disengage" event.
-- @function [parent=#ARMYGROUP] OnAfterDisengage
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Rearm".
-- @function [parent=#ARMYGROUP] Rearm
-- @param #ARMYGROUP self
--- Triggers the FSM event "Rearm" after a delay.
-- @function [parent=#ARMYGROUP] __Rearm
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "Rearm" event.
-- @function [parent=#ARMYGROUP] OnAfterRearm
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Rearming".
-- @function [parent=#ARMYGROUP] Rearming
-- @param #ARMYGROUP self
--- Triggers the FSM event "Rearming" after a delay.
-- @function [parent=#ARMYGROUP] __Rearming
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "Rearming" event.
-- @function [parent=#ARMYGROUP] OnAfterRearming
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Rearmed".
-- @function [parent=#ARMYGROUP] Rearmed
-- @param #ARMYGROUP self
--- Triggers the FSM event "Rearmed" after a delay.
-- @function [parent=#ARMYGROUP] __Rearmed
-- @param #ARMYGROUP self
-- @param #number delay Delay in seconds.
--- On after "Rearmed" event.
-- @function [parent=#ARMYGROUP] OnAfterRearmed
-- @param #ARMYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- TODO: Add pseudo functions.
-- Init waypoints.
self:_InitWaypoints()
@ -598,8 +815,10 @@ function ARMYGROUP:onafterSpawned(From, Event, To)
-- Update route.
if #self.waypoints>1 then
self:T(self.lid.."Got waypoints on spawn ==> Cruise in -0.1 sec!")
self:__Cruise(-0.1, nil, self.option.Formation)
else
self:T(self.lid.."No waypoints on spawn ==> Full Stop!")
self:FullStop()
end
@ -629,6 +848,8 @@ function ARMYGROUP:onbeforeUpdateRoute(From, Event, To, n, N, Speed, Formation)
elseif self:IsStopped() then
self:E(self.lid.."Update route denied. Group is STOPPED!")
return false
elseif self:IsHolding() then
self:E(self.lid.."Update route denied. Group is holding position! Use Cruise()")
end
return true
end
@ -724,10 +945,10 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
-- Debug output.
if false then
if self.verbose>=5 then
for i,_wp in pairs(waypoints) do
local wp=_wp
local text=string.format("WP #%d UID=%d type=%s: Speed=%d m/s, alt=%d m, Action=%s", i, wp.uid and wp.uid or 0, wp.type, wp.speed, wp.alt, wp.action)
local text=string.format("WP #%d UID=%d type=%s: Speed=%d m/s, alt=%d m, Action=%s", i, wp.uid and wp.uid or -1, wp.type, wp.speed, wp.alt, wp.action)
self:T(text)
end
end
@ -1376,7 +1597,8 @@ function ARMYGROUP:_InitGroup(Template)
-- Add elemets.
for _,unit in pairs(units) do
self:_AddElementByName(unit:GetName())
local unitname=unit:GetName()
self:_AddElementByName(unitname)
end

View File

@ -2255,11 +2255,11 @@ end
--- Attach OPS transport to the mission. Mission assets will be transported before the mission is started at the OPSGROUP level.
-- @param #AUFTRAG self
-- @param Core.Zone#ZONE DeployZone Zone where assets are deployed.
-- @param Core.Zone#ZONE DisembarkZone Zone where assets are disembarked to.
-- @param #number NcarriersMin Number of carriers *at least* required. Default 1.
-- @param #number NcarriersMax Number of carriers *at most* used for transportation. Default is same as `NcarriersMin`.
-- @param Core.Zone#ZONE DisembarkZone Zone where assets are disembarked to.
-- @return #AUFTRAG self
function AUFTRAG:SetRequiredTransport(DeployZone, DisembarkZone, NcarriersMin, NcarriersMax)
function AUFTRAG:SetRequiredTransport(DeployZone, NcarriersMin, NcarriersMax, DisembarkZone)
-- OPS transport from pickup to deploy zone.
self.transportDeployZone=DeployZone

View File

@ -235,15 +235,15 @@ function CHIEF:New(Coalition, AgentSet, Alias)
--- Triggers the FSM event "MissionAssign".
-- @function [parent=#CHIEF] MissionAssign
-- @param #CHIEF self
-- @param Ops.Legion#LEGION Legion The legion.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The Legion(s) to which the mission is assigned.
--- Triggers the FSM event "MissionAssign" after a delay.
-- @function [parent=#CHIEF] __MissionAssign
-- @param #CHIEF self
-- @param #number delay Delay in seconds.
-- @param Ops.Legion#LEGION Legion The legion.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The Legion(s) to which the mission is assigned.
--- On after "MissionAssign" event.
-- @function [parent=#CHIEF] OnAfterMissionAssign
@ -251,9 +251,8 @@ function CHIEF:New(Coalition, AgentSet, Alias)
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The legion.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The Legion(s) to which the mission is assigned.
--- Triggers the FSM event "MissionCancel".
-- @function [parent=#CHIEF] MissionCancel
@ -1183,15 +1182,15 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The legion.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
function CHIEF:onafterMissionAssign(From, Event, To, Legion, Mission)
-- @param #table Legions The Legion(s) to which the mission is assigned.
function CHIEF:onafterMissionAssign(From, Event, To, Mission, Legions)
if self.commander then
self:I(self.lid..string.format("Assigning mission %s (%s) to COMMANDER", Mission.name, Mission.type))
Mission.chief=self
Mission.statusChief=AUFTRAG.Status.QUEUED
self.commander:MissionAssign(Legion, Mission)
self.commander:MissionAssign(Mission, Legions)
else
self:E(self.lid..string.format("Mission cannot be assigned as no COMMANDER is defined!"))
end
@ -1523,11 +1522,9 @@ function CHIEF:CheckTargetQueue()
-- Mission parameters.
mission.prio=target.prio
mission.importance=target.importance
-- Assign mission to legions.
for _,Legion in pairs(Legions) do
self:MissionAssign(Legion, mission)
end
-- Assign mission to legions.
self:MissionAssign(mission, Legions)
-- Only ONE target is assigned per check.
return
@ -2054,10 +2051,7 @@ function CHIEF:RecruitAssetsForZone(StratZone, MissionType, NassetsMin, NassetsM
mission.opstransport=transport
-- Assign mission to legions.
for _,_legion in pairs(legions) do
local legion=_legion --Ops.Legion#LEGION
self:MissionAssign(legion, mission)
end
self:MissionAssign(mission, legions)
-- Attach mission to ops zone.
-- TODO: Need a better way!
@ -2078,10 +2072,7 @@ function CHIEF:RecruitAssetsForZone(StratZone, MissionType, NassetsMin, NassetsM
end
-- Assign mission to legions.
for _,_legion in pairs(legions) do
local legion=_legion --Ops.Legion#LEGION
self:MissionAssign(legion, mission)
end
self:MissionAssign(mission, legions)
-- Attach mission to ops zone.
-- TODO: Need a better way!

View File

@ -1,4 +1,4 @@
--- **Ops** - Commander of Airwings, Brigades and Flotillas.
--- **Ops** - Commander of Airwings, Brigades and Fleets.
--
-- **Main Features:**
--
@ -36,8 +36,81 @@
--
-- # The COMMANDER Concept
--
-- A commander is the head of legions. He/she will find the best LEGIONs to perform an assigned AUFTRAG (mission).
-- A commander is the head of legions. He/she will find the best LEGIONs to perform an assigned AUFTRAG (mission) or OPSTRANSPORT.
-- A legion can be an AIRWING, BRIGADE or FLEET.
--
-- # Constructor
--
-- A new CHIEF object is created with the @{#CHIEF.New}(*Coalition, Alias*) function, where the parameter *Coalition* is the coalition side.
-- It can be `coalition.side.RED`, `coalition.side.BLUE` or `coalition.side.NEUTRAL`. This parameter is mandatory.
-- The second parameter *Alias* is optional and can be used to give the COMMANDER a "name", which is used for output in the dcs.log file.
--
-- local myCommander=COMANDER:New(coalition.side.BLUE, "General Patton")
--
-- # Adding Legions
--
-- Legions, i.e. AIRWINGS, BRIGADES and FLEETS can be added via the @{#COMMANDER.AddLegion}(*Legion*) command:
--
-- myCommander:AddLegion(myLegion)
--
-- ## Adding Airwings
--
-- It is also possible to use @{#COMMANDER.AddAirwing}(*myAirwing*) function. This does the same as the `AddLegion` function but might be a bit more intuitive.
--
-- ## Adding Brigades
--
-- It is also possible to use @{#COMMANDER.AddBrigade}(*myBrigade*) function. This does the same as the `AddLegion` function but might be a bit more intuitive.
--
-- ## Adding Fleets
--
-- It is also possible to use @{#COMMANDER.AddFleet}(*myFleet*) function. This does the same as the `AddLegion` function but might be a bit more intuitive.
--
-- # Adding Missions
--
-- Mission can be added via the @{#COMMANDER.AddMission}(*myMission*) function.
--
-- # Adding OPS Transports
--
-- Transportation assignments can be added via the @{#COMMANDER.AddOpsTransport}(*myTransport*) function.
--
-- # Adding CAP Zones
--
-- A CAP zone can be added via the @{#COMMANDER.AddCapZone}() function.
--
-- # Adding Rearming Zones
--
-- A rearming zone can be added via the @{#COMMANDER.AddRearmingZone}() function.
--
-- # Adding Refuelling Zones
--
-- A refuelling zone can be added via the @{#COMMANDER.AddRefuellingZone}() function.
--
--
-- # FSM Events
--
-- The COMMANDER will
--
-- # OPSGROUP on Mission
--
-- Whenever an OPSGROUP (FLIGHTGROUP, ARMYGROUP or NAVYGROUP) is send on a mission, the `OnAfterOpsOnMission()` event is triggered.
-- Mission designers can hook into the event with the @{#COMMANDER.OnAfterOpsOnMission}() function
--
-- function myCommander:OnAfterOpsOnMission(From, Event, To, OpsGroup, Mission)
-- -- Your code
-- end
--
-- # Canceling a Mission
--
-- A mission can be cancelled with the @{#COMMMANDER.MissionCancel}() function
--
-- myCommander:MissionCancel(myMission)
--
-- or
-- myCommander:__MissionCancel(5*60, myMission)
--
-- The last commander cancels the mission after 5 minutes (300 seconds).
--
-- The cancel command will be forwarded to all assigned legions and OPS groups, which will abort their mission or remove it from their queue.
--
-- @field #COMMANDER
COMMANDER = {
@ -62,8 +135,8 @@ COMMANDER.version="0.1.0"
-- TODO list
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Add CAP zones.
-- TODO: Add tanker zones.
-- DONE: Add CAP zones.
-- DONE: Add tanker zones.
-- 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.
@ -83,11 +156,28 @@ function COMMANDER:New(Coalition, Alias)
-- Inherit everything from INTEL class.
local self=BASE:Inherit(self, FSM:New()) --#COMMANDER
if Coalition==nil then
env.error("ERROR: Coalition parameter is nil in COMMANDER:New() call!")
return nil
end
-- Set coaliton.
self.coalition=Coalition
-- Alias name.
self.alias=Alias or string.format("John Doe")
self.alias=Alias
-- Choose a name for red or blue.
if self.alias==nil then
if Coalition==coalition.side.BLUE then
self.alias="George S. Patton"
elseif Coalition==coalition.side.RED then
self.alias="Georgy Zhukov"
elseif Coalition==coalition.side.NEUTRAL then
self.alias="Mahatma Gandhi"
end
end
-- Log ID.
self.lid=string.format("COMMANDER %s [%s] | ", self.alias, UTILS.GetCoalitionName(self.coalition))
@ -145,15 +235,15 @@ function COMMANDER:New(Coalition, Alias)
--- Triggers the FSM event "MissionAssign". Mission is added to a LEGION mission queue and already requested. Needs assets to be added to the mission!
-- @function [parent=#COMMANDER] MissionAssign
-- @param #COMMANDER self
-- @param Ops.Legion#LEGION Legion The Legion.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The Legion(s) to which the mission is assigned.
--- Triggers the FSM event "MissionAssign" after a delay. Mission is added to a LEGION mission queue and already requested. Needs assets to be added to the mission!
-- @function [parent=#COMMANDER] __MissionAssign
-- @param #COMMANDER self
-- @param #number delay Delay in seconds.
-- @param Ops.Legion#LEGION Legion The Legion.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The Legion(s) to which the mission is assigned.
--- On after "MissionAssign" event.
-- @function [parent=#COMMANDER] OnAfterMissionAssign
@ -161,8 +251,8 @@ function COMMANDER:New(Coalition, Alias)
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The Legion.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The Legion(s) to which the mission is assigned.
--- Triggers the FSM event "MissionCancel".
@ -188,15 +278,15 @@ function COMMANDER:New(Coalition, Alias)
--- Triggers the FSM event "TransportAssign".
-- @function [parent=#COMMANDER] TransportAssign
-- @param #COMMANDER self
-- @param Ops.Legion#LEGION Legion The Legion.
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
-- @param #table Legions The legion(s) to which this transport is assigned.
--- Triggers the FSM event "TransportAssign" after a delay.
-- @function [parent=#COMMANDER] __TransportAssign
-- @param #COMMANDER self
-- @param #number delay Delay in seconds.
-- @param Ops.Legion#LEGION Legion The Legion.
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
-- @param #table Legions The legion(s) to which this transport is assigned.
--- On after "TransportAssign" event.
-- @function [parent=#COMMANDER] OnAfterTransportAssign
@ -204,8 +294,8 @@ function COMMANDER:New(Coalition, Alias)
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The Legion.
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
-- @param #table Legions The legion(s) to which this transport is assigned.
--- Triggers the FSM event "TransportCancel".
@ -377,7 +467,7 @@ function COMMANDER:RemoveTransport(Transport)
local transport=_transport --Ops.OpsTransport#OPSTRANSPORT
if transport.uid==Transport.uid then
self:I(self.lid..string.format("Removing mission %s (%s) status=%s from queue", transport.uid, transport:GetState()))
self:I(self.lid..string.format("Removing transport UID=%d status=%s from queue", transport.uid, transport:GetState()))
transport.commander=nil
table.remove(self.transportqueue, i)
break
@ -444,7 +534,7 @@ function COMMANDER:AddCapZone(Zone, Altitude, Speed, Heading, Leg)
table.insert(self.capZones, patrolzone)
return awacszone
return patrolzone
end
--- Add an AWACS zone.
@ -496,7 +586,7 @@ function COMMANDER:AddTankerZone(Zone, Altitude, Speed, Heading, Leg, RefuelSyst
table.insert(self.tankerZones, tankerzone)
return awacszone
return tankerzone
end
--- Check if this mission is already in the queue.
@ -762,24 +852,29 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The LEGION.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
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))
-- @param #table Legions The Legion(s) to which the mission is assigned.
function COMMANDER:onafterMissionAssign(From, Event, To, Mission, Legions)
-- 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
-- Add mission to legion.
Legion:AddMission(Mission)
-- Directly request the mission as the assets have already been selected.
Legion:MissionRequest(Mission)
for _,_Legion in pairs(Legions) do
local Legion=_Legion --Ops.Legion#LEGION
-- Debug info.
self:I(self.lid..string.format("Assigning mission \"%s\" [%s] to legion \"%s\"", Mission.name, Mission.type, Legion.alias))
-- Add mission to legion.
Legion:AddMission(Mission)
-- Directly request the mission as the assets have already been selected.
Legion:MissionRequest(Mission)
end
end
@ -792,7 +887,7 @@ end
function COMMANDER:onafterMissionCancel(From, Event, To, Mission)
-- Debug info.
self:I(self.lid..string.format("Cancelling mission %s (%s) in status %s", Mission.name, Mission.type, Mission.status))
self:I(self.lid..string.format("Cancelling mission \"%s\" [%s] in status %s", Mission.name, Mission.type, Mission.status))
-- Set commander status.
Mission.statusCommander=AUFTRAG.Status.CANCELLED
@ -825,21 +920,26 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The LEGION.
-- @param Ops.OpsTransport#OPSTRANSPORT
function COMMANDER:onafterTransportAssign(From, Event, To, Legion, Transport)
-- Debug info.
self:I(self.lid..string.format("Assigning transport %d to legion %s", Transport.uid, Legion.alias))
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
-- @param #table Legions The legion(s) to which this transport is assigned.
function COMMANDER:onafterTransportAssign(From, Event, To, Transport, Legions)
-- Set mission commander status to QUEUED as it is now queued at a legion.
Transport.statusCommander=OPSTRANSPORT.Status.QUEUED
-- Add mission to legion.
Legion:AddOpsTransport(Transport)
for _,_Legion in pairs(Legions) do
local Legion=_Legion --Ops.Legion#LEGION
-- Debug info.
self:I(self.lid..string.format("Assigning transport UID=%d to legion \"%s\"", Transport.uid, Legion.alias))
-- Directly request the mission as the assets have already been selected.
Legion:TransportRequest(Transport)
-- Add mission to legion.
Legion:AddOpsTransport(Transport)
-- Directly request the mission as the assets have already been selected.
Legion:TransportRequest(Transport)
end
end
@ -889,7 +989,7 @@ end
-- @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()))
self:T2(self.lid..string.format("Group \"%s\" on mission \"%s\" [%s]", OpsGroup:GetName(), Mission:GetName(), Mission:GetType()))
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -981,17 +1081,8 @@ function COMMANDER:CheckMissionQueue()
-- Escort and transport must be available (or not required).
if EscortAvail and TransportAvail then
-- Assign mission to legion(s).
for _,_legion in pairs(legions) do
local legion=_legion --Ops.Legion#LEGION
-- Debug message.
self:I(self.lid..string.format("Assigning mission %s [%s] to legion %s", mission:GetName(), mission:GetType(), legion.alias))
-- Add mission to legion.
self:MissionAssign(legion, mission)
end
-- Add mission to legion.
self:MissionAssign(mission, legions)
else
-- Recruited assets but no requested escort available. Unrecruit assets!
@ -1188,16 +1279,7 @@ function COMMANDER:CheckTransportQueue()
end
-- Assign transport to legion(s).
for _,_legion in pairs(legions) do
local legion=_legion --Ops.Legion#LEGION
-- Debug message.
self:I(self.lid..string.format("Assigning transport UID=%d to legion %s", transport.uid, legion.alias))
-- Add mission to legion.
self:TransportAssign(legion, transport)
end
self:TransportAssign(transport, legions)
-- Only ONE transport is assigned.
return

View File

@ -125,15 +125,15 @@ function LEGION:New(WarehouseName, LegionName)
--- Triggers the FSM event "MissionAssign".
-- @function [parent=#LEGION] MissionAssign
-- @param #LEGION self
-- @param Ops.Legion#LEGION Legion The legion from which the mission assets are requested.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The legion(s) from which the mission assets are requested.
--- Triggers the FSM event "MissionAssign" after a delay.
-- @function [parent=#LEGION] __MissionAssign
-- @param #LEGION self
-- @param #number delay Delay in seconds.
-- @param Ops.Legion#LEGION Legion The legion from which the mission assets are requested.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The legion(s) from which the mission assets are requested.
--- On after "MissionAssign" event.
-- @function [parent=#LEGION] OnAfterMissionAssign
@ -141,8 +141,8 @@ function LEGION:New(WarehouseName, LegionName)
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The legion from which the mission assets are requested.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
-- @param #table Legions The legion(s) from which the mission assets are requested.
--- Triggers the FSM event "MissionRequest".
@ -183,15 +183,15 @@ function LEGION:New(WarehouseName, LegionName)
--- Triggers the FSM event "TransportAssign".
-- @function [parent=#LEGION] TransportAssign
-- @param #LEGION self
-- @param Ops.Legion#LEGION Legion The legion from which the transport assets are requested.
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
-- @param #table Legions The legion(s) to which this transport is assigned.
--- Triggers the FSM event "TransportAssign" after a delay.
-- @function [parent=#LEGION] __TransportAssign
-- @param #LEGION self
-- @param #number delay Delay in seconds.
-- @param Ops.Legion#LEGION Legion The legion from which the transport assets are requested.
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
-- @param #table Legions The legion(s) to which this transport is assigned.
--- On after "TransportAssign" event.
-- @function [parent=#LEGION] OnAfterTransportAssign
@ -199,8 +199,8 @@ function LEGION:New(WarehouseName, LegionName)
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The legion from which the transport assets are requested.
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
-- @param #table Legions The legion(s) to which this transport is assigned.
--- Triggers the FSM event "TransportRequest".
@ -617,18 +617,23 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The LEGION.
-- @param Ops.Auftrag#AUFTRAG Mission The mission.
function LEGION:onafterMissionAssign(From, Event, To, Legion, Mission)
-- @param #table Legions The LEGIONs.
function LEGION:onafterMissionAssign(From, Event, To, Mission, Legions)
for _,_Legion in pairs(Legions) do
local Legion=_Legion --Ops.Legion#LEGION
-- Debug info.
self:I(self.lid..string.format("Assigning mission %s (%s) to legion %s", Mission.name, Mission.type, Legion.alias))
-- Add mission to legion.
Legion:AddMission(Mission)
-- Directly request the mission as the assets have already been selected.
Legion:MissionRequest(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 legion.
Legion:AddMission(Mission)
-- Directly request the mission as the assets have already been selected.
Legion:MissionRequest(Mission)
end
end
@ -749,18 +754,23 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param Ops.Legion#LEGION Legion The LEGION.
-- @param Ops.OpsTransport#OPSTRANSPORT The transport.
function LEGION:onafterTransportAssign(From, Event, To, Legion, Transport)
-- @param Ops.OpsTransport#OPSTRANSPORT Transport The transport.
-- @param #table Legions The legion(s) to which the transport is assigned.
function LEGION:onafterTransportAssign(From, Event, To, Transport, Legions)
-- Debug info.
self:I(self.lid..string.format("Assigning transport %d to legion %s", Transport.uid, Legion.alias))
for _,_Legion in pairs(Legions) do
local Legion=_Legion --Ops.Legion#LEGION
-- Debug info.
self:I(self.lid..string.format("Assigning transport %d to legion %s", Transport.uid, Legion.alias))
-- Add mission to legion.
Legion:AddOpsTransport(Transport)
-- Add mission to legion.
Legion:AddOpsTransport(Transport)
-- Directly request the mission as the assets have already been selected.
Legion:TransportRequest(Transport)
-- Directly request the mission as the assets have already been selected.
Legion:TransportRequest(Transport)
end
end
@ -2148,7 +2158,7 @@ function LEGION:AssignAssetsForEscort(Cohorts, Assets, NescortMin, NescortMax)
end
-- Assign mission to legion.
self:MissionAssign(legion, escort)
self:MissionAssign(escort, {legion})
end
end
@ -2240,7 +2250,7 @@ function LEGION:AssignAssetsForTransport(Legions, CargoAssets, NcarriersMin, Nca
end
-- Debug info.
env.info(string.format("FF Transport available with %d carrier assets", #CarrierAssets))
self:T(self.lid..string.format("Transport available with %d carrier assets", #CarrierAssets))
-- Add cargo assets to transport.
for _,_legion in pairs(CargoLegions) do
@ -2272,10 +2282,7 @@ function LEGION:AssignAssetsForTransport(Legions, CargoAssets, NcarriersMin, Nca
end
-- Assign TRANSPORT to legions. This also sends the request for the assets.
for _,_legion in pairs(CarrierLegions) do
local legion=_legion --Ops.Legion#LEGION
self:TransportAssign(legion, Transport)
end
self:TransportAssign(Transport, CarrierLegions)
-- Got transport.
return true, Transport
@ -2393,15 +2400,15 @@ function LEGION._OptimizeAssetSelection(assets, MissionType, TargetVec2, Include
table.sort(assets, optimize)
-- Remove distance parameter.
--[[
local text=string.format("Optimized %d assets for %s mission/transport (payload=%s):", #assets, MissionType, tostring(IncludePayload))
for i,Asset in pairs(assets) do
local asset=Asset --Functional.Warehouse#WAREHOUSE.Assetitem
text=text..string.format("\n%s %s: score=%d", asset.squadname, asset.spawngroupname, asset.score)
asset.score=nil
if LEGION.verbose>0 then
local text=string.format("Optimized %d assets for %s mission/transport (payload=%s):", #assets, MissionType, tostring(IncludePayload))
for i,Asset in pairs(assets) do
local asset=Asset --Functional.Warehouse#WAREHOUSE.Assetitem
text=text..string.format("\n%s %s: score=%d", asset.squadname, asset.spawngroupname, asset.score)
asset.score=nil
end
env.info(text)
end
env.info(text)
]]
end

View File

@ -159,13 +159,38 @@ function NAVYGROUP:New(group)
self:AddTransition("*", "CollisionWarning", "*") -- Collision warning.
self:AddTransition("*", "ClearAhead", "*") -- Clear ahead.
self:AddTransition("*", "Dive", "*") -- Command a submarine to dive.
self:AddTransition("Diving", "Surface", "*") -- Command a submarine to go to the surface.
self:AddTransition("Cruising", "Dive", "Cruising") -- Command a submarine to dive.
self:AddTransition("Cruising", "Surface", "Cruising") -- Command a submarine to go to the surface.
------------------------
--- Pseudo Functions ---
------------------------
--- Triggers the FSM event "Cruise".
-- @function [parent=#NAVYGROUP] Cruise
-- @param #NAVYGROUP self
-- @param #number Speed Speed in knots until next waypoint is reached.
--- Triggers the FSM event "Cruise" after a delay.
-- @function [parent=#NAVYGROUP] __Cruise
-- @param #NAVYGROUP self
-- @param #number delay Delay in seconds.
-- @param #number Speed Speed in knots until next waypoint is reached.
--- On after "Cruise" event.
-- @function [parent=#NAVYGROUP] OnAfterCruise
-- @param #NAVYGROUP self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #number Speed Speed in knots until next waypoint is reached.
--- Triggers the FSM event "TurnIntoWind".
-- @function [parent=#NAVYGROUP] TurnIntoWind
-- @param #NAVYGROUP self
@ -240,7 +265,6 @@ function NAVYGROUP:New(group)
-- @param #NAVYGROUP.IntoWind IntoWindData Data table.
--- Triggers the FSM event "TurningStarted".
-- @function [parent=#NAVYGROUP] TurningStarted
-- @param #NAVYGROUP self

View File

@ -2899,6 +2899,9 @@ function OPSGROUP:OnEventBirth(EventData)
local element=self:GetElementByName(unitname)
if element and element.status~=OPSGROUP.ElementStatus.SPAWNED then
-- Debug info.
self:T(self.lid..string.format("EVENT: Element %s born ==> spawned", unitname))
-- Set element to spawned state.
self:ElementSpawned(element)
@ -6113,7 +6116,6 @@ function OPSGROUP:_CheckCargoTransport()
local Time=timer.getAbsTime()
-- Cargo bay debug info.
-- Check cargo bay and declare cargo groups dead.
if self.verbose>=1 then
local text=""
for _,_element in pairs(self.elements) do
@ -8046,10 +8048,15 @@ function OPSGROUP:onafterBoard(From, Event, To, CarrierGroup, Carrier)
-- Debug info.
self:T(self.lid..string.format("Board with direct load to carrier %s", CarrierGroup:GetName()))
local mycarriergroup=self:_GetMyCarrierGroup()
-- Get current carrier group.
local mycarriergroup=self:_GetMyCarrierGroup()
if mycarriergroup then
self:T(self.lid..string.format("Current carrier group %s", mycarriergroup:GetName()))
end
-- Unload cargo first.
if mycarriergroup then
if mycarriergroup and mycarriergroup:GetName()~=CarrierGroup:GetName() and self:IsLoaded() then
-- TODO: Unload triggers other stuff like Disembarked. This can be a problem!
mycarriergroup:Unload(self)
end
@ -8880,8 +8887,8 @@ function OPSGROUP:Route(waypoints, delay)
airborne = self:IsFlightgroup(),
route={points=waypoints},
},
}
}
-- Set mission task.
self:SetTask(DCSTask)
@ -10813,11 +10820,20 @@ function OPSGROUP:_AddElementByName(unitname)
--local unittemplate=_DATABASE:GetUnitTemplateFromUnitName(unitname)
-- Element table.
local element={} --#OPSGROUP.Element
local element=self:GetElementByName(unitname)
-- Add element to table.
if element then
-- We already know this element.
else
-- Add a new element.
element={}
element.status=OPSGROUP.ElementStatus.INUTERO
table.insert(self.elements, element)
end
-- Name and status.
element.name=unitname
element.status=OPSGROUP.ElementStatus.INUTERO
-- Unit and group.
element.unit=unit
@ -10904,11 +10920,6 @@ function OPSGROUP:_AddElementByName(unitname)
element.size, element.length, element.height, element.width, element.weight, element.weightMaxTotal, element.weightCargo, element.weightMaxCargo)
self:T(self.lid..text)
-- Add element to table.
if not self:_IsElement(unitname) then
table.insert(self.elements, element)
end
-- Trigger spawned event if alive.
if unit:IsAlive() and element.status~=OPSGROUP.ElementStatus.SPAWNED then
-- This needs to be slightly delayed (or moved elsewhere) or the first element will always trigger the group spawned event as it is not known that more elements are in the group.

View File

@ -38,8 +38,8 @@
-- @field #number duration Duration (`Tstop-Tstart`) of the transport in seconds.
-- @field #table conditionStart Start conditions.
--
-- @field #table cargos Cargos. Each element is a @{Ops.OpsGroup#OPSGROUP.CargoGroup}.
-- @field #table carriers Carriers assigned for this transport.
-- @field #table carrierTransportStatus Status of each carrier.
--
-- @field #table tzCombos Table of transport zone combos. Each element of the table is of type `#OPSTRANSPORT.TransportZoneCombo`.
-- @field #number tzcCounter Running number of added transport zone combos.
@ -117,7 +117,6 @@
OPSTRANSPORT = {
ClassName = "OPSTRANSPORT",
verbose = 0,
cargos = {},
carriers = {},
carrierTransportStatus = {},
tzCombos = {},
@ -152,7 +151,7 @@ OPSTRANSPORT.Status={
FAILED="failed",
}
--- Pickup and deploy set.
--- Transport zone combination.
-- @type OPSTRANSPORT.TransportZoneCombo
-- @field #number uid Unique ID of the TZ combo.
-- @field #number Ncarriers Number of carrier groups using this transport zone.
@ -233,7 +232,6 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
self:SetRequiredCarriers()
-- Init arrays and counters.
self.cargos={}
self.carriers={}
self.Ncargo=0
self.Ncarrier=0
@ -256,7 +254,7 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
self:AddTransition(OPSTRANSPORT.Status.SCHEDULED, "Executing", OPSTRANSPORT.Status.EXECUTING) -- Cargo is being transported.
self:AddTransition("*", "Delivered", OPSTRANSPORT.Status.DELIVERED) -- Cargo was delivered.
self:AddTransition("*", "Status", "*")
self:AddTransition("*", "StatusUpdate", "*")
self:AddTransition("*", "Stop", "*")
self:AddTransition("*", "Cancel", OPSTRANSPORT.Status.CANCELLED) -- Command to cancel the transport.
@ -272,12 +270,12 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
--- Pseudo Functions ---
------------------------
--- Triggers the FSM event "Status".
-- @function [parent=#OPSTRANSPORT] Status
--- Triggers the FSM event "StatusUpdate".
-- @function [parent=#OPSTRANSPORT] StatusUpdate
-- @param #OPSTRANSPORT self
--- Triggers the FSM event "Status" after a delay.
-- @function [parent=#OPSTRANSPORT] __Status
-- @function [parent=#OPSTRANSPORT] __StatusUpdate
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
@ -291,6 +289,13 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- On after "Planned" event.
-- @function [parent=#OPSTRANSPORT] OnAfterPlanned
-- @param #OPSTRANSPORT self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Queued".
-- @function [parent=#OPSTRANSPORT] Queued
@ -301,6 +306,13 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- On after "Queued" event.
-- @function [parent=#OPSTRANSPORT] OnAfterQueued
-- @param #OPSTRANSPORT self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Requested".
-- @function [parent=#OPSTRANSPORT] Requested
@ -311,6 +323,13 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- On after "Requested" event.
-- @function [parent=#OPSTRANSPORT] OnAfterRequested
-- @param #OPSTRANSPORT self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Scheduled".
-- @function [parent=#OPSTRANSPORT] Scheduled
@ -321,6 +340,13 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- On after "Scheduled" event.
-- @function [parent=#OPSTRANSPORT] OnAfterScheduled
-- @param #OPSTRANSPORT self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Executing".
-- @function [parent=#OPSTRANSPORT] Executing
@ -331,6 +357,13 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- On after "Executing" event.
-- @function [parent=#OPSTRANSPORT] OnAfterExecuting
-- @param #OPSTRANSPORT self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Delivered".
-- @function [parent=#OPSTRANSPORT] Delivered
@ -341,6 +374,13 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
-- @param #OPSTRANSPORT self
-- @param #number delay Delay in seconds.
--- On after "Delivered" event.
-- @function [parent=#OPSTRANSPORT] OnAfterDelivered
-- @param #OPSTRANSPORT self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Cancel".
-- @function [parent=#OPSTRANSPORT] Cancel
@ -414,7 +454,7 @@ function OPSTRANSPORT:New(CargoGroups, PickupZone, DeployZone)
--TODO: Psydofunctions
-- Call status update.
self:__Status(-1)
self:__StatusUpdate(-1)
return self
end
@ -481,7 +521,7 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet, TransportZoneCombo)
if cargo then
-- Add to main table.
table.insert(self.cargos, cargo)
--table.insert(self.cargos, cargo)
self.Ncargo=self.Ncargo+1
-- Add to TZC table.
@ -514,7 +554,7 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet, TransportZoneCombo)
Weight=Weight+weight
text=text..string.format("\n- %s [%s] weight=%.1f kg", cargo.opsgroup:GetName(), cargo.opsgroup:GetState(), weight)
end
text=text..string.format("\nTOTAL: Ncargo=%d, Weight=%.1f kg", #self.cargos, Weight)
text=text..string.format("\nTOTAL: Ncargo=%d, Weight=%.1f kg", self.Ncargo, Weight)
self:I(self.lid..text)
end
@ -927,13 +967,8 @@ function OPSTRANSPORT:_DelCarrier(CarrierGroup)
self:T(self.lid..string.format("Removing carrier %s", CarrierGroup.groupname))
table.remove(self.carriers, i)
end
end
if #self.carriers==0 then
-- TODO: This call can be WRONG!
self:DeadCarrierAll()
end
end
return self
@ -1557,12 +1592,12 @@ end
-- Status Update
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- On after "Status" event.
--- On after "StatusUpdate" event.
-- @param #OPSTRANSPORT self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function OPSTRANSPORT:onafterStatus(From, Event, To)
function OPSTRANSPORT:onafterStatusUpdate(From, Event, To)
-- Current FSM state.
local fsmstate=self:GetState()
@ -1577,7 +1612,9 @@ function OPSTRANSPORT:onafterStatus(From, Event, To)
for i,_tz in pairs(self.tzCombos) do
local tz=_tz --#OPSTRANSPORT.TransportZoneCombo
text=text..string.format("\n[%d] %s --> %s", i, tz.PickupZone and tz.PickupZone:GetName() or "Unknown", tz.DeployZone and tz.DeployZone and tz.DeployZone:GetName() or "Unknown", tz.Ncarriers)
local pickupzone=tz.PickupZone and tz.PickupZone:GetName() or "Unknown"
local deployzone=tz.DeployZone and tz.DeployZone:GetName() or "Unknown"
text=text..string.format("\n[%d] %s --> %s: Ncarriers=%d, Ncargo=%d (%d)", i, pickupzone, deployzone, tz.Ncarriers, #tz.Cargos, tz.Ncargo)
end
end
@ -1613,7 +1650,7 @@ function OPSTRANSPORT:onafterStatus(From, Event, To)
-- Update status again.
if not self:IsDelivered() then
self:__Status(-30)
self:__StatusUpdate(-30)
end
end
@ -1671,9 +1708,9 @@ end
function OPSTRANSPORT:onafterDelivered(From, Event, To)
self:T(self.lid..string.format("New status: %s-->%s", From, To))
-- Inform all assigned carriers that cargo was delivered. They can have this in the queue or are currently processing this transport.
for _,_carrier in pairs(self.carriers) do
local carrier=_carrier --Ops.OpsGroup#OPSGROUP
-- Inform all assigned carriers that cargo was delivered. They can have this in the queue or are currently processing this transport.
for i=#self.carriers, 1, -1 do
local carrier=self.carriers[i] --Ops.OpsGroup#OPSGROUP
if self:GetCarrierTransportStatus(carrier)~=OPSTRANSPORT.Status.DELIVERED then
carrier:Delivered(self)
end
@ -1712,8 +1749,15 @@ end
-- @param Ops.OpsGroup#OPSGROUP OpsGroup Carrier OPSGROUP that is dead.
function OPSTRANSPORT:onafterDeadCarrierGroup(From, Event, To, OpsGroup)
self:I(self.lid..string.format("Carrier OPSGROUP %s dead!", OpsGroup:GetName()))
-- Remove group from carrier list/table.
self.NdeadCarrier=self.NdeadCarrier+1
-- Increase dead counter.
self.NcarrierDead=self.NcarrierDead+1
if #self.carriers==0 then
self:DeadCarrierAll()
end
-- Remove group from carrier list/table.
self:_DelCarrier(OpsGroup)
end
@ -1724,7 +1768,11 @@ end
-- @param #string To To state.
function OPSTRANSPORT:onafterDeadCarrierAll(From, Event, To)
self:I(self.lid..string.format("ALL Carrier OPSGROUPs are dead! Setting stage to PLANNED if not all cargo was delivered."))
-- Check if cargo was delivered.
self:_CheckDelivered()
-- Set state back to PLANNED if not delivered.
if not self:IsDelivered() then
self:Planned()
end
@ -2064,9 +2112,16 @@ function OPSTRANSPORT:_GetTransportZoneCombo(Carrier)
-- Get carrier position.
local vec2=Carrier:GetVec2()
--- Penalty function.
local function penalty(candidate)
local p=candidate.ncarriers*10-candidate.ncargo+candidate.distance/10
return p
end
-- TZC candidates.
local candidates={}
local pickup=nil --#OPSTRANSPORT.TransportZoneCombo
local distmin=nil
for i,_transportzone in pairs(self.tzCombos) do
local tz=_transportzone --#OPSTRANSPORT.TransportZoneCombo
@ -2078,31 +2133,58 @@ function OPSTRANSPORT:_GetTransportZoneCombo(Carrier)
-- Count undelivered cargos in embark(!) zone that fit into the carrier.
local ncargo=self:_CountCargosInZone(tz.EmbarkZone, false, Carrier, tz)
--env.info(string.format("FF GetPickupZone i=%d, ncargo=%d", i, ncargo))
-- At least one group in the zone.
if ncargo>=1 then
-- Distance to the carrier in meters.
local dist=tz.PickupZone:Get2DDistance(vec2)
if distmin==nil or dist<distmin then
distmin=dist
pickup=tz
local ncarriers=0
for _,_carrier in pairs(self.carriers) do
local carrier=_carrier --Ops.OpsGroup#OPSGROUP
if carrier and carrier:IsAlive() and carrier.cargoTZC and carrier.cargoTZC.uid==tz.uid then
ncarriers=ncarriers+1
end
end
-- New candidate.
local candidate={tzc=tz, distance=dist/1000, ncargo=ncargo, ncarriers=ncarriers}
-- Calculdate penalty of candidate.
candidate.penalty=penalty(candidate)
-- Add candidate.
table.insert(candidates, candidate)
end
end
end
-- Debug info.
if pickup then
self:T(self.lid..string.format("Found pickupzone %s for carrier group %s", pickup.PickupZone:GetName(), Carrier:GetName()))
if #candidates>0 then
-- Minimize penalty.
local function optTZC(candA, candB)
return candA.penalty<candB.penalty
end
table.sort(candidates, optTZC)
-- Debug output.
if self.verbose>=3 then
local text="TZC optimized"
for i,candidate in pairs(candidates) do
text=text..string.format("\n[%d] TPZ=%d, Ncarriers=%d, Ncargo=%d, Distance=%.1f km, PENALTY=%d", i, candidate.tzc.uid, candidate.ncarriers, candidate.ncargo, candidate.distance, candidate.penalty)
end
self:I(self.lid..text)
end
-- Return best candidate.
return candidates[1].tzc
else
-- No candidates.
self:T(self.lid..string.format("Could NOT find a pickup zone (with cargo) for carrier group %s", Carrier:GetName()))
end
end
return pickup
return nil
end
--- Get an OPSGROUP from a given OPSGROUP or GROUP object. If the object is a GROUUP, an OPSGROUP is created automatically.