mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-08-14 13:18:48 +00:00
Ops
This commit is contained in:
@@ -48,6 +48,7 @@
|
||||
AIRWING = {
|
||||
ClassName = "AIRWING",
|
||||
Debug = false,
|
||||
verbose = 0,
|
||||
lid = nil,
|
||||
menu = nil,
|
||||
squadrons = {},
|
||||
@@ -100,17 +101,17 @@ AIRWING.version="0.1.5"
|
||||
-- ToDo list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- DONE: Add squadrons to warehouse.
|
||||
-- TODO: Spawn in air or hot.
|
||||
-- TODO: Make special request to transfer squadrons to anther airwing (or warehouse).
|
||||
-- TODO: Border zone or even multiple zones.
|
||||
-- TODO: Check that airbase has enough parking spots if a request is BIG. Alternatively, split requests.
|
||||
-- DONE: Add squadrons to warehouse.
|
||||
-- DONE: Build mission queue.
|
||||
-- DONE: Find way to start missions.
|
||||
-- DONE: Check if missions are done/cancelled.
|
||||
-- DONE: Payloads as resources.
|
||||
-- TODO: Spawn in air or hot.
|
||||
-- DONE: Define CAP zones.
|
||||
-- DONE: Define TANKER zones for refuelling.
|
||||
-- TODO: Border zone or even multiple zones.
|
||||
-- TODO: Check that airbase has enough parking spots if a request is BIG. Alternatively, split requests.
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Constructor
|
||||
@@ -263,8 +264,8 @@ function AIRWING:NewPayload(Unit, MissionTypes, Npayloads, Unlimited, Priority)
|
||||
table.insert(self.payloads, payload)
|
||||
|
||||
-- Info
|
||||
self:I(self.lid..string.format("Adding new payload from unit %s for aircraft type %s: N=%d (unlimited=%s), missions:", payload.unitname, payload.aircrafttype, payload.navail, tostring(payload.unlimited)))
|
||||
self:I({MissionTypes=payload.missiontypes})
|
||||
self:I(self.lid..string.format("Adding new payload from unit %s for aircraft type %s: N=%d (unlimited=%s), prio=%d, missions: %s",
|
||||
payload.unitname, payload.aircrafttype, payload.navail, tostring(payload.unlimited), payload.priority, table.concat(payload.missiontypes, ", ")))
|
||||
|
||||
return payload
|
||||
end
|
||||
@@ -280,15 +281,28 @@ end
|
||||
-- @return #AIRWING.Payload Payload table or *nil*.
|
||||
function AIRWING:FetchPayloadFromStock(UnitType, MissionType)
|
||||
|
||||
--- Sort payload wrt the following criteria:
|
||||
-- 1) Highest prio (lower value) is the main selection criterion.
|
||||
-- 2) If payloads have the same prio, unlimited payloads are preferred over limited ones.
|
||||
-- 3) If payloads have the same prio _and_ are limited, the abundant one is preferred.
|
||||
local function sortpayloads(a,b)
|
||||
local pA=a --#AIRWING.Payload
|
||||
local pB=b --#AIRWING.Payload
|
||||
return pA.priority<pB.priority
|
||||
end
|
||||
|
||||
return (pA.priority<pB.priority) or (pA.priority==pB.priority and pA.unlimited==true) or (pA.priority==pB.priority and pA.unlimited==true and pB.unlimited==true and pA.navail>pB.navail)
|
||||
end
|
||||
table.sort(self.payloads, sortpayloads)
|
||||
|
||||
--[[
|
||||
env.info("FF sorted payloads for mission type X and aircraft type=Y:")
|
||||
for _,_payload in ipairs(self.payloads) do
|
||||
local payload=_payload --#AIRWING.Payload
|
||||
if payload.aircrafttype==UnitType and self:CheckMissionType(MissionType, payload.missiontypes) then
|
||||
self:I(string.format("FF %s payload for %s: avail=%d prio=%d", MissionType, payload.aircrafttype, payload.navail, payload.priority))
|
||||
end
|
||||
end
|
||||
]]
|
||||
|
||||
for _,_payload in pairs(self.payloads) do
|
||||
for _,_payload in ipairs(self.payloads) do
|
||||
local payload=_payload --#AIRWING.Payload
|
||||
|
||||
|
||||
@@ -300,6 +314,8 @@ function AIRWING:FetchPayloadFromStock(UnitType, MissionType)
|
||||
payload.navail=payload.navail-1
|
||||
end
|
||||
|
||||
--self:I(string.format("FETCHING %s payload for %s: avail=%d prio=%d", MissionType, payload.aircrafttype, payload.navail, payload.priority))
|
||||
|
||||
-- Return a copy of the table.
|
||||
return payload
|
||||
end
|
||||
@@ -618,8 +634,12 @@ function AIRWING:onafterStatus(From, Event, To)
|
||||
for i,_squadron in pairs(self.squadrons) do
|
||||
local squadron=_squadron --Ops.Squadron#SQUADRON
|
||||
|
||||
local callsign=squadron.callsignName and squadron.callsignName or "N/A"
|
||||
local modex=squadron.modex and squadron.modex or "N/A"
|
||||
local skill=squadron.skill and tostring(squadron.skill) or "N/A"
|
||||
|
||||
-- Squadron text
|
||||
text=text..string.format("\n* %s %s", squadron.name, squadron:GetState())
|
||||
text=text..string.format("\n* %s %s: Callsign=%s, Modex=%d, Skill=%s", squadron.name, squadron:GetState(), callsign, modex, skill)
|
||||
|
||||
-- Loop over all assets.
|
||||
for j,_asset in pairs(squadron.assets) do
|
||||
|
||||
@@ -159,6 +159,8 @@ AUFTRAG = {
|
||||
missionFraction = 0.5,
|
||||
enrouteTasks = {},
|
||||
markerID = nil,
|
||||
startconditions = {},
|
||||
stopconditions = {},
|
||||
}
|
||||
|
||||
--- Global mission counter.
|
||||
@@ -182,6 +184,8 @@ _AUFTRAGSNR=0
|
||||
-- @field #string ORBIT Orbit mission.
|
||||
-- @field #string PATROL Similar to CAP but no auto engage targets.
|
||||
-- @field #string RECON Recon mission.
|
||||
-- @field #string RECOVERYTANKER Recovery tanker mission.
|
||||
-- @field #string RESCUEHELO Rescue helo.
|
||||
-- @field #string SEAD Suppression/destruction of enemy air defences.
|
||||
-- @field #string STRIKE Strike mission.
|
||||
-- @field #string TANKER Tanker mission.
|
||||
@@ -202,6 +206,8 @@ AUFTRAG.Type={
|
||||
ORBIT="Orbit",
|
||||
PATROL="Patrol",
|
||||
RECON="Recon",
|
||||
RECOVERYTANKER="Recovery Tanker",
|
||||
RESCUEHELO="Rescue Helo",
|
||||
SEAD="SEAD",
|
||||
STRIKE="Strike",
|
||||
TANKER="Tanker",
|
||||
@@ -272,6 +278,7 @@ AUFTRAG.TargetType={
|
||||
-- @field Wrapper.Positionable#POSITIONABLE Target Target Object.
|
||||
-- @field #string Type Target type: "Group", "Unit", "Static", "Coordinate", "Airbase.
|
||||
-- @field #number Ninital Number of initial targets.
|
||||
-- @field #number Lifepoints Total life points.
|
||||
|
||||
--- Mission success.
|
||||
-- @type AUFTRAG.Success
|
||||
@@ -297,6 +304,9 @@ AUFTRAG.version="0.0.9"
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: Add mission start conditions.
|
||||
-- TODO: Add recovery tanker mission for boat ops.
|
||||
-- TODO: Add rescue helo mission for boat ops.
|
||||
-- TODO: Mission success options damaged, destroyed.
|
||||
-- DONE: Mission ROE and ROT.
|
||||
-- TODO: Mission frequency, formation, etc.
|
||||
@@ -313,7 +323,7 @@ AUFTRAG.version="0.0.9"
|
||||
-- Constructor
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Create a new AUFTRAG object.
|
||||
--- Create a new generic AUFTRAG object.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param #string Type Mission type.
|
||||
-- @return #AUFTRAG self
|
||||
@@ -342,12 +352,9 @@ function AUFTRAG:New(Type)
|
||||
self:SetPriority()
|
||||
self:SetTime()
|
||||
self.engageAsGroup=true
|
||||
|
||||
self.missionRepeated=0
|
||||
self.missionRepeatMax=0
|
||||
|
||||
self.nassets=1
|
||||
|
||||
self.dTevaluate=0
|
||||
|
||||
-- FMS start state is PLANNED.
|
||||
@@ -365,7 +372,8 @@ function AUFTRAG:New(Type)
|
||||
self:AddTransition(AUFTRAG.Status.STARTED, "Executing", AUFTRAG.Status.EXECUTING) -- First asset is executing the mission.
|
||||
|
||||
self:AddTransition("*", "Done", AUFTRAG.Status.DONE) -- All assets have reported that mission is done.
|
||||
self:AddTransition("*", "Cancel", "*") --AUFTRAG.Status.CANCELLED) -- Command to cancel the mission.
|
||||
|
||||
self:AddTransition("*", "Cancel", "*") -- Command to cancel the mission.
|
||||
|
||||
self:AddTransition("*", "Success", AUFTRAG.Status.SUCCESS)
|
||||
self:AddTransition("*", "Failed", AUFTRAG.Status.FAILED)
|
||||
@@ -377,13 +385,9 @@ function AUFTRAG:New(Type)
|
||||
|
||||
self:AddTransition("*", "FlightDead", "*")
|
||||
self:AddTransition("*", "AssetDead", "*")
|
||||
|
||||
--[[
|
||||
self:HandleEvent(EVENTS.PilotDead, self._UnitDead)
|
||||
self:HandleEvent(EVENTS.Ejection, self._UnitDead)
|
||||
self:HandleEvent(EVENTS.Crash, self._UnitDead)
|
||||
]]
|
||||
|
||||
|
||||
-- Init status update.
|
||||
self:__Status(-1)
|
||||
|
||||
return self
|
||||
@@ -393,6 +397,27 @@ end
|
||||
-- Create Missions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Create a RESCUE HELO mission.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Wrapper.UnitUNIT Carrier The carrier unit.
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:NewRESCUEHELO(Carrier)
|
||||
|
||||
local mission=AUFTRAG:New(AUFTRAG.Type.RESCUEHELO)
|
||||
|
||||
mission.engageTarget=mission:_TargetFromObject(Target)
|
||||
mission.engageWeaponType=ENUMS.WeaponFlag.Auto
|
||||
|
||||
mission.missionTask=ENUMS.MissionTask.NOTHING
|
||||
mission.missionFraction=0.4
|
||||
mission.optionROE=ENUMS.ROE.OpenFire
|
||||
mission.optionROT=ENUMS.ROT.EvadeFire
|
||||
|
||||
mission.DCStask=mission:GetDCSMissionTask()
|
||||
|
||||
return mission
|
||||
end
|
||||
|
||||
--- Create an ANTI-SHIP mission.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Wrapper.Positionable#POSITIONABLE Target The target to attack. Can be passed as a @{Wrapper.Group#GROUP} or @{Wrapper.Unit#UNIT} object.
|
||||
@@ -729,7 +754,7 @@ end
|
||||
|
||||
--- Create a BOMBING mission. Flight will drop bombs a specified coordinate.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Core.Point#COORDINATE TargetCoordinate Target coordinate. Can also be specified as a GROUP, UNIT or STATIC object.
|
||||
-- @param Core.Point#COORDINATE Target Target coordinate. Can also be specified as a GROUP, UNIT or STATIC object.
|
||||
-- @param #number Altitude Engage altitude in feet. Default 25000 ft.
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:NewBOMBING(Target, Altitude)
|
||||
@@ -1903,6 +1928,56 @@ function AUFTRAG:CountMissionTargets()
|
||||
return N
|
||||
end
|
||||
|
||||
--- Get target life points.
|
||||
-- @param #AUFTRAG self
|
||||
-- @return #number Number of alive target units.
|
||||
function AUFTRAG:GetTargetLife()
|
||||
|
||||
local N=0
|
||||
|
||||
if self.engageTarget then
|
||||
|
||||
if self.engageTarget.Type==AUFTRAG.TargetType.GROUP then
|
||||
|
||||
local target=self.engageTarget.Target --Wrapper.Group#GROUP
|
||||
|
||||
local units=target:GetUnits()
|
||||
|
||||
for _,_unit in pairs(units or {}) do
|
||||
local unit=_unit --Wrapper.Unit#UNIT
|
||||
|
||||
-- We check that unit is "alive".
|
||||
if unit and unit:IsAlive() then
|
||||
N=N+unit:GetLife()
|
||||
end
|
||||
end
|
||||
|
||||
elseif self.engageTarget.Type==AUFTRAG.TargetType.UNIT then
|
||||
|
||||
local target=self.engageTarget.Target --Wrapper.Unit#UNIT
|
||||
|
||||
if target and target:IsAlive() then
|
||||
N=N+target:GetLife()
|
||||
end
|
||||
|
||||
elseif self.engageTarget.Type==AUFTRAG.TargetType.STATIC then
|
||||
|
||||
local target=self.engageTarget.Target --Wrapper.Static#STATIC
|
||||
|
||||
if target and target:IsAlive() then
|
||||
N=N+1 --target:GetLife()
|
||||
end
|
||||
|
||||
elseif self.engageTarget.Type==AUFTRAG.TargetType.AIRBASE then
|
||||
|
||||
-- TODO: any (good) way to tell whether an airbase was "destroyed" or at least damaged? Is :GetLive() working?
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return N
|
||||
end
|
||||
|
||||
--- Count alive flight groups assigned for this mission.
|
||||
-- @param #AUFTRAG self
|
||||
-- @return #number Number of alive flight groups.
|
||||
@@ -2251,7 +2326,7 @@ function AUFTRAG:GetDCSMissionTask()
|
||||
-- Count mission targets.
|
||||
self.Ntargets=self:CountMissionTargets()
|
||||
|
||||
self:I({Ntargets=self.Ntargets, missiontask=DCStasks})
|
||||
self:T({Ntargets=self.Ntargets, missiontask=DCStasks})
|
||||
|
||||
-- Return the task.
|
||||
if #DCStasks==1 then
|
||||
|
||||
@@ -372,6 +372,7 @@ FLIGHTGROUP.version="0.3.8"
|
||||
-- TODO list
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO: Use new UnitLost event instead of crash/dead.
|
||||
-- TODO: Options EPLRS, Afterburner restrict etc.
|
||||
-- TODO: Add TACAN beacon.
|
||||
-- TODO: Damage?
|
||||
@@ -2872,13 +2873,30 @@ function FLIGHTGROUP:onafterRTB(From, Event, To, airbase, SpeedTo, SpeedHold, Sp
|
||||
wp[#wp+1]=c0:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, UTILS.KnotsToKmph(SpeedTo), true , nil, {}, "Current Pos")
|
||||
wp[#wp+1]=p0:WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, UTILS.KnotsToKmph(SpeedTo), true , nil, {TaskArrived, TaskHold, TaskKlar}, "Holding Point")
|
||||
|
||||
-- Approach point: 10 NN in direction of runway.
|
||||
local papp=airbase:GetCoordinate():Translate(x1, runway.heading-180):SetAltitude(h1)
|
||||
wp[#wp+1]=papp:WaypointAirTurningPoint(nil, UTILS.KnotsToKmph(SpeedLand), {}, "Final Approach")
|
||||
-- Approach point: 10 NN in direction of runway.
|
||||
if airbase:GetAirbaseCategory()==Airbase.Category.AIRDROME then
|
||||
|
||||
-- Okay, it looks like it's best to specify the coordinates not at the airbase but a bit away. This causes a more direct landing approach.
|
||||
local pland=airbase:GetCoordinate():Translate(x2, runway.heading-180):SetAltitude(h2)
|
||||
wp[#wp+1]=pland:WaypointAirLanding(UTILS.KnotsToKmph(SpeedLand), airbase, {}, "Landing")
|
||||
---
|
||||
-- Airdrome
|
||||
---
|
||||
|
||||
local papp=airbase:GetCoordinate():Translate(x1, runway.heading-180):SetAltitude(h1)
|
||||
wp[#wp+1]=papp:WaypointAirTurningPoint(nil, UTILS.KnotsToKmph(SpeedLand), {}, "Final Approach")
|
||||
|
||||
-- Okay, it looks like it's best to specify the coordinates not at the airbase but a bit away. This causes a more direct landing approach.
|
||||
local pland=airbase:GetCoordinate():Translate(x2, runway.heading-180):SetAltitude(h2)
|
||||
wp[#wp+1]=pland:WaypointAirLanding(UTILS.KnotsToKmph(SpeedLand), airbase, {}, "Landing")
|
||||
|
||||
elseif airbase:GetAirbaseCategory()==Airbase.Category.SHIP then
|
||||
|
||||
---
|
||||
-- Ship
|
||||
---
|
||||
|
||||
local pland=airbase:GetCoordinate()
|
||||
wp[#wp+1]=pland:WaypointAirLanding(UTILS.KnotsToKmph(SpeedLand), airbase, {}, "Landing")
|
||||
|
||||
end
|
||||
|
||||
-- Respawn?
|
||||
if fc or world.event.S_EVENT_KILL then
|
||||
|
||||
@@ -192,7 +192,16 @@ end
|
||||
-- User functions
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Set livery.
|
||||
--- Set livery painted on all squadron aircraft.
|
||||
-- Note that the livery name in general is different from the name shown in the mission editor.
|
||||
--
|
||||
-- Valid names are the names of the **livery directories**. Check out the folder in your DCS installation:
|
||||
--
|
||||
-- * `DCS World OpenBeta\CoreMods\aircraft\<Aircraft Type>\<Livery Name>`
|
||||
-- * `DCS World OpenBeta\Bazar\Liveries\<Aircraft Type>\<Livery Name>`
|
||||
--
|
||||
-- Or personal liveries you have installed somewhere in your saved games folder.
|
||||
--
|
||||
-- @param #SQUADRON self
|
||||
-- @param #string LiveryName Name of the livery.
|
||||
-- @return #SQUADRON self
|
||||
@@ -201,9 +210,10 @@ function SQUADRON:SetLivery(LiveryName)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set skill.
|
||||
--- Set skill level of all squadron team members.
|
||||
-- @param #SQUADRON self
|
||||
-- @param #string Skill Skill of all flights.
|
||||
-- @usage mysquadron:SetSkill(AI.Skill.EXCELLENT)
|
||||
-- @return #SQUADRON self
|
||||
function SQUADRON:SetSkill(Skill)
|
||||
self.skill=Skill
|
||||
|
||||
Reference in New Issue
Block a user