From ba591c9dc5bae9f10761d7eb6d563ecb2177c172 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 29 Apr 2022 22:00:23 +0200 Subject: [PATCH] OPS **AUFTRAG** - Added new type `NOTHING` (similar to `ALERT5` but for ground/naval) --- Moose Development/Moose/Ops/ArmyGroup.lua | 5 +- Moose Development/Moose/Ops/Auftrag.lua | 71 ++++++++------- Moose Development/Moose/Ops/Cohort.lua | 33 +++++-- Moose Development/Moose/Ops/FlightGroup.lua | 13 +++ Moose Development/Moose/Ops/Flotilla.lua | 8 +- Moose Development/Moose/Ops/Legion.lua | 6 +- Moose Development/Moose/Ops/NavyGroup.lua | 3 + Moose Development/Moose/Ops/OpsGroup.lua | 96 ++++++++++++++++----- Moose Development/Moose/Ops/Platoon.lua | 5 +- 9 files changed, 178 insertions(+), 62 deletions(-) diff --git a/Moose Development/Moose/Ops/ArmyGroup.lua b/Moose Development/Moose/Ops/ArmyGroup.lua index d4ffc672d..8e330e9f8 100644 --- a/Moose Development/Moose/Ops/ArmyGroup.lua +++ b/Moose Development/Moose/Ops/ArmyGroup.lua @@ -1149,7 +1149,7 @@ function ARMYGROUP:onafterOutOfAmmo(From, Event, To) end -- Third, check if we want to RTZ once out of ammo. - if self.rtzOnOutOfAmmo then + if self.rtzOnOutOfAmmo then self:__RTZ(-1) end @@ -1251,6 +1251,9 @@ function ARMYGROUP:onafterRTZ(From, Event, To, Zone, Formation) -- Zone. local zone=Zone or self.homezone + -- Cancel all missions in the queue. + self:CancelAllMissions() + if zone then if self:IsInZone(zone) then diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index 387eb7777..77503da0e 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -610,7 +610,7 @@ AUFTRAG.Category={ --- AUFTRAG class version. -- @field #string version -AUFTRAG.version="0.9.4" +AUFTRAG.version="0.9.5" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -1615,7 +1615,7 @@ function AUFTRAG:NewRESCUEHELO(Carrier) return mission end ---- **[AIRPANE]** Create a RECOVERY TANKER mission. +--- **[AIRPANE]** Create a RECOVERY TANKER mission. **WIP and not working coorectly yet!** -- @param #AUFTRAG self -- @param Wrapper.Unit#UNIT Carrier The carrier unit. -- @return #AUFTRAG self @@ -1630,6 +1630,9 @@ function AUFTRAG:NewRECOVERYTANKER(Carrier) mission.missionFraction=0.5 mission.optionROE=ENUMS.ROE.WeaponHold mission.optionROT=ENUMS.ROT.NoReaction + + mission.missionAltitude=UTILS.FeetToMeters(6000) + mission.missionSpeed=UTILS.KnotsToKmph(274) mission.categories={AUFTRAG.Category.AIRPLANE} @@ -2113,24 +2116,24 @@ function AUFTRAG:_NewRELOCATECOHORT(Legion, Cohort) return mission end ---- **[AIR, GROUND, NAVAL]** Create a mission to do NOTHING. +--- **[GROUND, NAVAL]** Create a mission to do NOTHING. -- @param #AUFTRAG self +-- @param Core.Zone#ZONE RelaxZone Zone where the assets are supposed to do nothing. -- @return #AUFTRAG self -function AUFTRAG:NewNOTHING() +function AUFTRAG:NewNOTHING(RelaxZone) local mission=AUFTRAG:New(AUFTRAG.Type.NOTHING) - --mission:_TargetFromObject(Coordinate) + mission:_TargetFromObject(RelaxZone) mission.optionROE=ENUMS.ROE.WeaponHold - mission.optionAlarm=ENUMS.AlarmState.Green + mission.optionAlarm=ENUMS.AlarmState.Auto mission.missionFraction=1.0 - mission.categories={AUFTRAG.Category.ALL} + mission.categories={AUFTRAG.Category.GROUND, AUFTRAG.Category.NAVAL} mission.DCStask=mission:GetDCSMissionTask() - mission.DCStask.params.adinfinitum=true return mission end @@ -2748,7 +2751,7 @@ function AUFTRAG:SetRequiredAttribute(Attributes) end --- Set required property or properties the assets must have. --- These are DCS attributes. +-- These are [DCS attributes](https://wiki.hoggitworld.com/view/DCS_enum_attributes). -- @param #AUFTRAG self -- @param #table Properties Property or table of properties. -- @return #AUFTRAG self @@ -5101,9 +5104,8 @@ end --- Get DCS task table for the given mission. -- @param #AUFTRAG self --- @param Wrapper.Controllable#CONTROLLABLE TaskControllable The controllable for which this task is set. Most tasks don't need it. -- @return DCS#Task The DCS task table. If multiple tasks are necessary, this is returned as a combo task. -function AUFTRAG:GetDCSMissionTask(TaskControllable) +function AUFTRAG:GetDCSMissionTask() local DCStasks={} @@ -5238,32 +5240,43 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) elseif self.type==AUFTRAG.Type.RECOVERYTANKER then - - --[[ - local DCStask={} - - DCStask.id=AUFTRAG.SpecialTask.RECOVERYTANKER - - -- We create a "fake" DCS task. - local param={} - DCStask.params=param - - ]] + ---------------------------- + -- RECOVERYTANKER Mission -- + ---------------------------- + -- Get the carrier unit. local Carrier=self:GetObjective() --Wrapper.Unit#UNIT - local heading=Carrier:GetHeading() + -- Carrier coordinate. + local Coord=Carrier:GetCoordinate() - local Altitude=2000 - - local Coordinate=Carrier:GetCoordinate():SetAltitude(2000) - - local RaceTrack=Coordinate:Translate(1000, heading, true) + -- Get current heading of carrier. + local hdg=Carrier:GetHeading() - local DCStask=CONTROLLABLE.TaskOrbit(nil, Coordinate, Altitude, 300, RaceTrack) + -- Altitude + local Altitude=self.missionAltitude + -- Race-track distances. + local distStern=UTILS.NMToMeters(4) + local distBow=UTILS.NMToMeters(10) + + -- Racetrack pattern points. + local p1=Coord:Translate(distStern, hdg):SetAltitude(self.missionAltitude) + local p2=Coord:Translate(distBow, hdg):SetAltitude(self.missionAltitude) + + p1:MarkToAll("p1") + p2:MarkToAll("p2") + + -- Set speed in m/s. + local Speed=UTILS.KmphToMps(self.missionSpeed) + + -- Orbit task. + local DCStask=CONTROLLABLE.TaskOrbit(nil, p1, Altitude, Speed, p2) + + -- Set carrier as parameter. DCStask.params.carrier=Carrier + -- Add to DCS tasks. table.insert(DCStasks, DCStask) elseif self.type==AUFTRAG.Type.INTERCEPT then diff --git a/Moose Development/Moose/Ops/Cohort.lua b/Moose Development/Moose/Ops/Cohort.lua index e5626c065..fe90c4e2f 100644 --- a/Moose Development/Moose/Ops/Cohort.lua +++ b/Moose Development/Moose/Ops/Cohort.lua @@ -86,7 +86,7 @@ COHORT = { --- COHORT class version. -- @field #string version -COHORT.version="0.3.4" +COHORT.version="0.3.5" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -391,10 +391,12 @@ function COHORT:AddMissionCapability(MissionTypes, Performance) for _,missiontype in pairs(MissionTypes) do + local Capability=self:GetMissionCapability(missiontype) + -- Check not to add the same twice. - if AUFTRAG.CheckMissionCapability(missiontype, self.missiontypes) then - self:E(self.lid.."WARNING: Mission capability already present! No need to add it twice.") - -- TODO: update performance. + if Capability then + self:E(self.lid.."WARNING: Mission capability already present! No need to add it twice. Will update the performance though!") + Capability.Performance=Performance or 50 else local capability={} --Ops.Auftrag#AUFTRAG.Capability @@ -411,6 +413,22 @@ function COHORT:AddMissionCapability(MissionTypes, Performance) return self end +--- Get missin capability for a given mission type. +-- @param #COHORT self +-- @param #string MissionType Mission type, e.g. `AUFTRAG.Type.BAI`. +-- @return Ops.Auftrag#AUFTRAG.Capability Capability table or `nil` if the capability does not exist. +function COHORT:GetMissionCapability(MissionType) + + for _,_capability in pairs(self.missiontypes) do + local capability=_capability --Ops.Auftrag#AUFTRAG.Capability + if capability.MissionType==MissionType then + return capability + end + end + + return nil +end + --- Check if cohort assets have a given property (DCS attribute). -- @param #COHORT self -- @param #string Property The property. @@ -1008,12 +1026,17 @@ function COHORT:RecruitAssets(MissionType, Npayloads) -- Asset is already on a mission. --- - -- Check if this asset is currently on a GCICAP mission (STARTED or EXECUTING). + -- Check if this asset is currently on a mission (STARTED or EXECUTING). if MissionType==AUFTRAG.Type.RELOCATECOHORT then -- Relocation: Take all assets. Mission will be cancelled. table.insert(assets, asset) + elseif self.legion:IsAssetOnMission(asset, AUFTRAG.Type.NOTHING) then + + -- Relocation: Take all assets. Mission will be cancelled. + table.insert(assets, asset) + elseif self.legion:IsAssetOnMission(asset, AUFTRAG.Type.GCICAP) and MissionType==AUFTRAG.Type.INTERCEPT then -- Check if the payload of this asset is compatible with the mission. diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index aa0f1f860..6cc77618f 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -1041,6 +1041,19 @@ function FLIGHTGROUP:Status() --- self:_PrintTaskAndMissionStatus() + + -- Current mission. + local mission=self:GetMissionCurrent() + + if mission and mission.type==AUFTRAG.Type.RECOVERYTANKER and mission:GetGroupStatus(self)==AUFTRAG.GroupStatus.EXECUTING then + + --env.info("FF recovery tanker updating DCS task") + --self:ClearTasks() + + local DCSTask=mission:GetDCSMissionTask() + self:SetTask(DCSTask) + + end end diff --git a/Moose Development/Moose/Ops/Flotilla.lua b/Moose Development/Moose/Ops/Flotilla.lua index 7711f9b60..179925658 100644 --- a/Moose Development/Moose/Ops/Flotilla.lua +++ b/Moose Development/Moose/Ops/Flotilla.lua @@ -41,13 +41,13 @@ FLOTILLA = { --- FLOTILLA class version. -- @field #string version -FLOTILLA.version="0.0.1" +FLOTILLA.version="0.1.0" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- TODO: Add weapon data. +-- TODO: A lot. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constructor @@ -63,7 +63,11 @@ function FLOTILLA:New(TemplateGroupName, Ngroups, FlotillaName) -- Inherit everything from COHORT class. local self=BASE:Inherit(self, COHORT:New(TemplateGroupName, Ngroups, FlotillaName)) -- #FLOTILLA + + -- All flotillas get mission type Nothing. + self:AddMissionCapability(AUFTRAG.Type.NOTHING, 50) + -- Get initial ammo. self.ammo=self:_CheckAmmo() return self diff --git a/Moose Development/Moose/Ops/Legion.lua b/Moose Development/Moose/Ops/Legion.lua index 477934925..5479e94f2 100644 --- a/Moose Development/Moose/Ops/Legion.lua +++ b/Moose Development/Moose/Ops/Legion.lua @@ -47,7 +47,7 @@ LEGION = { --- LEGION class version. -- @field #string version -LEGION.version="0.3.2" +LEGION.version="0.3.3" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -864,6 +864,8 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission) pause=true elseif (currM.type==AUFTRAG.Type.ONGUARD or currM.type==AUFTRAG.Type.PATROLZONE) and (Mission.type==AUFTRAG.Type.ARTY or Mission.type==AUFTRAG.Type.GROUNDATTACK) then pause=true + elseif currM.type==AUFTRAG.Type.NOTHING then + pause=true end -- Cancel current ALERT5 mission. @@ -2759,6 +2761,8 @@ function LEGION.CalculateAssetMissionScore(asset, MissionType, TargetVec2, Inclu score=score+25 elseif (currmission.type==AUFTRAG.Type.ONGUARD or currmission.type==AUFTRAG.Type.PATROLZONE) and (MissionType==AUFTRAG.Type.ARTY or MissionType==AUFTRAG.Type.GROUNDATTACK) then score=score+25 + elseif currmission.type==AUFTRAG.Type.NOTHING then + score=score+25 end end diff --git a/Moose Development/Moose/Ops/NavyGroup.lua b/Moose Development/Moose/Ops/NavyGroup.lua index 176b22fb6..a770297b0 100644 --- a/Moose Development/Moose/Ops/NavyGroup.lua +++ b/Moose Development/Moose/Ops/NavyGroup.lua @@ -1584,6 +1584,9 @@ function NAVYGROUP:onafterRTZ(From, Event, To, Zone, Formation) -- Zone. local zone=Zone or self.homezone + -- Cancel all missions in the queue. + self:CancelAllMissions() + if zone then if self:IsInZone(zone) then diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 82b2094b2..dd4b628e6 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -3969,6 +3969,22 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task) -- FLIGHTGROUP not implemented (intended!) for this AUFTRAG type. end + elseif Task.dcstask.id==AUFTRAG.SpecialTask.NOTHING then + + --- + -- Task "Nothing" Mission. + --- + + -- Just stay put. + --TODO: Change ALARM STATE + + if self:IsArmygroup() or self:IsNavygroup() then + -- Especially NAVYGROUP needs a full stop as patrol ad infinitum + self:FullStop() + else + -- FLIGHTGROUP not implemented (intended!) for this AUFTRAG type. + end + elseif Task.dcstask.id==AUFTRAG.SpecialTask.AIRDEFENSE or Task.dcstask.id==AUFTRAG.SpecialTask.EWR then --- @@ -4064,7 +4080,7 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task) end wp.missionUID=Mission and Mission.auftragsnummer or nil - + else -- If task is scheduled (not waypoint) set task. @@ -4108,8 +4124,15 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task) -- Number of ammo avail. local nAmmo=ammo.Total - if DCSTask.params.weaponType then - --TODO: use weapon type infor, e.g. for cruise missiles + local weaponType=DCSTask.params.weaponType or -1 + + -- Adjust max number of ammo for specific weapon types requested. + if weaponType==ENUMS.WeaponFlag.CruiseMissile then + nAmmo=ammo.MissilesCR + elseif weaponType==ENUMS.WeaponFlag.AnyRocket then + nAmmo=ammo.Rockets + elseif weaponType==ENUMS.WeaponFlag.Cannons then + nAmmo=ammo.Guns end --TODO: Update target location while we're at it anyway. @@ -4127,6 +4150,13 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task) -- Set quantity of task. DCSTask.params.expendQty=nShots + elseif Mission and Mission.type==AUFTRAG.Type.RECOVERYTANKER then + + env.info("FF recoverytanker setting DCS task") + + -- Update DCS task with the current carrier parameters. + DCSTask=Mission:GetDCSMissionTask() + else --- -- Take DCS task @@ -4230,6 +4260,8 @@ function OPSGROUP:onafterTaskCancel(From, Event, To, Task) done=true elseif Task.dcstask.id==AUFTRAG.SpecialTask.GROUNDATTACK or Task.dcstask.id==AUFTRAG.SpecialTask.ARMORATTACK then done=true + elseif Task.dcstask.id==AUFTRAG.SpecialTask.NOTHING then + done=true elseif stopflag==1 or (not self:IsAlive()) or self:IsDead() or self:IsStopped() then -- Manual call TaskDone if setting flag to one was not successful. done=true @@ -4344,7 +4376,7 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task) self:Disengage() end - if Task.description==AUFTRAG.SpecialTask.ONGUARD or Task.description==AUFTRAG.SpecialTask.ARMOREDGUARD then + if Task.description==AUFTRAG.SpecialTask.ONGUARD or Task.description==AUFTRAG.SpecialTask.ARMOREDGUARD or Task.description==AUFTRAG.SpecialTask.NOTHING then self:T(self.lid.."Task DONE OnGuard ==> Cruise") self:Cruise() end @@ -4829,7 +4861,8 @@ function OPSGROUP:onafterMissionCancel(From, Event, To, Mission) -- Alert 5 missoins dont have a task set, which could be cancelled. if Mission.type==AUFTRAG.Type.ALERT5 or Mission.type==AUFTRAG.Type.ONGUARD or - Mission.type==AUFTRAG.Type.ARMOREDGUARD or + Mission.type==AUFTRAG.Type.ARMOREDGUARD or + Mission.type==AUFTRAG.Type.NOTHING or Mission.type==AUFTRAG.Type.AIRDEFENSE or Mission.type==AUFTRAG.Type.EWR then @@ -5115,7 +5148,18 @@ function OPSGROUP:RouteToMission(mission, delay) -- Mission waypoint waypointcoord=mission:GetMissionWaypointCoord(self.group, nil, surfacetypes) + + elseif mission.type==AUFTRAG.Type.NOTHING then + --- + -- Nothing + --- + + -- Get the zone. + targetzone=mission.engageTarget:GetObject() --Core.Zone#ZONE + -- Random coordinate. + waypointcoord=targetzone:GetRandomCoordinate(nil , nil, surfacetypes) + elseif mission.type==AUFTRAG.Type.HOVER then --- -- Hover @@ -5143,10 +5187,16 @@ function OPSGROUP:RouteToMission(mission, delay) -- Recoverytanker --- + local carrier=mission.DCStask.params.carrier --Wrapper.Unit#UNIT + -- Roughly go to the new legion. - local CarrierCoordinate=mission.DCStask.params.carrier:GetCoordinate() + local CarrierCoordinate=carrier:GetCoordinate() - waypointcoord=CarrierCoordinate:Translate(5000, 90):SetAltitude(2000) + local heading=carrier:GetHeading() + + waypointcoord=CarrierCoordinate:Translate(10000, heading-180):SetAltitude(2000) + + waypointcoord:MarkToAll("Recoverytanker",ReadOnly,Text) else --- @@ -9427,12 +9477,27 @@ function OPSGROUP:_CheckGroupDone(delay) return end + -- Number of tasks remaining. + local nTasks=self:CountRemainingTasks() + + -- Number of mission remaining. + local nMissions=self:CountRemainingMissison() + + -- Number of cargo transports remaining. + local nTransports=self:CountRemainingTransports() + -- First check if there is a paused mission that - if self.missionpaused then + if self.missionpaused and nMissions==1 then self:T(self.lid..string.format("Found paused mission %s [%s]. Unpausing mission...", self.missionpaused.name, self.missionpaused.type)) self:UnpauseMission() return end + + -- Number of remaining tasks/missions? + if nTasks>0 or nMissions>0 or nTransports>0 then + self:T(self.lid..string.format("Group still has tasks, missions or transports ==> NOT DONE")) + return + end -- Get current waypoint. local waypoint=self:GetWaypoint(self.currentwp) @@ -9449,21 +9514,6 @@ function OPSGROUP:_CheckGroupDone(delay) end end - -- Number of tasks remaining. - local nTasks=self:CountRemainingTasks() - - -- Number of mission remaining. - local nMissions=self:CountRemainingMissison() - - -- Number of cargo transports remaining. - local nTransports=self:CountRemainingTransports() - - -- Number of remaining tasks/missions? - if nTasks>0 or nMissions>0 or nTransports>0 then - self:T(self.lid..string.format("Group still has tasks, missions or transports ==> NOT DONE")) - return - end - if self.adinfinitum then --- diff --git a/Moose Development/Moose/Ops/Platoon.lua b/Moose Development/Moose/Ops/Platoon.lua index 100095cc2..405cb2268 100644 --- a/Moose Development/Moose/Ops/Platoon.lua +++ b/Moose Development/Moose/Ops/Platoon.lua @@ -46,7 +46,7 @@ PLATOON.version="0.1.0" -- TODO list ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- TODO: Add weapon data. +-- TODO: A lot. ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Constructor @@ -62,6 +62,9 @@ function PLATOON:New(TemplateGroupName, Ngroups, PlatoonName) -- Inherit everything from COHORT class. local self=BASE:Inherit(self, COHORT:New(TemplateGroupName, Ngroups, PlatoonName)) -- #PLATOON + + -- All platoons get mission type Nothing. + self:AddMissionCapability(AUFTRAG.Type.NOTHING, 50) -- Get ammo. self.ammo=self:_CheckAmmo()