From 4661f6981ef68d40b0be8951207b7fc884745bc4 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 6 Jan 2020 21:09:21 +0100 Subject: [PATCH] Misc --- Moose Development/Moose/Core/Set.lua | 14 ---- Moose Development/Moose/Core/Zone.lua | 2 +- .../Moose/Functional/Suppression.lua | 76 ++++++++++++------- .../Moose/Functional/ZoneCaptureCoalition.lua | 14 ++-- Moose Development/Moose/Ops/ATIS.lua | 10 ++- Moose Development/Moose/Utilities/Utils.lua | 20 +++++ 6 files changed, 85 insertions(+), 51 deletions(-) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index dedec77c9..58cb5c386 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -2186,20 +2186,6 @@ do -- SET_UNIT return IsNotInZone end - - --- Check if minimal one element of the SET_UNIT is in the Zone. - -- @param #SET_UNIT self - -- @param #function IteratorFunction The function that will be called when there is an alive UNIT in the SET_UNIT. The function needs to accept a UNIT parameter. - -- @return #SET_UNIT self - function SET_UNIT:ForEachUnitInZone( IteratorFunction, ... ) - self:F2( arg ) - - self:ForEach( IteratorFunction, arg, self:GetSet() ) - - return self - end - - end diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index a1db93d70..802656890 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -949,7 +949,7 @@ function ZONE_RADIUS:SearchZone( EvaluateFunction, ObjectCategories ) local function EvaluateZone( ZoneDCSUnit ) - env.info( ZoneDCSUnit:getName() ) + --env.info( ZoneDCSUnit:getName() ) local ZoneUnit = UNIT:Find( ZoneDCSUnit ) diff --git a/Moose Development/Moose/Functional/Suppression.lua b/Moose Development/Moose/Functional/Suppression.lua index c66cc1906..1698f0c0a 100644 --- a/Moose Development/Moose/Functional/Suppression.lua +++ b/Moose Development/Moose/Functional/Suppression.lua @@ -83,6 +83,8 @@ -- @field #string DefaultAlarmState Alarm state the group will go to when it is changed back from another state. Default is "Auto". -- @field #string DefaultROE ROE the group will get once suppression is over. Default is "Free". -- @field #boolean eventmoose If true, events are handled by MOOSE. If false, events are handled directly by DCS eventhandler. Default true. +-- @field Core.Zone#ZONE BattleZone +-- @field #boolean AutoEngage -- @extends Core.Fsm#FSM_CONTROLLABLE -- @@ -307,8 +309,7 @@ SUPPRESSION.version="0.9.3" --- Creates a new AI_suppression object. -- @param #SUPPRESSION self -- @param Wrapper.Group#GROUP group The GROUP object for which suppression should be applied. --- @return #SUPPRESSION SUPPRESSION object. --- @return nil If group does not exist or is not a ground group. +-- @return #SUPPRESSION SUPPRESSION object or *nil* if group does not exist or is not a ground group. function SUPPRESSION:New(group) -- Inherits from FSM_CONTROLLABLE @@ -333,18 +334,16 @@ function SUPPRESSION:New(group) self:SetControllable(group) -- Get DCS descriptors of group. - local DCSgroup=Group.getByName(group:GetName()) - local DCSunit=DCSgroup:getUnit(1) - self.DCSdesc=DCSunit:getDesc() + self.DCSdesc=group:GetDCSDesc(1) -- Get max speed the group can do and convert to km/h. - self.SpeedMax=self.DCSdesc.speedMaxOffRoad*3.6 + self.SpeedMax=group:GetSpeedMax() -- Set speed to maximum. self.Speed=self.SpeedMax -- Is this infantry or not. - self.IsInfantry=DCSunit:hasAttribute("Infantry") + self.IsInfantry=group:GetUnit(1):HasAttribute("Infantry") -- Type of group. self.Type=group:GetTypeName() @@ -368,6 +367,7 @@ function SUPPRESSION:New(group) self:AddTransition("TakingCover", "FightBack", "CombatReady") self:AddTransition("FallingBack", "FightBack", "CombatReady") self:AddTransition("Retreating", "Retreated", "Retreated") + self:AddTransition("*", "OutOfAmmo", "*") self:AddTransition("*", "Dead", "*") self:AddTransition("*", "Stop", "Stopped") @@ -598,6 +598,24 @@ function SUPPRESSION:New(group) -- @param #string To To state. + --- Trigger "OutOfAmmo" event. + -- @function [parent=#SUPPRESSION] OutOfAmmo + -- @param #SUPPRESSION self + + --- Trigger "OutOfAmmo" event after a delay. + -- @function [parent=#SUPPRESSION] __OutOfAmmo + -- @param #SUPPRESSION self + -- @param #number Delay Delay in seconds. + + --- User function for OnAfter "OutOfAmmo" event. + -- @function [parent=#SUPPRESSION] OnAfterOutOfAmmo + -- @param #SUPPRESSION self + -- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group. + -- @param #string From From state. + -- @param #string Event Event. + -- @param #string To To state. + + --- Trigger "Dead" event. -- @function [parent=#SUPPRESSION] Dead -- @param #SUPPRESSION self @@ -1002,9 +1020,8 @@ function SUPPRESSION:onafterStatus(Controllable, From, Event, To) -- Retreat if completely out of ammo and retreat zone defined. local nammo=group:GetAmmunition() - if nammo==0 and self.RetreatZone then - self:I(self.lid..string.format("Out of ammo!")) - self:Retreat() + if nammo==0 then + self:OutOfAmmo() end -- Status report. @@ -1016,34 +1033,18 @@ function SUPPRESSION:onafterStatus(Controllable, From, Event, To) end else + -- Stop FSM as there are no units left. self:Stop() end else + -- Stop FSM as there group object does not exist. self:Stop() end end ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---- Before "Hit" event. (Of course, this is not really before the group got hit.) --- @param #SUPPRESSION self --- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group. --- @param #string From From state. --- @param #string Event Event. --- @param #string To To state. --- @param Wrapper.Unit#UNIT Unit Unit that was hit. --- @param Wrapper.Unit#UNIT AttackUnit Unit that attacked. --- @return boolean -function SUPPRESSION:onbeforeHit(Controllable, From, Event, To, Unit, AttackUnit) - self:_EventFromTo("onbeforeHit", Event, From, To) - - --local Tnow=timer.getTime() - --env.info(self.lid..string.format("Last hit = %s %s", tostring(self.LastHit), tostring(Tnow))) - - return true -end - --- After "Hit" event. -- @param #SUPPRESSION self -- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group. @@ -1314,6 +1315,25 @@ function SUPPRESSION:onafterTakeCover(Controllable, From, Event, To, Hideout) end +--- After "OutOfAmmo" event. Triggered when group is completely out of ammo. +-- @param #SUPPRESSION self +-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group. +-- @param #string From From state. +-- @param #string Event Event. +-- @param #string To To state. +function SUPPRESSION:onafterOutOfAmmo(Controllable, From, Event, To) + self:_EventFromTo("onafterOutOfAmmo", Event, From, To) + + -- Info to log. + self:I(self.lid..string.format("Out of ammo!")) + + -- Order retreat if retreat zone was specified. + if self.RetreatZone then + self:Retreat() + end + +end + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Before "Retreat" event. We check that the group is not already retreating. diff --git a/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua b/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua index 1e9417e96..4b0801681 100644 --- a/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua +++ b/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua @@ -874,14 +874,16 @@ do -- ZONE_CAPTURE_COALITION self:Capture() end - if self:IsAttacked() then - local unitset=self:GetScannedSetUnit() --Core.Set#SET_UNIT - - unitset:ForEachUnitInZone(self) - end + -- Get red and blue unit sets. + local unitsetRed=self:GetScannedSetUnit():FilterCoalitions(coalition.side.RED):FilterActive(true):FilterOnce() + local unitsetBlu=self:GetScannedSetUnit():FilterCoalitions(coalition.side.BLUE):FilterActive(true):FilterOnce() + + -- Count number of units. + local nRed=unitsetRed:Count() + local nBlu=unitsetBlu:Count() -- Status text. - local text=string.format("CAPTURE ZONE %s: Owner=%s (Previous=%s): Status %s", self:GetZoneName(), self:GetCoalitionName(), UTILS.GetCoalitionName(self:GetPreviousCoalition()), State) + local text=string.format("CAPTURE ZONE %s: Owner=%s (Previous=%s): #blue=%d, #red=%d, Status %s", self:GetZoneName(), self:GetCoalitionName(), UTILS.GetCoalitionName(self:GetPreviousCoalition()), nBlu, nRed, State) local NewState = self:GetState() if NewState~=State then text=text..string.format(" --> %s", NewState) diff --git a/Moose Development/Moose/Ops/ATIS.lua b/Moose Development/Moose/Ops/ATIS.lua index 6d7a939bd..a1b5f4866 100644 --- a/Moose Development/Moose/Ops/ATIS.lua +++ b/Moose Development/Moose/Ops/ATIS.lua @@ -515,7 +515,7 @@ _ATIS={} --- ATIS class version. -- @field #string version -ATIS.version="0.6.0" +ATIS.version="0.6.1" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -996,9 +996,15 @@ function ATIS:onafterStatus(From, Event, To) -- Get FSM state. local fsmstate=self:GetState() + + local relayunitstatus="N/A" + if self.relayunitname then + local ru=UNIT:FindByName(self.relayunitname) + relayunitstatus=tostring(ru:IsAlive()) + end -- Info text. - local text=string.format("State %s", fsmstate) + local text=string.format("State %s: Freq=%.3f MHz %s, Relay unit=%s (alive=%s)", fsmstate, self.frequency, UTILS.GetModulationName(self.modulation), tostring(self.relayunitname), relayunitstatus) self:I(self.lid..text) self:__Status(-60) diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 26ef8c76e..766b8de47 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -1060,3 +1060,23 @@ function UTILS.GetCoalitionName(Coalition) end +--- Get the modulation name from its numerical value. +-- @param #number Modulation The modulation enumerator number. Can be either 0 or 1. +-- @return #string The modulation name, i.e. "AM"=0 or "FM"=1. Anything else will return "Unknown". +function UTILS.GetModulationName(Modulation) + + if Modulation then + if Modulation==0 then + return "AM" + elseif Modulation==1 then + return "FM" + else + return "Unknown" + end + else + return "Unknown" + end + +end + +