This commit is contained in:
Applevangelist 2023-12-30 16:48:17 +01:00
parent 6d818cbc1d
commit 596334dab9

View File

@ -0,0 +1,388 @@
--- **Functional** - TIRESIAS
--
-- ===
--
-- ## Features:
--
-- * Tbd
--
-- ===
--
-- ## Missions:
--
-- ### [TIRESIAS](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master)
--
-- ===
--
-- ### Author : **applevangelist **
--
-- @module Functional.Tiresias
-- @image Functional.Tiresias.jpg
--
-- Last Update: Dec 2023
-------------------------------------------------------------------------
--- **TIRESIAS** class, extends Core.Base#BASE
-- @type TIRESIAS
-- @field #string ClassName
-- @field #booelan debug
-- @field #string version
-- @field #number Interval
-- @field Core.Set#SET_CLIENT PilotSet
-- @field Core.Set#SET_GROUP GroundSet
-- @field #string CoalitionText
-- @field #number Coalition
-- @field Core.Set#SET_GROUP VehicleSet
-- @field Core.Set#SET_GROUP AAASet
-- @field Core.Set#SET_GROUP SAMSet
-- @field #number AAARange
-- @field #number HeloSwitchRange
-- @field #number PlaneSwitchRange
-- @field Core.Set#SET_GROUP FlightSet
-- @extends Core.Fsm#FSM
---
-- @type TIRESIAS.Data
-- @field #string type
-- @field #number range
-- @field #boolean invisible
-- @field #boolean AIOff
---
-- # Documentation
--
-- @field TIRESIAS
TIRESIAS = {
ClassName = "TIRESIAS",
debug = true,
version = "0.0.1",
Interval = 20,
PilotSet = nil,
GroundSet = nil,
CoalitionText = "blue",
Coalition = coalition.side.BLUE,
VehicleSet = nil,
AAASet = nil,
SAMSet = nil,
AAARange = 60,
HeloSwitchRange = 10, -- NM
PlaneSwitchRange = 25, -- NM
}
---
-- @param #TIRESIAS self
-- @return #TIRESIAS self
function TIRESIAS:New()
-- Inherit everything from FSM class.
local self = BASE:Inherit(self, FSM:New()) -- #TIRESIAS
self.PilotSet = SET_CLIENT:New():FilterActive(true):FilterCoalitions(self.CoalitionText):FilterStart()
--- FSM Functions ---
-- Start State.
self:SetStartState("Stopped")
-- Add FSM transitions.
-- From State --> Event --> To State
self:AddTransition("Stopped", "Start", "Running") -- Start FSM.
self:AddTransition("*", "Status", "*") -- TIRESIAS status update.
self:AddTransition("*", "Stop", "Stopped") -- Stop FSM.
self:HandleEvent(EVENTS.PlayerEnterAircraft,self._EventHandler)
self.lid = string.format("TIRESIAS %s | ",self.version)
self:I(self.lid.."Managing ground groups!")
self:__Start(1)
return self
end
-------------------------------------------------------------------------------------------------------------
--
-- Helper Functions
--
-------------------------------------------------------------------------------------------------------------
---
-- @param #TIRESIAS self
-- @param Wrapper.Group#GROUP Group
-- @return #boolean isin
function TIRESIAS._FilterAAA(Group)
local grp = Group -- Wrapper.Group#GROUP
local isaaa = grp:IsAAA()
if isaaa == true and grp:IsGround() then
return false -- remove from SET
else
return true -- keep in SET
end
end
---
-- @param #TIRESIAS self
-- @param Wrapper.Group#GROUP Group
-- @return #boolean isin
function TIRESIAS._FilterSAM(Group)
local grp = Group -- Wrapper.Group#GROUP
local issam = grp:IsSAM()
if issam == true and grp:IsGround() then
return false -- remove from SET
else
return true -- keep in SET
end
end
---
-- @param #TIRESIAS self
-- @return #TIRESIAS self
function TIRESIAS:_InitGroups()
self:I(self.lid.."_InitGroups")
-- Set all groups invisible/motionless
local EngageRange = self.AAARange
self.AAASet:ForEachGroupAlive(
function(grp)
if not grp.Tiresias then
grp:OptionEngageRange(EngageRange)
grp:SetCommandInvisible(true)
grp.Tiresias = { -- #TIRESIAS.Data
type = "AAA",
invisible = true,
range = EngageRange,
}
end
if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then
grp:SetCommandInvisible(true)
end
end
)
self.VehicleSet:ForEachGroupAlive(
function(grp)
if not grp.Tiresias then
grp:SetAIOff()
grp:SetCommandInvisible(true)
grp.Tiresias = { -- #TIRESIAS.Data
type = "Vehicle",
invisible = true,
AIOff = true,
}
end
if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then
grp:SetCommandInvisible(true)
grp:SetAIOff()
end
end
)
self.SAMSet:ForEachGroupAlive(
function(grp)
if not grp.Tiresias then
grp:SetCommandInvisible(true)
grp.Tiresias = { -- #TIRESIAS.Data
type = "SAM",
invisible = true,
}
end
if grp.Tiresias and grp.Tiresias.invisible and grp.Tiresias.invisible == false then
grp:SetCommandInvisible(true)
end
end
)
return self
end
--- (Internal) Event handler function
-- @param #TIRESIAS self
-- @param Core.Event#EVENTDATA EventData
-- @return #TIRESIAS self
function TIRESIAS:_EventHandler(EventData)
self:I(string.format("%s Event = %d",self.lid, EventData.id))
local event = EventData -- Core.Event#EVENTDATA
if event.id == EVENTS.PlayerEnterAircraft or event.id == EVENTS.PlayerEnterUnit then
local _coalition = event.IniCoalition
if _coalition ~= self.Coalition then
return --ignore!
end
local unitname = event.IniUnitName or "none"
local _unit = event.IniUnit
local _group = event.IniGroup
if _group and _group:IsAlive() then
local radius = self.PlaneSwitchRange
if _group:IsHelicopter() then
radius = self.HeloSwitchRange
end
self:_SwitchOnGroups(_group,radius)
end
end
return self
end
---
-- @param #TIRESIAS self
-- @param Wrapper.Group#GROUP group
-- @param #number radius Radius in NM
-- @return #TIRESIAS self
function TIRESIAS:_SwitchOnGroups(group,radius)
self:I(self.lid.."_SwitchOnGroups "..group:GetName().." Radius "..radius.." NM")
local zone = ZONE_GROUP:New("Zone-"..group:GetName(),group,UTILS.NMToMeters(radius))
local ground = SET_GROUP:New():FilterCategoryGround():FilterZones({zone}):FilterOnce()
local count = ground:CountAlive()
if self.debug then
local text = string.format("There are %d groups around this plane or helo!",count)
self:I(text)
end
if ground:CountAlive() > 0 then
ground:ForEachGroupAlive(
function(grp)
if grp.Tiresias and grp.Tiresias.type then
if grp.Tiresias.invisible == true then
grp:SetCommandInvisible(false)
grp.Tiresias.invisible = false
end
if grp.Tiresias.type == "Vehicle" and grp.Tiresias.AIOff and grp.Tiresias.AIOff == false then
grp:SetAIOn()
grp.Tiresias.AIOff = false
end
else
BASE:I("TIRESIAS - This group has not been initialized!")
end
end
)
end
return self
end
-------------------------------------------------------------------------------------------------------------
--
-- FSM Functions
--
-------------------------------------------------------------------------------------------------------------
---
-- @param #TIRESIAS self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #TIRESIAS self
function TIRESIAS:onafterStart(From, Event, To)
self:I({From, Event, To})
local VehicleSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(TIRESIAS._FilterAAA):FilterFunction(TIRESIAS._FilterSAM):FilterStart()
local AAASet = SET_GROUP:New():FilterCategoryGround():FilterFunction(function(grp) return grp:IsAAA() end):FilterStart()
local SAMSet = SET_GROUP:New():FilterCategoryGround():FilterFunction(function(grp) return grp:IsSAM() end):FilterStart()
self.FlightSet = SET_GROUP:New():FilterCategories({"plane","helicopter"}):FilterStart()
local EngageRange = self.AAARange
function VehicleSet:OnAfterAdded(From,Event,To,ObjectName,Object)
BASE:I("TIRESIAS: VEHCILE Object Added: "..Object:GetName())
if Object and Object:IsAlive() then
Object:SetAIOff()
Object:SetCommandInvisible(true)
Object.Tiresias = { -- #TIRESIAS.Data
type = "Vehicle",
invisible = true,
AIOff = true,
}
end
end
function AAASet:OnAfterAdded(From,Event,To,ObjectName,Object)
if Object and Object:IsAlive() then
BASE:I("TIRESIAS: AAA Object Added: "..Object:GetName())
Object:OptionEngageRange(EngageRange)
Object:SetCommandInvisible(true)
Object.Tiresias = { -- #TIRESIAS.Data
type = "AAA",
invisible = true,
range = EngageRange,
}
end
end
function SAMSet:OnAfterAdded(From,Event,To,ObjectName,Object)
if Object and Object:IsAlive() then
BASE:I("TIRESIAS: SAM Object Added: "..Object:GetName())
Object:SetCommandInvisible(true)
Object.Tiresias = { -- #TIRESIAS.Data
type = "SAM",
invisible = true,
}
end
end
self.VehicleSet = VehicleSet
self.AAASet = AAASet
self.SAMSet = SAMSet
self:_InitGroups()
self:__Status(1)
return self
end
---
-- @param #TIRESIAS self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #TIRESIAS self
function TIRESIAS:onbeforeStatus(From, Event, To)
self:T({From, Event, To})
if self:GetState() == "Stopped" then
return false
end
return self
end
---
-- @param #TIRESIAS self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #TIRESIAS self
function TIRESIAS:onafterStatus(From, Event, To)
self:I({From, Event, To})
if self.debug then
local count = self.VehicleSet:CountAlive()
local AAAcount = self.AAASet:CountAlive()
local SAMcount = self.SAMSet:CountAlive()
local text = string.format("Overall: %d | Vehicles: %d | AAA: %d | SAM: %d",count+AAAcount+SAMcount,count,AAAcount,SAMcount)
self:I(text)
end
self:_InitGroups()
if self.FlightSet:CountAlive() > 0 then
local Set = self.FlightSet:GetAliveSet()
for _,_plane in pairs(Set) do
local plane = _plane -- Wrapper.Group#GROUP
local radius = self.PlaneSwitchRange
if plane:IsHelicopter() then
radius = self.HeloSwitchRange
end
self:_SwitchOnGroups(_plane,radius)
end
end
if self:GetState() ~= "Stopped" then
self:__Status(self.Interval)
end
return self
end
---
-- @param #TIRESIAS self
-- @param #string From
-- @param #string Event
-- @param #string To
-- @return #TIRESIAS self
function TIRESIAS:onafterStop(From, Event, To)
self:I({From, Event, To})
self:UnHandleEvent(EVENTS.PlayerEnterAircraft)
return self
end
-------------------------------------------------------------------------------------------------------------
--
-- End
--
-------------------------------------------------------------------------------------------------------------