mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Compare commits
17 Commits
ac7cdb7d16
...
ca3fb4e479
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca3fb4e479 | ||
|
|
40d4dc14ab | ||
|
|
618a5ca9be | ||
|
|
c1997d9f70 | ||
|
|
bb1caa6642 | ||
|
|
638f083729 | ||
|
|
59d41cf98b | ||
|
|
793adafda7 | ||
|
|
dd5ca93f26 | ||
|
|
f7a86deba5 | ||
|
|
740f90a513 | ||
|
|
0d1a7c770b | ||
|
|
1889df4952 | ||
|
|
7ca219748d | ||
|
|
b3f944e82e | ||
|
|
2fc16ba694 | ||
|
|
efceb095d2 |
@@ -2798,7 +2798,7 @@ function ATIS:onafterBroadcast( From, Event, To )
|
||||
|
||||
end
|
||||
_RUNACT = subtitle
|
||||
alltext = alltext .. ";\n" .. subtitle
|
||||
--alltext = alltext .. ";\n" .. subtitle
|
||||
|
||||
-- Runway length.
|
||||
if self.rwylength then
|
||||
|
||||
@@ -1715,6 +1715,42 @@ function AUFTRAG:NewSEAD(Target, Altitude)
|
||||
return mission
|
||||
end
|
||||
|
||||
--- **[AIR]** Create a SEAD in Zone mission.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Core.Zone#ZONE TargetZone The target zone to attack.
|
||||
-- @param #number Altitude Engage altitude in feet. Default 25000 ft.
|
||||
-- @param #table TargetTypes Table of string of DCS known target types, defaults to {"Air defence"}. See [DCS Target Attributes](https://wiki.hoggitworld.com/view/DCS_enum_attributes)
|
||||
-- @param #number Duration Engage this much time when the AUFTRAG starts executing.
|
||||
-- @return #AUFTRAG self
|
||||
function AUFTRAG:NewSEADInZone(TargetZone, Altitude, TargetTypes, Duration)
|
||||
|
||||
local mission=AUFTRAG:New(AUFTRAG.Type.SEAD)
|
||||
|
||||
mission:_TargetFromObject(TargetZone)
|
||||
|
||||
-- DCS Task options:
|
||||
mission.engageWeaponType=ENUMS.WeaponFlag.Auto
|
||||
mission.engageWeaponExpend=AI.Task.WeaponExpend.ALL
|
||||
mission.engageAltitude=UTILS.FeetToMeters(Altitude or 25000)
|
||||
mission.engageZone = TargetZone
|
||||
mission.engageTargetTypes = TargetTypes or {"Air defence"}
|
||||
|
||||
-- Mission options:
|
||||
mission.missionTask=ENUMS.MissionTask.SEAD
|
||||
mission.missionAltitude=mission.engageAltitude
|
||||
mission.missionFraction=0.7
|
||||
mission.optionROE=ENUMS.ROE.OpenFire
|
||||
mission.optionROT=ENUMS.ROT.EvadeFire
|
||||
|
||||
mission.categories={AUFTRAG.Category.AIRCRAFT}
|
||||
|
||||
mission.DCStask=mission:GetDCSMissionTask()
|
||||
|
||||
mission:SetDuration(Duration or 1800)
|
||||
|
||||
return mission
|
||||
end
|
||||
|
||||
--- **[AIR]** Create a STRIKE mission. Flight will attack the closest map object to the specified coordinate.
|
||||
-- @param #AUFTRAG self
|
||||
-- @param Core.Point#COORDINATE Target The target coordinate. Can also be given as a GROUP, UNIT, STATIC, SET_GROUP, SET_UNIT, SET_STATIC or TARGET object.
|
||||
@@ -4822,6 +4858,11 @@ function AUFTRAG:CheckGroupsDone()
|
||||
self:T(self.lid..string.format("CheckGroupsDone: Mission is STARTED state %s [FSM=%s] but count of alive OPSGROUP is zero. Mission DONE!", self.status, self:GetState()))
|
||||
return true
|
||||
end
|
||||
|
||||
if (self:IsStarted() or self:IsExecuting()) and self:CountOpsGroups()>0 then
|
||||
self:T(self.lid..string.format("CheckGroupsDone: Mission is STARTED state %s [FSM=%s] and count of alive OPSGROUP > zero. Mission NOT DONE!", self.status, self:GetState()))
|
||||
return true
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
@@ -6305,9 +6346,35 @@ function AUFTRAG:GetDCSMissionTask()
|
||||
-- Add enroute task SEAD. Disabled that here because the group enganges everything on its route.
|
||||
--local DCStask=CONTROLLABLE.EnRouteTaskSEAD(nil, self.TargetType)
|
||||
--table.insert(self.enrouteTasks, DCStask)
|
||||
|
||||
self:_GetDCSAttackTask(self.engageTarget, DCStasks)
|
||||
|
||||
|
||||
if self.engageZone then
|
||||
|
||||
--local DCStask=CONTROLLABLE.EnRouteTaskSEAD(nil, self.engageTargetTypes)
|
||||
--table.insert(self.enrouteTasks, DCStask)
|
||||
self.engageZone:Scan({Object.Category.UNIT},{Unit.Category.GROUND_UNIT})
|
||||
local ScanUnitSet = self.engageZone:GetScannedSetUnit()
|
||||
local SeadUnitSet = SET_UNIT:New()
|
||||
for _,_unit in pairs (ScanUnitSet.Set) do
|
||||
local unit = _unit -- Wrapper.Unit#UNTI
|
||||
if unit and unit:IsAlive() and unit:HasSEAD() then
|
||||
self:T("Adding UNIT for SEAD: "..unit:GetName())
|
||||
local task = CONTROLLABLE.TaskAttackUnit(nil,unit,GroupAttack,AI.Task.WeaponExpend.ALL,1,Direction,self.engageAltitude,4161536)
|
||||
table.insert(DCStasks, task)
|
||||
SeadUnitSet:AddUnit(unit)
|
||||
end
|
||||
end
|
||||
self.engageTarget = TARGET:New(SeadUnitSet)
|
||||
--local OrbitTask = CONTROLLABLE.TaskOrbitCircle(nil,self.engageAltitude,self.missionSpeed,self.engageZone:GetCoordinate())
|
||||
--local Point = self.engageZone:GetVec2()
|
||||
--local OrbitTask = CONTROLLABLE.TaskOrbitCircleAtVec2(nil,Point,self.engageAltitude,self.missionSpeed)
|
||||
--table.insert(DCStasks, OrbitTask)
|
||||
|
||||
else
|
||||
|
||||
self:_GetDCSAttackTask(self.engageTarget, DCStasks)
|
||||
|
||||
end
|
||||
|
||||
elseif self.type==AUFTRAG.Type.STRIKE then
|
||||
|
||||
--------------------
|
||||
|
||||
@@ -263,6 +263,7 @@ CSAR = {
|
||||
rescuedpilots = 0,
|
||||
limitmaxdownedpilots = true,
|
||||
maxdownedpilots = 10,
|
||||
useFIFOLimitReplacement = false, -- If true, it will remove the oldest downed pilot when a new one is added, if the limit is reached.
|
||||
allheligroupset = nil,
|
||||
topmenuname = "CSAR",
|
||||
ADFRadioPwr = 1000,
|
||||
@@ -313,7 +314,7 @@ CSAR.AircraftType["CH-47Fbl1"] = 31
|
||||
|
||||
--- CSAR class version.
|
||||
-- @field #string version
|
||||
CSAR.version="1.0.32"
|
||||
CSAR.version="1.0.33"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- ToDo list
|
||||
@@ -1144,19 +1145,8 @@ function CSAR:_EventHandler(EventData)
|
||||
self:T("Double Ejection!")
|
||||
return self
|
||||
end
|
||||
|
||||
-- limit no of pilots in the field.
|
||||
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
||||
self:T("Maxed Downed Pilot!")
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
-- TODO: Over water check --- EVENTS.LandingAfterEjection NOT triggered by DCS, so handle csarUsePara = true case
|
||||
-- might create dual pilots in edge cases
|
||||
|
||||
local wetfeet = false
|
||||
|
||||
|
||||
|
||||
local initdcscoord = nil
|
||||
local initcoord = nil
|
||||
if _event.id == EVENTS.Ejection then
|
||||
@@ -1168,6 +1158,36 @@ function CSAR:_EventHandler(EventData)
|
||||
initcoord = COORDINATE:NewFromVec3(initdcscoord)
|
||||
self:T({initdcscoord})
|
||||
end
|
||||
|
||||
-- Remove downed pilot if already exists to replace with new one.
|
||||
if _event.IniPlayerName then
|
||||
local PilotTable = self.downedPilots --#CSAR.DownedPilot
|
||||
local _foundPilot = nil
|
||||
for _,_pilot in pairs(PilotTable) do
|
||||
if _pilot.player == _event.IniPlayerName and _pilot.alive == true then
|
||||
_foundPilot = _pilot
|
||||
break
|
||||
end
|
||||
end
|
||||
if _foundPilot then
|
||||
self:T("Downed pilot already exists!")
|
||||
_foundPilot.group:Destroy(false)
|
||||
self:_RemoveNameFromDownedPilots(_foundPilot.name)
|
||||
self:_CheckDownedPilotTable()
|
||||
end
|
||||
end
|
||||
|
||||
-- limit no of pilots in the field.
|
||||
if self.limitmaxdownedpilots and self:_ReachedPilotLimit() then
|
||||
self:T("Maxed Downed Pilot!")
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
-- TODO: Over water check --- EVENTS.LandingAfterEjection NOT triggered by DCS, so handle csarUsePara = true case
|
||||
-- might create dual pilots in edge cases
|
||||
|
||||
local wetfeet = false
|
||||
|
||||
--local surface = _unit:GetCoordinate():GetSurfaceType()
|
||||
local surface = initcoord:GetSurfaceType()
|
||||
@@ -2116,7 +2136,8 @@ end
|
||||
--- (Internal) Determine distance to closest MASH.
|
||||
-- @param #CSAR self
|
||||
-- @param Wrapper.Unit#UNIT _heli Helicopter #UNIT
|
||||
-- @return #CSAR self
|
||||
-- @return #number Distance in meters
|
||||
-- @return #string MASH Name as string
|
||||
function CSAR:_GetClosestMASH(_heli)
|
||||
self:T(self.lid .. " _GetClosestMASH")
|
||||
local _mashset = self.mash -- Core.Set#SET_GROUP
|
||||
@@ -2128,31 +2149,13 @@ function CSAR:_GetClosestMASH(_heli)
|
||||
local _shortestDistance = -1
|
||||
local _distance = 0
|
||||
local _helicoord = _heli:GetCoordinate()
|
||||
|
||||
local function GetCloseAirbase(coordinate,Coalition,Category)
|
||||
|
||||
local a=coordinate:GetVec3()
|
||||
local distmin=math.huge
|
||||
local airbase=nil
|
||||
for DCSairbaseID, DCSairbase in pairs(world.getAirbases(Coalition)) do
|
||||
local b=DCSairbase:getPoint()
|
||||
|
||||
local c=UTILS.VecSubstract(a,b)
|
||||
local dist=UTILS.VecNorm(c)
|
||||
|
||||
if dist<distmin and (Category==nil or Category==DCSairbase:getDesc().category) then
|
||||
distmin=dist
|
||||
airbase=DCSairbase
|
||||
end
|
||||
|
||||
end
|
||||
return distmin
|
||||
end
|
||||
local MashName = nil
|
||||
|
||||
if self.allowFARPRescue then
|
||||
local position = _heli:GetCoordinate()
|
||||
local afb,distance = position:GetClosestAirbase(nil,self.coalition)
|
||||
_shortestDistance = distance
|
||||
MashName = (afb ~= nil) and afb:GetName() or "Unknown"
|
||||
end
|
||||
|
||||
for _,_mashes in pairs(MashSets) do
|
||||
@@ -2166,12 +2169,13 @@ function CSAR:_GetClosestMASH(_heli)
|
||||
_distance = self:_GetDistance(_helicoord, _mashcoord)
|
||||
if _distance ~= nil and (_shortestDistance == -1 or _distance < _shortestDistance) then
|
||||
_shortestDistance = _distance
|
||||
MashName = _mashUnit:GetName() or "Unknown"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if _shortestDistance ~= -1 then
|
||||
return _shortestDistance
|
||||
return _shortestDistance, MashName
|
||||
else
|
||||
return -1
|
||||
end
|
||||
@@ -2417,11 +2421,26 @@ function CSAR:_ReachedPilotLimit()
|
||||
local limit = self.maxdownedpilots
|
||||
local islimited = self.limitmaxdownedpilots
|
||||
local count = self:_CountActiveDownedPilots()
|
||||
if islimited and (count >= limit) then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
if islimited and (count >= limit) then
|
||||
if self.useFIFOLimitReplacement then
|
||||
local oldIndex = -1
|
||||
local oldDownedPilot = nil
|
||||
for _index, _downedpilot in pairs(self.downedPilots) do
|
||||
oldIndex = _index
|
||||
oldDownedPilot = _downedpilot
|
||||
break
|
||||
end
|
||||
if oldDownedPilot then
|
||||
oldDownedPilot.group:Destroy(false)
|
||||
oldDownedPilot.alive = false
|
||||
self:_CheckDownedPilotTable()
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--- User - Function to add onw SET_GROUP Set-up for pilot filtering and assignment.
|
||||
|
||||
@@ -3486,7 +3486,7 @@ end
|
||||
-- @param #PLAYERTASKCONTROLLER self
|
||||
-- @param Ops.PlayerTask#PLAYERTASK PlayerTask
|
||||
-- @param #boolean Silent If true, make no "has new task" announcement
|
||||
-- @param #boolen TaskFilter If true, apply the white/black-list task filters here, also
|
||||
-- @param #boolean TaskFilter If true, apply the white/black-list task filters here, also
|
||||
-- @return #PLAYERTASKCONTROLLER self
|
||||
-- @usage
|
||||
-- Example to create a PLAYERTASK of type CTLD and give Players 10 minutes to complete:
|
||||
|
||||
@@ -1432,7 +1432,7 @@ end
|
||||
-- @param #number Speed The speed [m/s] flying when holding the position.
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:TaskOrbitCircleAtVec2( Point, Altitude, Speed )
|
||||
self:F2( { self.ControllableName, Point, Altitude, Speed } )
|
||||
--self:F2( { self.ControllableName, Point, Altitude, Speed } )
|
||||
|
||||
local DCSTask = {
|
||||
id = 'Orbit',
|
||||
|
||||
@@ -912,15 +912,18 @@ function GROUP:GetVelocityVec3()
|
||||
|
||||
if DCSGroup and DCSGroup:isExist() then
|
||||
local GroupUnits = DCSGroup:getUnits()
|
||||
local GroupCount = #GroupUnits
|
||||
local GroupCount = 0
|
||||
|
||||
local VelocityVec3 = { x = 0, y = 0, z = 0 }
|
||||
|
||||
for _, DCSUnit in pairs( GroupUnits ) do
|
||||
local UnitVelocityVec3 = DCSUnit:getVelocity()
|
||||
VelocityVec3.x = VelocityVec3.x + UnitVelocityVec3.x
|
||||
VelocityVec3.y = VelocityVec3.y + UnitVelocityVec3.y
|
||||
VelocityVec3.z = VelocityVec3.z + UnitVelocityVec3.z
|
||||
if DCSUnit:isExist() and DCSUnit:isActive() then
|
||||
local UnitVelocityVec3 = DCSUnit:getVelocity()
|
||||
VelocityVec3.x = VelocityVec3.x + UnitVelocityVec3.x
|
||||
VelocityVec3.y = VelocityVec3.y + UnitVelocityVec3.y
|
||||
VelocityVec3.z = VelocityVec3.z + UnitVelocityVec3.z
|
||||
GroupCount = GroupCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
VelocityVec3.x = VelocityVec3.x / GroupCount
|
||||
@@ -1754,11 +1757,13 @@ function GROUP:GetMaxVelocity()
|
||||
|
||||
for Index, UnitData in pairs( DCSGroup:getUnits() ) do
|
||||
|
||||
local UnitVelocityVec3 = UnitData:getVelocity()
|
||||
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
|
||||
if UnitData:isExist() and UnitData:isActive() then
|
||||
local UnitVelocityVec3 = UnitData:getVelocity()
|
||||
local UnitVelocity = math.abs( UnitVelocityVec3.x ) + math.abs( UnitVelocityVec3.y ) + math.abs( UnitVelocityVec3.z )
|
||||
|
||||
if UnitVelocity > GroupVelocityMax then
|
||||
GroupVelocityMax = UnitVelocity
|
||||
if UnitVelocity > GroupVelocityMax then
|
||||
GroupVelocityMax = UnitVelocity
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user