mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
FOX v0.6.0
FOX v0.6.0 - Missile target constantly updated. - Increased safety distance to 200 m. - Added safety distance for BIG missiles > 50 kg TNT as 400 m. - More output to dcs.log file. SPAWN - enabled uncontrolled UTILS - LLDMS accurracy fix. AI_A2A_DISPATCHER - Squadron visible improvements ZONE - Added MarkZone function for F10 zone markings. AI_PATROL_ZONE - Some WP code improvements.
This commit is contained in:
@@ -386,7 +386,7 @@ function AI_A2A_CAP:onafterEngage( AICap, From, Event, To, AttackSetUnit )
|
||||
|
||||
if FirstAttackUnit and FirstAttackUnit:IsAlive() then -- If there is no attacker anymore, stop the engagement.
|
||||
|
||||
if AICap:IsAlive() then
|
||||
if AICap and AICap:IsAlive() then
|
||||
|
||||
local EngageRoute = {}
|
||||
|
||||
@@ -417,6 +417,8 @@ function AI_A2A_CAP:onafterEngage( AICap, From, Event, To, AttackSetUnit )
|
||||
local AttackUnit = AttackUnit -- Wrapper.Unit#UNIT
|
||||
self:T( { "Attacking Unit:", AttackUnit:GetName(), AttackUnit:IsAlive(), AttackUnit:IsAir() } )
|
||||
if AttackUnit:IsAlive() and AttackUnit:IsAir() then
|
||||
-- TODO: Add coalition check? Only attack units of if AttackUnit:GetCoalition()~=AICap:GetCoalition()
|
||||
-- Maybe the detected set also contains
|
||||
AttackTasks[#AttackTasks+1] = AICap:TaskAttackUnit( AttackUnit )
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1092,8 +1092,9 @@ do -- AI_A2A_DISPATCHER
|
||||
self:GetParent( self, AI_A2A_DISPATCHER ).onafterStart( self, From, Event, To )
|
||||
|
||||
-- Spawn the resources.
|
||||
for SquadronName, DefenderSquadron in pairs( self.DefenderSquadrons ) do
|
||||
DefenderSquadron.Resource = {}
|
||||
for SquadronName,_DefenderSquadron in pairs( self.DefenderSquadrons ) do
|
||||
local DefenderSquadron=_DefenderSquadron --#AI_A2A_DISPATCHER.Squadron
|
||||
DefenderSquadron.Resources = {}
|
||||
if DefenderSquadron.ResourceCount then
|
||||
for Resource = 1, DefenderSquadron.ResourceCount do
|
||||
self:ParkDefender( DefenderSquadron )
|
||||
@@ -1107,18 +1108,39 @@ do -- AI_A2A_DISPATCHER
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param #AI_A2A_DISPATCHER.Squadron DefenderSquadron The squadron.
|
||||
function AI_A2A_DISPATCHER:ParkDefender( DefenderSquadron )
|
||||
|
||||
local TemplateID = math.random( 1, #DefenderSquadron.Spawn )
|
||||
|
||||
local Spawn = DefenderSquadron.Spawn[ TemplateID ] -- Core.Spawn#SPAWN
|
||||
|
||||
Spawn:InitGrouping( 1 )
|
||||
|
||||
local SpawnGroup
|
||||
|
||||
if self:IsSquadronVisible( DefenderSquadron.Name ) then
|
||||
|
||||
local Grouping=DefenderSquadron.Grouping or self.DefenderDefault.Grouping
|
||||
|
||||
Grouping=1
|
||||
|
||||
Spawn:InitGrouping(Grouping)
|
||||
|
||||
SpawnGroup = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase, SPAWN.Takeoff.Cold )
|
||||
|
||||
local GroupName = SpawnGroup:GetName()
|
||||
|
||||
DefenderSquadron.Resources = DefenderSquadron.Resources or {}
|
||||
|
||||
DefenderSquadron.Resources[TemplateID] = DefenderSquadron.Resources[TemplateID] or {}
|
||||
DefenderSquadron.Resources[TemplateID][GroupName] = {}
|
||||
DefenderSquadron.Resources[TemplateID][GroupName] = SpawnGroup
|
||||
|
||||
self.uncontrolled=self.uncontrolled or {}
|
||||
self.uncontrolled[DefenderSquadron.Name]=self.uncontrolled[DefenderSquadron.Name] or {}
|
||||
|
||||
table.insert(self.uncontrolled[DefenderSquadron.Name], {group=SpawnGroup, name=GroupName, grouping=Grouping})
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -1701,10 +1723,23 @@ do -- AI_A2A_DISPATCHER
|
||||
local DefenderSquadron = self:GetSquadron( SquadronName ) --#AI_A2A_DISPATCHER.Squadron
|
||||
|
||||
DefenderSquadron.Uncontrolled = true
|
||||
|
||||
-- For now, grouping is forced to 1 due to other parts of the class which would not work well with grouping>1.
|
||||
DefenderSquadron.Grouping=1
|
||||
|
||||
-- Get free parking for fighter aircraft.
|
||||
local nfreeparking=DefenderSquadron.Airbase:GetFreeParkingSpotsNumber(AIRBASE.TerminalType.FighterAircraft, true)
|
||||
|
||||
-- Take number of free parking spots if no resource count was specifed.
|
||||
DefenderSquadron.ResourceCount=DefenderSquadron.ResourceCount or nfreeparking
|
||||
|
||||
-- Check that resource count is not larger than free parking spots.
|
||||
DefenderSquadron.ResourceCount=math.min(DefenderSquadron.ResourceCount, nfreeparking)
|
||||
|
||||
-- Set uncontrolled spawning option.
|
||||
for SpawnTemplate,_DefenderSpawn in pairs( self.DefenderSpawns ) do
|
||||
local DefenderSpawn=_DefenderSpawn --Core.Spawn#SPAWN
|
||||
DefenderSpawn:InitUnControlled()
|
||||
DefenderSpawn:InitUnControlled(true)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -2751,7 +2786,7 @@ do -- AI_A2A_DISPATCHER
|
||||
--- Get squadron from defender.
|
||||
-- @param #AI_A2A_DISPATCHER self
|
||||
-- @param Wrapper.Group#GROUP Defender The defender group.
|
||||
-- @return ?
|
||||
-- @return #AI_A2A_DISPATCHER.Squadron Squadron The squadron.
|
||||
function AI_A2A_DISPATCHER:GetSquadronFromDefender( Defender )
|
||||
self.Defenders = self.Defenders or {}
|
||||
local DefenderName = Defender:GetName()
|
||||
@@ -2800,8 +2835,9 @@ do -- AI_A2A_DISPATCHER
|
||||
if AIGroup and AIGroup:IsAlive() then
|
||||
-- Check if the CAP is patrolling or engaging. If not, this is not a valid CAP, even if it is alive!
|
||||
-- The CAP could be damaged, lost control, or out of fuel!
|
||||
if DefenderTask.Fsm:Is( "Patrolling" ) or DefenderTask.Fsm:Is( "Engaging" ) or DefenderTask.Fsm:Is( "Refuelling" )
|
||||
or DefenderTask.Fsm:Is( "Started" ) then
|
||||
--env.info("FF fsm state "..tostring(DefenderTask.Fsm:GetState()))
|
||||
if DefenderTask.Fsm:Is( "Patrolling" ) or DefenderTask.Fsm:Is( "Engaging" ) or DefenderTask.Fsm:Is( "Refuelling" ) or DefenderTask.Fsm:Is( "Started" ) then
|
||||
--env.info("FF capcount "..CapCount)
|
||||
CapCount = CapCount + 1
|
||||
end
|
||||
end
|
||||
@@ -2908,16 +2944,48 @@ do -- AI_A2A_DISPATCHER
|
||||
function AI_A2A_DISPATCHER:ResourceActivate( DefenderSquadron, DefendersNeeded )
|
||||
|
||||
local SquadronName = DefenderSquadron.Name
|
||||
|
||||
DefendersNeeded = DefendersNeeded or 4
|
||||
|
||||
local DefenderGrouping = DefenderSquadron.Grouping or self.DefenderDefault.Grouping
|
||||
|
||||
DefenderGrouping = ( DefenderGrouping < DefendersNeeded ) and DefenderGrouping or DefendersNeeded
|
||||
|
||||
if self:IsSquadronVisible( SquadronName ) then
|
||||
--env.info(string.format("FF resource activate: Squadron=%s grouping=%d needed=%d visible=%s", SquadronName, DefenderGrouping, DefendersNeeded, tostring(self:IsSquadronVisible( SquadronName ))))
|
||||
|
||||
if self:IsSquadronVisible( SquadronName ) then
|
||||
|
||||
local n=#self.uncontrolled[SquadronName]
|
||||
|
||||
if n>0 then
|
||||
-- Random number 1,...n
|
||||
local id=math.random(n)
|
||||
|
||||
-- Pick a random defender group.
|
||||
local Defender=self.uncontrolled[SquadronName][id].group --Wrapper.Group#GROUP
|
||||
|
||||
-- Start uncontrolled group.
|
||||
Defender:StartUncontrolled()
|
||||
|
||||
-- Get grouping.
|
||||
DefenderGrouping=self.uncontrolled[SquadronName][id].grouping
|
||||
|
||||
-- Add defender to squadron.
|
||||
self:AddDefenderToSquadron( DefenderSquadron, Defender, DefenderGrouping )
|
||||
|
||||
-- Remove defender from uncontrolled table.
|
||||
table.remove(self.uncontrolled[SquadronName], id)
|
||||
|
||||
return Defender, DefenderGrouping
|
||||
else
|
||||
return nil,0
|
||||
end
|
||||
|
||||
-- Here we CAP the new planes.
|
||||
-- The Resources table is filled in advance.
|
||||
local TemplateID = math.random( 1, #DefenderSquadron.Spawn ) -- Choose the template.
|
||||
|
||||
|
||||
--[[
|
||||
-- We determine the grouping based on the parameters set.
|
||||
self:F( { DefenderGrouping = DefenderGrouping } )
|
||||
|
||||
@@ -2960,8 +3028,16 @@ do -- AI_A2A_DISPATCHER
|
||||
self:AddDefenderToSquadron( DefenderSquadron, Defender, DefenderGrouping )
|
||||
return Defender, DefenderGrouping
|
||||
end
|
||||
]]
|
||||
|
||||
else
|
||||
|
||||
----------------------------
|
||||
--- Squadron not visible ---
|
||||
----------------------------
|
||||
|
||||
local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ] -- Core.Spawn#SPAWN
|
||||
|
||||
if DefenderGrouping then
|
||||
Spawn:InitGrouping( DefenderGrouping )
|
||||
else
|
||||
@@ -2969,8 +3045,11 @@ do -- AI_A2A_DISPATCHER
|
||||
end
|
||||
|
||||
local TakeoffMethod = self:GetSquadronTakeoff( SquadronName )
|
||||
|
||||
local Defender = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase, TakeoffMethod, DefenderSquadron.TakeoffAltitude or self.DefenderDefault.TakeoffAltitude ) -- Wrapper.Group#GROUP
|
||||
|
||||
self:AddDefenderToSquadron( DefenderSquadron, Defender, DefenderGrouping )
|
||||
|
||||
return Defender, DefenderGrouping
|
||||
end
|
||||
|
||||
@@ -3261,6 +3340,7 @@ do -- AI_A2A_DISPATCHER
|
||||
Dispatcher:ParkDefender( Squadron )
|
||||
end
|
||||
end
|
||||
|
||||
end -- if DefenderGCI then
|
||||
end -- while ( DefendersNeeded > 0 ) do
|
||||
end
|
||||
|
||||
@@ -349,13 +349,16 @@ function AI_A2A_PATROL:onafterRoute( AIPatrol, From, Event, To )
|
||||
|
||||
local CurrentCoord = AIPatrol:GetCoordinate()
|
||||
|
||||
if self.racetrack then
|
||||
|
||||
-- Random altitude.
|
||||
local altitude=math.random(self.PatrolFloorAltitude, self.PatrolCeilingAltitude)
|
||||
-- Random altitude.
|
||||
local altitude=math.random(self.PatrolFloorAltitude, self.PatrolCeilingAltitude)
|
||||
|
||||
-- Random speed in km/h.
|
||||
local speedkmh = math.random(self.PatrolMinSpeed, self.PatrolMaxSpeed)
|
||||
-- Random speed in km/h.
|
||||
local speedkmh = math.random(self.PatrolMinSpeed, self.PatrolMaxSpeed)
|
||||
|
||||
-- First waypoint is current position.
|
||||
PatrolRoute[1]=CurrentCoord:WaypointAirTurningPoint(nil, speedkmh, {}, "Current")
|
||||
|
||||
if self.racetrack then
|
||||
|
||||
-- Random heading.
|
||||
local heading = math.random(self.racetrackheadingmin, self.racetrackheadingmax)
|
||||
@@ -379,6 +382,8 @@ function AI_A2A_PATROL:onafterRoute( AIPatrol, From, Event, To )
|
||||
local c1=c0:SetAltitude(altitude) --Core.Point#COORDINATE
|
||||
local c2=c1:Translate(leg, heading):SetAltitude(altitude)
|
||||
|
||||
self:SetTargetDistance(c0) -- For RTB status check
|
||||
|
||||
-- Debug:
|
||||
self:T(string.format("Patrol zone race track: v=%.1f knots, h=%.1f ft, heading=%03d, leg=%d m, t=%s sec", UTILS.KmphToKnots(speedkmh), UTILS.MetersToFeet(altitude), heading, leg, tostring(duration)))
|
||||
--c1:MarkToAll("Race track c1")
|
||||
@@ -390,37 +395,25 @@ function AI_A2A_PATROL:onafterRoute( AIPatrol, From, Event, To )
|
||||
-- Task function to redo the patrol at other random position.
|
||||
local taskPatrol=AIPatrol:TaskFunction("AI_A2A_PATROL.PatrolRoute", self)
|
||||
|
||||
|
||||
-- Controlled task with task condition.
|
||||
local taskCond=AIPatrol:TaskCondition(nil, nil, nil, nil, duration, nil)
|
||||
local taskCont=AIPatrol:TaskControlled(taskOrbit, taskCond)
|
||||
|
||||
PatrolRoute[1]=CurrentCoord:WaypointAirTurningPoint(nil, speedkmh, {}, "Current")
|
||||
PatrolRoute[2]=c1:WaypointAirTurningPoint(self.PatrolAltType, speedkmh, {taskCont, taskPatrol}, "Orbit")
|
||||
-- Second waypoint
|
||||
PatrolRoute[2]=c1:WaypointAirTurningPoint(self.PatrolAltType, speedkmh, {taskCont, taskPatrol}, "CAP Orbit")
|
||||
|
||||
else
|
||||
|
||||
local ToTargetCoord = self.PatrolZone:GetRandomPointVec2()
|
||||
ToTargetCoord:SetAlt( math.random( self.PatrolFloorAltitude, self.PatrolCeilingAltitude ) )
|
||||
|
||||
-- Target coordinate.
|
||||
local ToTargetCoord=self.PatrolZone:GetRandomCoordinate() --Core.Point#COORDINATE
|
||||
ToTargetCoord:SetAltitude(altitude)
|
||||
|
||||
self:SetTargetDistance( ToTargetCoord ) -- For RTB status check
|
||||
|
||||
local ToTargetSpeed = math.random( self.PatrolMinSpeed, self.PatrolMaxSpeed )
|
||||
|
||||
--- Create a route point of type air.
|
||||
local ToPatrolRoutePoint = ToTargetCoord:WaypointAir(
|
||||
self.PatrolAltType,
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
ToTargetSpeed,
|
||||
true
|
||||
)
|
||||
|
||||
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||
PatrolRoute[#PatrolRoute+1] = ToPatrolRoutePoint
|
||||
|
||||
local Tasks = {}
|
||||
Tasks[#Tasks+1] = AIPatrol:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self )
|
||||
PatrolRoute[#PatrolRoute].task = AIPatrol:TaskCombo( Tasks )
|
||||
local taskReRoute=AIPatrol:TaskFunction( "AI_A2A_PATROL.PatrolRoute", self )
|
||||
|
||||
PatrolRoute[2]=ToTargetCoord:WaypointAirTurningPoint(self.PatrolAltType, speedkmh, {taskReRoute}, "Patrol Point")
|
||||
|
||||
end
|
||||
|
||||
-- ROE
|
||||
|
||||
Reference in New Issue
Block a user