diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 37de1edad..8e68cb931 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -1364,23 +1364,22 @@ function AUFTRAG:NewFUELSUPPLY(Zone) end ---- **[AIR]** Create an ALERT 5 mission. +--- **[AIR]** Create an ALERT 5 mission. Aircraft will be spawned uncontrolled and wait for an assignment. You must specify **one** mission type which is performed. +-- This determines the payload and the DCS mission task which are used when the aircraft is spawned. -- @param #AUFTRAG self --- @param #string MissionType Mission type `AUFTRAG.Type.XXX`. +-- @param #string MissionType Mission type `AUFTRAG.Type.XXX`. Determines payload and mission task (intercept, ground attack, etc.). -- @return #AUFTRAG self function AUFTRAG:NewALERT5(MissionType) local mission=AUFTRAG:New(AUFTRAG.Type.ALERT5) - --mission:_TargetFromObject(Coordinate) - mission.missionTask=self:GetMissionTaskforMissionType(MissionType) mission.optionROE=ENUMS.ROE.WeaponHold mission.optionROT=ENUMS.ROT.NoReaction mission.alert5MissionType=MissionType - mission.missionFraction=0.0 + mission.missionFraction=1.0 mission.DCStask=mission:GetDCSMissionTask() @@ -1828,14 +1827,18 @@ 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 PickupZone Zone where assets are picked up. -- @param Core.Zone#ZONE DeployZone Zone where assets are deployed. +-- @param Core.Zone#ZONE DisembarkZone Zone where assets are disembarked to. -- @param Core.Set#SET_OPSGROUP Carriers Set of carriers. Can also be a single group. Can also be added via the AddTransportCarriers functions. -- @return #AUFTRAG self -function AUFTRAG:SetTransportForAssets(PickupZone, DeployZone, Carriers) +function AUFTRAG:SetTransportForAssets(DeployZone, DisembarkZone, Carriers) -- OPS transport from pickup to deploy zone. - self.opstransport=OPSTRANSPORT:New(nil, PickupZone, DeployZone) + self.opstransport=OPSTRANSPORT:New(nil, nil, DeployZone) + + if DisembarkZone then + self.opstransport:SetDisembarkZone(DisembarkZone) + end if Carriers then if Carriers:IsInstanceOf("SET_OPSGROUP") then @@ -1854,6 +1857,18 @@ function AUFTRAG:SetTransportForAssets(PickupZone, DeployZone, Carriers) return self end +--- Add a transport Legion. This requires an OPSTRANSPORT to be set via `AUFTRAG:SetTransportForAssets`. +-- @param #AUFTRAG self +-- @param Ops.Legion#LEGION Legion The legion. +function AUFTRAG:AddTransportLegion(Legion) + + self.transportLegions=self.transportLegions or {} + + table.insert(self.transportLegions, Legion) + + return self +end + --- Set Rules of Engagement (ROE) for this mission. -- @param #AUFTRAG self -- @param #string roe Mission ROE. @@ -2162,7 +2177,12 @@ function AUFTRAG:AddOpsGroup(OpsGroup) -- Add ops transport to new group. if self.opstransport then - self.opstransport:AddCargoGroups(OpsGroup) + for _,_tzc in pairs(self.opstransport.tzCombos) do + local tzc=_tzc --Ops.OpsTransport#OPSTRANSPORT.TransportZoneCombo + if tzc.uid~=self.opstransport.tzcDefault.uid then + self.opstransport:AddCargoGroups(OpsGroup, tzc) + end + end end return self @@ -2300,7 +2320,7 @@ function AUFTRAG:IsReadyToGo() if #self.legions>0 then end if self.opstransport:IsPlanned() or self.opstransport:IsQueued() or self.opstransport:IsRequested() then - return false + --return false end end diff --git a/Moose Development/Moose/Ops/Cohort.lua b/Moose Development/Moose/Ops/Cohort.lua index 969210f8c..6ae931404 100644 --- a/Moose Development/Moose/Ops/Cohort.lua +++ b/Moose Development/Moose/Ops/Cohort.lua @@ -37,6 +37,8 @@ -- @field #number radioFreq Radio frequency in MHz the cohort uses. -- @field #number radioModu Radio modulation the cohort uses. -- @field #table tacanChannel List of TACAN channels available to the cohort. +-- @field #number weightAsset Weight of one assets group in kg. +-- @field #number cargobayLimit Cargo bay capacity in kg. -- @extends Core.Fsm#FSM --- *It is unbelievable what a platoon of twelve aircraft did to tip the balance.* -- Adolf Galland @@ -67,7 +69,9 @@ COHORT = { legion = nil, Ngroups = nil, engageRange = nil, - tacanChannel = {}, + tacanChannel = {}, + weightAsset = 99999, + cargobayLimit = 0, } --- COHORT class version. @@ -124,7 +128,20 @@ function COHORT:New(TemplateGroupName, Ngroups, CohortName) -- Aircraft type. self.aircrafttype=self.templategroup:GetTypeName() - + + local units=self.templategroup:GetUnits() + + -- Weight of the whole group. + self.weightAsset=0 + for i,_unit in pairs(units) do + local unit=_unit --Wrapper.Unit#UNIT + local desc=unit:GetDesc() + self.weightAsset=self.weightAsset + (desc.massMax or 666) + if i==1 then + self.cargobayLimit=unit:GetCargoBayFreeWeight() + end + end + -- Start State. self:SetStartState("Stopped") diff --git a/Moose Development/Moose/Ops/Legion.lua b/Moose Development/Moose/Ops/Legion.lua index 2be104b6e..32344af38 100644 --- a/Moose Development/Moose/Ops/Legion.lua +++ b/Moose Development/Moose/Ops/Legion.lua @@ -253,13 +253,28 @@ function LEGION:AddMission(Mission) Mission:_TargetFromObject(self:GetCoordinate()) end - --[[ + -- Add ops transport to transport Legions. if Mission.opstransport then - Mission.opstransport:SetPickupZone(self.spawnzone) - Mission.opstransport:SetEmbarkZone(self.spawnzone) - self:AddOpsTransport(Mission.opstransport) + + + -- Add a new TZC: from pickup here to the deploy zone. + local tzc=Mission.opstransport:AddTransportZoneCombo(self.spawnzone, Mission.opstransport.tzcDefault.DeployZone) + + --TODO: Depending on "from where to where" the assets need to transported, we need to set ZONE_AIRBASE etc. + + --Mission.opstransport:SetPickupZone(self.spawnzone) + --Mission.opstransport:SetEmbarkZone(self.spawnzone) + + + -- Loop over all defined transport legions. + for _,_legion in pairs(Mission.transportLegions) do + local legion=_legion --Ops.Legion#LEGION + + -- Add ops transport to legion. + legion:AddOpsTransport(Mission.opstransport) + end + end - ]] -- Add mission to queue. table.insert(self.missionqueue, Mission) @@ -458,8 +473,10 @@ function LEGION:_GetNextTransport() return nil end - - local function getAssets(n) + --- Function to get carrier assets from all cohorts. + local function getAssets(n, weightGroup) + + -- Selected assets. local assets={} -- Loop over cohorts. @@ -467,14 +484,14 @@ function LEGION:_GetNextTransport() local cohort=_cohort --Ops.Cohort#COHORT -- Check if chort can do a transport. - if cohort:CheckMissionCapability({AUFTRAG.Type.OPSTRANSPORT}, cohort.missiontypes) then + if cohort:CheckMissionCapability({AUFTRAG.Type.OPSTRANSPORT}) and cohort.cargobayLimit>=weightGroup then -- Loop over cohort assets. for _,_asset in pairs(cohort.assets) do local asset=_asset --Functional.Warehouse#WAREHOUSE.Assetitem -- Check if asset is currently on a mission (STARTED or QUEUED). - if not asset.spawned then + if not (asset.spawned or asset.isReserved or asset.requested) then -- Add to assets. table.insert(assets, asset) @@ -488,6 +505,8 @@ function LEGION:_GetNextTransport() end end + + return nil end @@ -498,11 +517,30 @@ function LEGION:_GetNextTransport() -- Check if transport is still queued and ready. if transport:IsQueued() and transport:IsReadyToGo() then - local assets=getAssets(1) - - if #assets>0 then - transport.assets=assets - return transport + -- Get all undelivered cargo ops groups. + local cargoOpsGroups=transport:GetCargoOpsGroups(false) + + -- At least one group should be spawned. + if #cargoOpsGroups>0 then + + -- Calculate the max weight so we know which cohorts can provide carriers. + local weightGroup=0 + for _,_opsgroup in pairs(cargoOpsGroups) do + local opsgroup=_opsgroup --Ops.OpsGroup#OPSGROUP + local weight=opsgroup:GetWeightTotal() + if weight>weightGroup then + weightGroup=weight + end + end + + -- Get assets. If not enough assets can be found, nil is returned. + local assets=getAssets(1, weightGroup) + + if assets then + transport.assets=assets + return transport + end + end end @@ -821,6 +859,7 @@ function LEGION:onafterOpsOnMission(From, Event, To, OpsGroup, Mission) -- Trigger event for Brigades. self:ArmyOnMission(OpsGroup, Mission) else + --TODO: Flotilla end end @@ -901,8 +940,6 @@ function LEGION:onafterNewAsset(From, Event, To, asset, assignment) -- Add asset to cohort. cohort:AddAsset(asset) - -- TODO - --asset.terminalType=AIRBASE.TerminalType.OpenBig else --- diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 7af0acbe1..8ec6d644b 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -5751,13 +5751,13 @@ function OPSGROUP:_CheckCargoTransport() if self.verbose>=3 then local text="" for i,_transport in pairs(self.cargoqueue) do - local transport=_transport --#Ops.OpsTransport#OPSTRANSPORT + local transport=_transport --Ops.OpsTransport#OPSTRANSPORT local pickupzone=transport:GetPickupZone() local deployzone=transport:GetDeployZone() local pickupname=pickupzone and pickupzone:GetName() or "unknown" local deployname=deployzone and deployzone:GetName() or "unknown" text=text..string.format("\n[%d] UID=%d Status=%s: %s --> %s", i, transport.uid, transport:GetState(), pickupname, deployname) - for j,_cargo in pairs(transport.cargos) do + for j,_cargo in pairs(transport:GetCargos()) do local cargo=_cargo --#OPSGROUP.CargoGroup local state=cargo.opsgroup:GetState() local status=cargo.opsgroup.cargoStatus @@ -5785,6 +5785,12 @@ function OPSGROUP:_CheckCargoTransport() if self.cargoTransport then if self:IsNotCarrier() then + + -- Unset time stamps. + self.Tpickingup=nil + self.Tloading=nil + self.Ttransporting=nil + self.Tunloading=nil -- Get transport zone combo (TZC). self.cargoTZC=self.cargoTransport:_GetTransportZoneCombo(self) @@ -5802,18 +5808,28 @@ function OPSGROUP:_CheckCargoTransport() end elseif self:IsPickingup() then + + -- Set time stamp. + self.Tpickingup=self.Tpickingup or Time + + -- Current pickup time. + local tpickingup=Time-self.Tpickingup -- Debug Info. - self:T(self.lid.."Picking up...") + self:T(self.lid..string.format("Picking up at %s [TZC UID=%d] for %s sec...", self.cargoTZC.PickupZone and self.cargoTZC.PickupZone:GetName() or "unknown", self.cargoTZC.uid, tpickingup)) elseif self:IsLoading() then -- Set loading time stamp. - --TODO: Check max loading time. If exceeded ==> abort transport. self.Tloading=self.Tloading or Time + + -- Current pickup time. + local tloading=Time-self.Tloading + + --TODO: Check max loading time. If exceeded ==> abort transport. -- Debug info. - self:T(self.lid.."Loading...") + self:T(self.lid..string.format("Loading at %s [TZC UID=%d] for %s sec...", self.cargoTZC.PickupZone and self.cargoTZC.PickupZone:GetName() or "unknown", self.cargoTZC.uid, tloading)) local boarding=false local gotcargo=false @@ -5847,11 +5863,23 @@ function OPSGROUP:_CheckCargoTransport() end elseif self:IsTransporting() then + + -- Set time stamp. + self.Ttransporting=self.Ttransporting or Time + + -- Current pickup time. + local ttransporting=Time-self.Ttransporting -- Debug info. self:T(self.lid.."Transporting (nothing to do)") elseif self:IsUnloading() then + + -- Set time stamp. + self.Tunloading=self.Tunloading or Time + + -- Current pickup time. + local tunloading=Time-self.Tunloading -- Debug info. self:T(self.lid.."Unloading ==> Checking if all cargo was delivered") @@ -6084,7 +6112,7 @@ end function OPSGROUP:_CheckDelivered(CargoTransport) local done=true - for _,_cargo in pairs(CargoTransport.cargos) do + for _,_cargo in pairs(CargoTransport:GetCargos()) do local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup if self:CanCargo(cargo.opsgroup) then @@ -6118,7 +6146,7 @@ function OPSGROUP:_CheckGoPickup(CargoTransport) if CargoTransport then - for _,_cargo in pairs(CargoTransport.cargos) do + for _,_cargo in pairs(CargoTransport:GetCargos()) do local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup if self:CanCargo(cargo.opsgroup) then @@ -8236,15 +8264,25 @@ function OPSGROUP:_InitWaypoints(WpIndexMin, WpIndexMax) -- Speed in knots. local Speed=UTILS.MpsToKnots(wp.speed) - --local waypoint=self:_CreateWaypoint(wp) - --self:_AddWaypoint(waypoint) - + -- Add waypoint. + local Waypoint=nil if self:IsFlightgroup() then - FLIGHTGROUP.AddWaypoint(self, Coordinate, Speed, nil, Altitude, false) + Waypoint=FLIGHTGROUP.AddWaypoint(self, Coordinate, Speed, nil, Altitude, false) elseif self:IsArmygroup() then - ARMYGROUP.AddWaypoint(self, Coordinate, Speed, nil, wp.action, false) + Waypoint=ARMYGROUP.AddWaypoint(self, Coordinate, Speed, nil, wp.action, false) elseif self:IsNavygroup() then - NAVYGROUP.AddWaypoint(self, Coordinate, Speed, nil, Depth, false) + Waypoint=NAVYGROUP.AddWaypoint(self, Coordinate, Speed, nil, Depth, false) + end + + -- Get DCS waypoint tasks set in the ME. EXPERIMENTAL! + local DCStasks=wp.task and wp.task.params.tasks or nil + if DCStasks then + for _,DCStask in pairs(DCStasks) do + -- Wrapped Actions are commands. We do not take those. + if DCStask.id and DCStask.id~="WrappedAction" then + self:AddTaskWaypoint(DCStask,Waypoint, "ME Task") + end + end end end diff --git a/Moose Development/Moose/Ops/OpsTransport.lua b/Moose Development/Moose/Ops/OpsTransport.lua index 5e123a191..a77c7c4e9 100644 --- a/Moose Development/Moose/Ops/OpsTransport.lua +++ b/Moose Development/Moose/Ops/OpsTransport.lua @@ -432,9 +432,10 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet, TransportZoneCombo) if GroupSet:IsInstanceOf("GROUP") or GroupSet:IsInstanceOf("OPSGROUP") then -- We got a single GROUP or OPSGROUP object. - local cargo=self:_CreateCargoGroupData(GroupSet) + local cargo=self:_CreateCargoGroupData(GroupSet, TransportZoneCombo) if cargo then + -- Add to main table. table.insert(self.cargos, cargo) self.Ncargo=self.Ncargo+1 @@ -442,6 +443,7 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet, TransportZoneCombo) -- Add to TZC table. table.insert(TransportZoneCombo.Cargos, cargo) TransportZoneCombo.Ncargo=TransportZoneCombo.Ncargo+1 + end else @@ -450,6 +452,10 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet, TransportZoneCombo) for _,group in pairs(GroupSet.Set) do + -- Call iteravely for each group. + self:AddCargoGroups(group, TransportZoneCombo) + + --[[ local cargo=self:_CreateCargoGroupData(group) if cargo then @@ -461,6 +467,7 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet, TransportZoneCombo) table.insert(TransportZoneCombo.Cargos, cargo) TransportZoneCombo.Ncargo=TransportZoneCombo.Ncargo+1 end + ]] end end @@ -469,7 +476,7 @@ function OPSTRANSPORT:AddCargoGroups(GroupSet, TransportZoneCombo) if self.verbose>=1 then local text=string.format("Added cargo groups:") local Weight=0 - for _,_cargo in pairs(self.cargos) do + for _,_cargo in pairs(self:GetCargos()) do local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup local weight=cargo.opsgroup:GetWeightTotal() Weight=Weight+weight @@ -874,7 +881,14 @@ function OPSTRANSPORT:GetCargos(TransportZoneCombo) if TransportZoneCombo then return TransportZoneCombo.Cargos else - return self.cargos + local cargos={} + for _,_tzc in pairs(self.tzCombos) do + local tzc=_tzc --#OPSTRANSPORT.TransportZoneCombo + for _,cargo in pairs(tzc.Cargos) do + table.insert(cargos, cargo) + end + end + return cargos end end @@ -1316,7 +1330,7 @@ function OPSTRANSPORT:onafterStatus(From, Event, To) if self.verbose>=3 then text=text..string.format("\nCargos:") - for _,_cargo in pairs(self.cargos) do + for _,_cargo in pairs(self:GetCargos()) do local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup local carrier=cargo.opsgroup:_GetMyCarrierElement() local name=carrier and carrier.name or "none" @@ -1472,7 +1486,7 @@ function OPSTRANSPORT:_CheckDelivered() local done=true local dead=true - for _,_cargo in pairs(self.cargos) do + for _,_cargo in pairs(self:GetCargos()) do local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup if cargo.delivered then @@ -1611,17 +1625,31 @@ end -- @param #OPSTRANSPORT self -- @param Wrapper.Group#GROUP group The GROUP or OPSGROUP object. -- @return Ops.OpsGroup#OPSGROUP.CargoGroup Cargo group data. -function OPSTRANSPORT:_CreateCargoGroupData(group) +-- @param #OPSTRANSPORT.TransportZoneCombo TransportZoneCombo Transport zone combo. +function OPSTRANSPORT:_CreateCargoGroupData(group, TransportZoneCombo) + -- Get ops group. local opsgroup=self:_GetOpsGroupFromObject(group) + -- First check that this group is not already contained in this TZC. + for _,_cargo in pairs(TransportZoneCombo.Cargos or {}) do + local cargo=_cargo --Ops.OpsGroup#OPSGROUP.CargoGroup + if cargo.opsgroup.groupname==opsgroup.groupname then + -- Group is already contained. + return nil + end + end + + + -- Create a new data item. local cargo={} --Ops.OpsGroup#OPSGROUP.CargoGroup - + cargo.opsgroup=opsgroup cargo.delivered=false cargo.status="Unknown" cargo.disembarkCarrierElement=nil cargo.disembarkCarrierGroup=nil + cargo.tzcUID=TransportZoneCombo return cargo end