mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
OPS
** ARMYGROUP** - Added suppression option **COMMANDER** - Added function to add targets with defined resources **OPSGROUP** - Added option to pause multiple missions **INTEL** - Fixed bug in cluster calc **LEGION** - Added function to get alive opsgroups **TARGET** * Added start condition
This commit is contained in:
@@ -34,6 +34,11 @@
|
||||
-- @field #boolean isMobile If true, group is mobile.
|
||||
-- @field #ARMYGROUP.Target engage Engage target.
|
||||
-- @field Core.Set#SET_ZONE retreatZones Set of retreat zones.
|
||||
-- @field #boolean suppressOn Bla
|
||||
-- @field #boolean isSuppressed Bla
|
||||
-- @field #number TsuppressMin Bla
|
||||
-- @field #number TsuppressMax Bla
|
||||
-- @field #number TsuppressAve Bla
|
||||
-- @extends Ops.OpsGroup#OPSGROUP
|
||||
|
||||
--- *Your soul may belong to Jesus, but your ass belongs to the marines.* -- Eugene B Sledge
|
||||
@@ -122,6 +127,9 @@ function ARMYGROUP:New(group)
|
||||
self:AddTransition("*", "Retreat", "Retreating") -- Order a retreat.
|
||||
self:AddTransition("Retreating", "Retreated", "Retreated") -- Group retreated.
|
||||
|
||||
self:AddTransition("*", "Suppressed", "*") -- Group is suppressed
|
||||
self:AddTransition("*", "Unsuppressed", "*") -- Group is unsuppressed.
|
||||
|
||||
self:AddTransition("Cruising", "EngageTarget", "Engaging") -- Engage a target from Cruising state
|
||||
self:AddTransition("Holding", "EngageTarget", "Engaging") -- Engage a target from Holding state
|
||||
self:AddTransition("OnDetour", "EngageTarget", "Engaging") -- Engage a target from OnDetour state
|
||||
@@ -280,6 +288,7 @@ function ARMYGROUP:New(group)
|
||||
-- @function [parent=#ARMYGROUP] EngageTarget
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param Wrapper.Group#GROUP Group the group to be engaged.
|
||||
-- @param #number Speed Speed in knots.
|
||||
-- @param #string Formation Formation used in the engagement.
|
||||
|
||||
--- Triggers the FSM event "EngageTarget" after a delay.
|
||||
@@ -287,6 +296,7 @@ function ARMYGROUP:New(group)
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #number delay Delay in seconds.
|
||||
-- @param Wrapper.Group#GROUP Group the group to be engaged.
|
||||
-- @param #number Speed Speed in knots.
|
||||
-- @param #string Formation Formation used in the engagement.
|
||||
|
||||
|
||||
@@ -297,6 +307,7 @@ function ARMYGROUP:New(group)
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Group#GROUP Group the group to be engaged.
|
||||
-- @param #number Speed Speed in knots.
|
||||
-- @param #string Formation Formation used in the engagement.
|
||||
|
||||
|
||||
@@ -386,7 +397,7 @@ function ARMYGROUP:New(group)
|
||||
self:HandleEvent(EVENTS.Birth, self.OnEventBirth)
|
||||
self:HandleEvent(EVENTS.Dead, self.OnEventDead)
|
||||
self:HandleEvent(EVENTS.RemoveUnit, self.OnEventRemoveUnit)
|
||||
--self:HandleEvent(EVENTS.Hit, self.OnEventHit)
|
||||
self:HandleEvent(EVENTS.Hit, self.OnEventHit)
|
||||
|
||||
-- Start the status monitoring.
|
||||
self.timerStatus=TIMER:New(self.Status, self):Start(1, 30)
|
||||
@@ -572,6 +583,47 @@ function ARMYGROUP:AddRetreatZone(RetreatZone)
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set suppression on. average, minimum and maximum time a unit is suppressed each time it gets hit.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #number Tave Average time [seconds] a group will be suppressed. Default is 15 seconds.
|
||||
-- @param #number Tmin (Optional) Minimum time [seconds] a group will be suppressed. Default is 5 seconds.
|
||||
-- @param #number Tmax (Optional) Maximum time a group will be suppressed. Default is 25 seconds.
|
||||
-- @return #ARMYGROUP self
|
||||
function ARMYGROUP:SetSuppressionOn(Tave, Tmin, Tmax)
|
||||
|
||||
-- Activate suppression.
|
||||
self.suppressionOn=true
|
||||
|
||||
-- Minimum suppression time is input or default 5 sec (but at least 1 second).
|
||||
self.TsuppressMin=Tmin or 1
|
||||
self.TsuppressMin=math.max(self.TsuppressMin, 1)
|
||||
|
||||
-- Maximum suppression time is input or default but at least Tmin.
|
||||
self.TsuppressMax=Tmax or 15
|
||||
self.TsuppressMax=math.max(self.TsuppressMax, self.TsuppressMin)
|
||||
|
||||
-- Expected suppression time is input or default but at leat Tmin and at most Tmax.
|
||||
self.TsuppressAve=Tave or 10
|
||||
self.TsuppressAve=math.max(self.TsuppressMin)
|
||||
self.TsuppressAve=math.min(self.TsuppressMax)
|
||||
|
||||
-- Debug Info
|
||||
self:T(self.lid..string.format("Set ave suppression time to %d seconds.", self.TsuppressAve))
|
||||
self:T(self.lid..string.format("Set min suppression time to %d seconds.", self.TsuppressMin))
|
||||
self:T(self.lid..string.format("Set max suppression time to %d seconds.", self.TsuppressMax))
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- Set suppression off.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @return #ARMYGROUP self
|
||||
function ARMYGROUP:SetSuppressionOff()
|
||||
-- Activate suppression.
|
||||
self.suppressionOn=false
|
||||
end
|
||||
|
||||
|
||||
--- Check if the group is currently holding its positon.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @return #boolean If true, group was ordered to hold.
|
||||
@@ -651,10 +703,14 @@ function ARMYGROUP:Status()
|
||||
-- Check if group is waiting.
|
||||
if self:IsWaiting() then
|
||||
if self.Twaiting and self.dTwait then
|
||||
if timer.getAbsTime()>self.Twaiting+self.dTwait then
|
||||
if timer.getAbsTime()>self.Twaiting+self.dTwait then
|
||||
self.Twaiting=nil
|
||||
self.dTwait=nil
|
||||
self:Cruise()
|
||||
if self:_CountPausedMissions()>0 then
|
||||
self:UnpauseMission()
|
||||
else
|
||||
self:Cruise()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -799,22 +855,6 @@ end
|
||||
-- DCS Events ==> See OPSGROUP
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
--- Event function handling when a unit is hit.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param Core.Event#EVENTDATA EventData Event data.
|
||||
function ARMYGROUP:OnEventHit(EventData)
|
||||
|
||||
-- Check that this is the right group.
|
||||
if EventData and EventData.IniGroup and EventData.IniUnit and EventData.IniGroupName and EventData.IniGroupName==self.groupname then
|
||||
local unit=EventData.IniUnit
|
||||
local group=EventData.IniGroup
|
||||
local unitname=EventData.IniUnitName
|
||||
|
||||
-- TODO: suppression
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- FSM Events
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -1126,7 +1166,7 @@ function ARMYGROUP:onafterUpdateRoute(From, Event, To, n, N, Speed, Formation)
|
||||
self.speedWp=wp.speed
|
||||
|
||||
-- Debug output.
|
||||
if self.verbose>=10 or true then
|
||||
if self.verbose>=10 then
|
||||
for i,_wp in pairs(waypoints) do
|
||||
local wp=_wp --Ops.OpsGroup#OPSGROUP.Waypoint
|
||||
|
||||
@@ -1228,6 +1268,16 @@ end
|
||||
function ARMYGROUP:onafterOutOfAmmo(From, Event, To)
|
||||
self:T(self.lid..string.format("Group is out of ammo at t=%.3f", timer.getTime()))
|
||||
|
||||
-- Get current task.
|
||||
local task=self:GetTaskCurrent()
|
||||
|
||||
if task then
|
||||
if task.dcstask.id=="FireAtPoint" or task.dcstask.id==AUFTRAG.SpecialTask.BARRAGE then
|
||||
self:T(self.lid..string.format("Cancelling current %s task because out of ammo!", task.dcstask.id))
|
||||
self:TaskCancel(task)
|
||||
end
|
||||
end
|
||||
|
||||
-- Fist, check if we want to rearm once out-of-ammo.
|
||||
--TODO: IsMobile() check
|
||||
if self.rearmOnOutOfAmmo then
|
||||
@@ -1250,16 +1300,6 @@ function ARMYGROUP:onafterOutOfAmmo(From, Event, To)
|
||||
if self.rtzOnOutOfAmmo then
|
||||
self:__RTZ(-1)
|
||||
end
|
||||
|
||||
-- Get current task.
|
||||
local task=self:GetTaskCurrent()
|
||||
|
||||
if task then
|
||||
if task.dcstask.id=="FireAtPoint" or task.dcstask.id==AUFTRAG.SpecialTask.BARRAGE then
|
||||
self:T(self.lid..string.format("Cancelling current %s task because out of ammo!", task.dcstask.id))
|
||||
self:TaskCancel(task)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1292,6 +1332,15 @@ function ARMYGROUP:onbeforeRearm(From, Event, To, Coordinate, Formation)
|
||||
allowed=false
|
||||
end
|
||||
|
||||
-- Check if coordinate is provided.
|
||||
if allowed and not Coordinate then
|
||||
local truck=self:FindNearestAmmoSupply()
|
||||
if truck and truck:IsAlive() then
|
||||
self:__Rearm(-0.1, truck:GetCoordinate(), Formation)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Try again...
|
||||
if dt then
|
||||
self:T(self.lid..string.format("Trying Rearm again in %.2f sec", dt))
|
||||
@@ -1589,7 +1638,7 @@ function ARMYGROUP:onafterEngageTarget(From, Event, To, Target, Speed, Formation
|
||||
self.engage.Coordinate=UTILS.DeepCopy(self.engage.Target:GetCoordinate())
|
||||
|
||||
-- Get a coordinate close to the target.
|
||||
local intercoord=self:GetCoordinate():GetIntermediateCoordinate(self.engage.Coordinate, 0.9)
|
||||
local intercoord=self:GetCoordinate():GetIntermediateCoordinate(self.engage.Coordinate, 0.95)
|
||||
|
||||
-- Backup ROE and alarm state.
|
||||
self.engage.roe=self:GetROE()
|
||||
@@ -1752,6 +1801,21 @@ function ARMYGROUP:onafterCruise(From, Event, To, Speed, Formation)
|
||||
|
||||
end
|
||||
|
||||
--- On after "Hit" event.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @param Wrapper.Unit#UNIT Enemy Unit that hit the element or `nil`.
|
||||
function ARMYGROUP:onafterHit(From, Event, To, Enemy)
|
||||
self:T(self.lid..string.format("ArmyGroup hit by %s", Enemy and Enemy:GetName() or "unknown"))
|
||||
|
||||
if self.suppressionOn then
|
||||
env.info(self.lid.."FF suppress")
|
||||
self:_Suppress()
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- Routing
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -1996,6 +2060,100 @@ function ARMYGROUP:FindNearestAmmoSupply(Radius)
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
--- Suppress fire of the group by setting its ROE to weapon hold.
|
||||
-- @param #ARMYGROUP self
|
||||
function ARMYGROUP:_Suppress()
|
||||
|
||||
-- Current time.
|
||||
local Tnow=timer.getTime()
|
||||
|
||||
-- Current ROE
|
||||
local currROE=self:GetROE()
|
||||
|
||||
|
||||
-- Get randomized time the unit is suppressed.
|
||||
local sigma=(self.TsuppressMax-self.TsuppressMin)/4
|
||||
|
||||
-- Gaussian distribution.
|
||||
local Tsuppress=UTILS.RandomGaussian(self.TsuppressAve,sigma,self.TsuppressMin, self.TsuppressMax)
|
||||
|
||||
-- Time at which the suppression is over.
|
||||
local renew=true
|
||||
if not self.TsuppressionOver then
|
||||
|
||||
-- Group is not suppressed currently.
|
||||
self.TsuppressionOver=Tnow+Tsuppress
|
||||
|
||||
-- Group will hold their weapons.
|
||||
self:SwitchROE(ENUMS.ROE.WeaponHold)
|
||||
|
||||
-- Backup ROE.
|
||||
self.suppressionROE=currROE
|
||||
|
||||
else
|
||||
-- Check if suppression is longer than current time.
|
||||
if Tsuppress+Tnow > self.TsuppressionOver then
|
||||
self.TsuppressionOver=Tnow+Tsuppress
|
||||
else
|
||||
renew=false
|
||||
end
|
||||
end
|
||||
|
||||
-- Recovery event will be called in Tsuppress seconds.
|
||||
if renew then
|
||||
self:__Unsuppressed(self.TsuppressionOver-Tnow)
|
||||
end
|
||||
|
||||
-- Debug message.
|
||||
self:T(self.lid..string.format("Suppressed for %d sec", Tsuppress))
|
||||
|
||||
end
|
||||
|
||||
--- Before "Recovered" event. Check if suppression time is over.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
-- @return #boolean
|
||||
function ARMYGROUP:onbeforeUnsuppressed(From, Event, To)
|
||||
|
||||
-- Current time.
|
||||
local Tnow=timer.getTime()
|
||||
|
||||
-- Debug info
|
||||
self:T(self.lid..string.format("onbeforeRecovered: Time now: %d - Time over: %d", Tnow, self.TsuppressionOver))
|
||||
|
||||
-- Recovery is only possible if enough time since the last hit has passed.
|
||||
if Tnow >= self.TsuppressionOver then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- After "Recovered" event. Group has recovered and its ROE is set back to the "normal" unsuppressed state. Optionally the group is flared green.
|
||||
-- @param #ARMYGROUP self
|
||||
-- @param #string From From state.
|
||||
-- @param #string Event Event.
|
||||
-- @param #string To To state.
|
||||
function ARMYGROUP:onafterUnsuppressed(From, Event, To)
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("Group %s has recovered!", self:GetName())
|
||||
MESSAGE:New(text, 10):ToAll()
|
||||
self:T(self.lid..text)
|
||||
|
||||
-- Set ROE back to default.
|
||||
self:SwitchROE(self.suppressionROE)
|
||||
|
||||
-- Flare unit green.
|
||||
if true then
|
||||
self.group:FlareGreen()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user