diff --git a/Moose Development/Moose/Core/Goal.lua b/Moose Development/Moose/Core/Goal.lua index ac1f616b9..c145d6de4 100644 --- a/Moose Development/Moose/Core/Goal.lua +++ b/Moose Development/Moose/Core/Goal.lua @@ -15,6 +15,7 @@ -- === -- -- ### Author: **FlightControl** +-- ### Contributions: **funkyfranky** -- -- === -- diff --git a/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua b/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua index fbca12fae..81c2aefd1 100644 --- a/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua +++ b/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua @@ -39,7 +39,7 @@ -- === -- -- ### Author: **FlightControl** --- ### Contributions: **Millertime** - Concept +-- ### Contributions: **Millertime** - Concept, **funkyfranky** -- -- === -- @@ -49,6 +49,15 @@ do -- ZONE_CAPTURE_COALITION --- @type ZONE_CAPTURE_COALITION + -- @field #string ClassName Name of the class. + -- @field #number MarkBlue ID of blue F10 mark. + -- @field #number MarkRed ID of red F10 mark. + -- @field #number StartInterval Time in seconds after the status monitor is started. + -- @field #number RepeatInterval Time in seconds after which the zone status is updated. + -- @field #boolean HitsOn If true, hit events are monitored and trigger the "Attack" event when a defending unit is hit. + -- @field #number HitTimeLast Time stamp in seconds when the last unit inside the zone was hit. + -- @field #number HitTimeAttackOver Time interval in seconds before the zone goes from "Attacked" to "Guarded" state after the last hit. + -- @field #boolean MarkOn If true, create marks of zone status on F10 map. -- @extends Functional.ZoneGoalCoalition#ZONE_GOAL_COALITION @@ -337,12 +346,21 @@ do -- ZONE_CAPTURE_COALITION -- -- @field #ZONE_CAPTURE_COALITION ZONE_CAPTURE_COALITION = { - ClassName = "ZONE_CAPTURE_COALITION", + ClassName = "ZONE_CAPTURE_COALITION", + MarkBlue = nil, + MarkRed = nil, + StartInterval = nil, + RepeatInterval = nil, + HitsOn = nil, + HitTimeLast = nil, + HitTimeAttackOver = nil, + MarkOn = nil, } - - --- @field #table ZONE_CAPTURE_COALITION.States - ZONE_CAPTURE_COALITION.States = {} - + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Constructor and Start/Stop Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + --- ZONE_CAPTURE_COALITION Constructor. -- @param #ZONE_CAPTURE_COALITION self -- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved. @@ -354,16 +372,22 @@ do -- ZONE_CAPTURE_COALITION -- -- AttackZone = ZONE:New( "AttackZone" ) -- - -- ZoneCaptureCoalition = ZONE_CAPTURE_COALITION:New( AttackZone, coalition.side.RED ) -- Create a new ZONE_CAPTURE_COALITION object of zone AttackZone with ownership RED coalition. + -- ZoneCaptureCoalition = ZONE_CAPTURE_COALITION:New( AttackZone, coalition.side.RED, {UNITS ) -- Create a new ZONE_CAPTURE_COALITION object of zone AttackZone with ownership RED coalition. -- ZoneCaptureCoalition:__Guard( 1 ) -- Start the Guarding of the AttackZone. -- function ZONE_CAPTURE_COALITION:New( Zone, Coalition, UnitCategories, ObjectCategories ) local self = BASE:Inherit( self, ZONE_GOAL_COALITION:New( Zone, Coalition, UnitCategories ) ) -- #ZONE_CAPTURE_COALITION - self:F( { Zone = Zone, Coalition = Coalition, UnitCategories = UnitCategories, ObjectCategories = ObjectCategories } ) self:SetObjectCategories(ObjectCategories) + + -- Default is no smoke. + self:SetSmokeZone(false) + -- Default is F10 marks ON. + self:SetMarkZone(true) + -- Start in state "Empty". + self:SetStartState("Empty") do @@ -548,47 +572,8 @@ do -- ZONE_CAPTURE_COALITION -- @param #ZONE_CAPTURE_COALITION self -- @param #number Delay - self:AddTransition( "*", "ChangeCoalition", "*" ) - - --- ChangeCoalition Handler OnBefore for ZONE_CAPTURE_COALITION - -- @function [parent=#ZONE_CAPTURE_COALITION] OnBeforeChangeCoalition - -- @param #ZONE_CAPTURE_COALITION self - -- @param #string From - -- @param #string Event - -- @param #string To - -- @param #number NewCoalition New coalition ID, i.e. after the change. - -- @param #number OldCoalition Old coalition ID, i.e. before the change. - -- @return #boolean - - --- ChangeCoalition Handler OnAfter for ZONE_CAPTURE_COALITION - -- @function [parent=#ZONE_CAPTURE_COALITION] OnAfterChangeCoalition - -- @param #ZONE_CAPTURE_COALITION self - -- @param #string From - -- @param #string Event - -- @param #string To - -- @param #number NewCoalition New coalition ID, i.e. after the change. - -- @param #number OldCoalition Old coalition ID, i.e. before the change. - - --- ChangeCoalition Trigger for ZONE_CAPTURE_COALITION - -- @function [parent=#ZONE_CAPTURE_COALITION] ChangeCoalition - -- @param #ZONE_CAPTURE_COALITION self - -- @param #number NewCoalition New coalition ID, i.e. after the change. - -- @param #number OldCoalition Old coalition ID, i.e. before the change. - - --- ChangeCoalition Asynchronous Trigger for ZONE_CAPTURE_COALITION - -- @function [parent=#ZONE_CAPTURE_COALITION] __ChangeCoalition - -- @param #ZONE_CAPTURE_COALITION self - -- @param #number Delay - -- @param #number NewCoalition New coalition ID, i.e. after the change. - -- @param #number OldCoalition Old coalition ID, i.e. before the change. - - - -- We check if a unit within the zone is hit. - -- If it is, then we must move the zone to attack state. - self:HandleEvent( EVENTS.Hit, self.OnEventHit ) - -- ZoneGoal objects are added to the _DATABASE.ZONES_GOAL and SET_ZONE_GOAL sets. - _EVENTDISPATCHER:CreateEventNewZoneGoal( self ) + _EVENTDISPATCHER:CreateEventNewZoneGoal(self) return self end @@ -603,6 +588,7 @@ do -- ZONE_CAPTURE_COALITION -- @param #ZONE_CAPTURE_COALITION self -- @param #number StartInterval (optional) Specifies the start time interval in seconds when the zone state will be checked for the first time. -- @param #number RepeatInterval (optional) Specifies the repeat time interval in seconds when the zone state will be checked repeatedly. + -- @return #ZONE_CAPTURE_COALITION self -- @usage -- -- -- Setup the zone. @@ -626,6 +612,14 @@ do -- ZONE_CAPTURE_COALITION -- Start Status scheduler. self.ScheduleStatusZone = self:ScheduleRepeat( self.StartInterval, self.RepeatInterval, 0.1, nil, self.StatusZone, self ) + + -- We check if a unit within the zone is hit. If it is, then we must move the zone to attack state. + self:HandleEvent(EVENTS.Hit, self.OnEventHit) + + -- Create mark on F10 map. + self:Mark() + + return self end @@ -667,30 +661,88 @@ do -- ZONE_CAPTURE_COALITION function ZONE_CAPTURE_COALITION:Stop() if self.ScheduleStatusZone then - self:ScheduleStop( self.ScheduleStatusZone ) + self:ScheduleStop(self.ScheduleStatusZone) end + + if self.SmokeScheduler then + self:ScheduleStop(self.SmokeScheduler) + end + + self:UnHandleEvent(EVENTS.Hit) + end + + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- User API Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + + --- Set whether hit events of defending units are monitored and trigger "Attack" events. + -- @param #ZONE_CAPTURE_COALITION self + -- @param #boolean Switch If *true*, hit events are monitored. If *false* or *nil*, hit events are not monitored. + -- @param #number TimeAttackOver (Optional) Time in seconds after an attack is over after the last hit and the zone state goes to "Guarded". Default is 300 sec = 5 min. + -- @return #ZONE_CAPTURE_COALITION self + function ZONE_CAPTURE_COALITION:SetMonitorHits(Switch, TimeAttackOver) + self.HitsOn=Switch + self.HitTimeAttackOver=TimeAttackOver or 5*60 + return self + end + + --- Set whether marks on the F10 map are shown, which display the current zone status. + -- @param #ZONE_CAPTURE_COALITION self + -- @param #boolean Switch If *true* or *nil*, marks are shown. If *false*, marks are not displayed. + -- @return #ZONE_CAPTURE_COALITION self + function ZONE_CAPTURE_COALITION:SetMarkZone(Switch) + if Switch==nil or Switch==true then + self.MarkOn=true + else + self.MarkOn=false + end + return self + end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- DCS Event Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + - --- @param #ZONE_CAPTURE_COALITION self + --- Monitor hit events. + -- @param #ZONE_CAPTURE_COALITION self -- @param Core.Event#EVENTDATA EventData The event data. function ZONE_CAPTURE_COALITION:OnEventHit( EventData ) - local UnitHit = EventData.TgtUnit - - if UnitHit then - if UnitHit:IsInZone( self ) then - self:Attack() + if self.HitsOn then + + local UnitHit = EventData.TgtUnit + + -- Check if unit is inside the capture zone and that it is of the defending coalition. + if UnitHit and UnitHit:IsInZone(self) and UnitHit:GetCoalition()==self.Coalition then + + -- Update last hit time. + self.HitTimeLast=timer.getTime() + + -- Only trigger attacked event if not already in state "Attacked". + if self:GetState()~="Attacked" then + self:F2("Hit ==> Attack") + self:Attack() + end + end + end end +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- FSM Event Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --- On after "Guard" event. -- @param #ZONE_CAPTURE_COALITION self function ZONE_CAPTURE_COALITION:onafterGuard() + self:F2("After Guard") - if not self.SmokeScheduler then + if self.SmokeZone and not self.SmokeScheduler then self.SmokeScheduler = self:ScheduleRepeat( self.StartInterval, self.RepeatInterval, 0.1, nil, self.StatusSmoke, self ) end @@ -699,21 +751,21 @@ do -- ZONE_CAPTURE_COALITION --- On enter "Guarded" state. -- @param #ZONE_CAPTURE_COALITION self function ZONE_CAPTURE_COALITION:onenterGuarded() - env.info("FF enter Guarded") + self:F2("Enter Guarded") self:Mark() end --- On enter "Captured" state. -- @param #ZONE_CAPTURE_COALITION self function ZONE_CAPTURE_COALITION:onenterCaptured() - env.info("FF enter Captured") + self:F2("Enter Captured") -- Get new coalition. local NewCoalition = self:GetScannedCoalition() self:F( { NewCoalition = NewCoalition } ) -- Set new owner of zone. - self:ChangeCoalition(NewCoalition, self.Coalition) + self:SetCoalition(NewCoalition) -- Update mark. self:Mark() @@ -721,92 +773,70 @@ do -- ZONE_CAPTURE_COALITION -- Goal achieved. self.Goal:Achieved() end - - --- On after "ChangeCoalition" state. - -- @param #ZONE_CAPTURE_COALITION self - function ZONE_CAPTURE_COALITION:onafterChangeCoalition(From, Event, To, NewCoalition, OldCoalition) - env.info("FF after ChangeCoalition") - self:SetCoalition(NewCoalition) - end - + --- On enter "Empty" state. -- @param #ZONE_CAPTURE_COALITION self function ZONE_CAPTURE_COALITION:onenterEmpty() - env.info("FF enter Empty") + self:F2("Enter Empty") self:Mark() end --- On enter "Attacked" state. -- @param #ZONE_CAPTURE_COALITION self function ZONE_CAPTURE_COALITION:onenterAttacked() - env.info("FF enter Attacked") + self:F2("Enter Attacked") self:Mark() end +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Status Check Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - - --- Check if zone is "Guarded" - -- @param #ZONE_CAPTURE_COALITION self - -- @return #boolean self:IsAllInZoneOfCoalition( self.Coalition ) - function ZONE_CAPTURE_COALITION:IsGuarded() - - local IsGuarded = self:IsAllInZoneOfCoalition( self.Coalition ) - self:F( { IsGuarded = IsGuarded } ) - return IsGuarded - end - - --- Check if zone is "Empty" + --- Check if zone is "Empty". -- @param #ZONE_CAPTURE_COALITION self -- @return #boolean self:IsNoneInZone() function ZONE_CAPTURE_COALITION:IsEmpty() local IsEmpty = self:IsNoneInZone() self:F( { IsEmpty = IsEmpty } ) + return IsEmpty end - --- Check if zone is "Captured" + --- Check if zone is "Guarded", i.e. only one (the defending) coaliton is present inside the zone. + -- @param #ZONE_CAPTURE_COALITION self + -- @return #boolean self:IsAllInZoneOfCoalition( self.Coalition ) + function ZONE_CAPTURE_COALITION:IsGuarded() + + local IsGuarded = self:IsAllInZoneOfCoalition( self.Coalition ) + self:F( { IsGuarded = IsGuarded } ) + + return IsGuarded + end + + --- Check if zone is "Captured", i.e. another coalition took control over the zone and is the only one present. -- @param #ZONE_CAPTURE_COALITION self -- @return #boolean self:IsAllInZoneOfOtherCoalition( self.Coalition ) function ZONE_CAPTURE_COALITION:IsCaptured() local IsCaptured = self:IsAllInZoneOfOtherCoalition( self.Coalition ) self:F( { IsCaptured = IsCaptured } ) + return IsCaptured end - --- Check if zone is "Attacked" + --- Check if zone is "Attacked", i.e. another coaliton entered the zone. -- @param #ZONE_CAPTURE_COALITION self -- @return #boolean self:IsSomeInZoneOfCoalition( self.Coalition ) function ZONE_CAPTURE_COALITION:IsAttacked() local IsAttacked = self:IsSomeInZoneOfCoalition( self.Coalition ) self:F( { IsAttacked = IsAttacked } ) + return IsAttacked end - - --- Check if zone is captured. - -- @param #ZONE_CAPTURE_COALITION self - -- @return #boolean self:IsAllInZoneOfOtherCoalition( self.Coalition ) - function ZONE_CAPTURE_COALITION:IsCaptured() - local IsCaptured = self:IsAllInZoneOfOtherCoalition( self.Coalition ) - self:F( { IsCaptured = IsCaptured } ) - return IsCaptured - end - - --- Check if zone is attacked. - -- @param #ZONE_CAPTURE_COALITION self - -- @return #boolean self:IsSomeInZoneOfCoalition( self.Coalition ) - function ZONE_CAPTURE_COALITION:IsAttacked() - - local IsAttacked = self:IsSomeInZoneOfCoalition( self.Coalition ) - self:F( { IsAttacked = IsAttacked } ) - return IsAttacked - end - - --- Check status Coalition ownership. -- @param #ZONE_CAPTURE_COALITION self function ZONE_CAPTURE_COALITION:StatusZone() @@ -817,9 +847,16 @@ do -- ZONE_CAPTURE_COALITION -- Scan zone in parent class ZONE_GOAL_COALITION self:GetParent( self, ZONE_CAPTURE_COALITION ).StatusZone( self ) + local Tnow=timer.getTime() + -- Check if zone is guarded. if State ~= "Guarded" and self:IsGuarded() then - self:Guard() + + -- Check that there was a sufficient amount of time after the last hit before going back to "Guarded". + if self.HitTimeLast==nil or Tnow>=self.HitTimeLast+self.HitTimeAttackOver then + self:Guard() + self.HitTimeLast=nil + end end -- Check if zone is empty. @@ -837,9 +874,8 @@ do -- ZONE_CAPTURE_COALITION self:Capture() end - -- - local text=string.format("CAPTURE ZONE %s: Status %s", self:GetZoneName(), State) - + -- 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 NewState = self:GetState() if NewState~=State then text=text..string.format(" --> %s", NewState) @@ -847,32 +883,44 @@ do -- ZONE_CAPTURE_COALITION self:I(text) end + +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- +-- Misc Functions +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + --- Update Mark on F10 map. -- @param #ZONE_CAPTURE_COALITION self function ZONE_CAPTURE_COALITION:Mark() - local Coord = self:GetCoordinate() - local ZoneName = self:GetZoneName() - local State = self:GetState() + if self.MarkOn then - if self.MarkRed and self.MarkBlue then - self:F( { MarkRed = self.MarkRed, MarkBlue = self.MarkBlue } ) - Coord:RemoveMark( self.MarkRed ) - Coord:RemoveMark( self.MarkBlue ) + local Coord = self:GetCoordinate() + local ZoneName = self:GetZoneName() + local State = self:GetState() + + -- Remove marks. + if self.MarkRed then + Coord:RemoveMark(self.MarkRed) + end + if self.MarkBlue then + Coord:RemoveMark(self.MarkBlue) + end + + -- Create new marks for each coaliton. + if self.Coalition == coalition.side.BLUE then + self.MarkBlue = Coord:MarkToCoalitionBlue( "Coalition: Blue\nGuard Zone: " .. ZoneName .. "\nStatus: " .. State ) + self.MarkRed = Coord:MarkToCoalitionRed( "Coalition: Blue\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State ) + elseif self.Coalition == coalition.side.RED then + self.MarkRed = Coord:MarkToCoalitionRed( "Coalition: Red\nGuard Zone: " .. ZoneName .. "\nStatus: " .. State ) + self.MarkBlue = Coord:MarkToCoalitionBlue( "Coalition: Red\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State ) + else + self.MarkRed = Coord:MarkToCoalitionRed( "Coalition: Neutral\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State ) + self.MarkBlue = Coord:MarkToCoalitionBlue( "Coalition: Neutral\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State ) + end + end - if self.Coalition == coalition.side.BLUE then - self.MarkBlue = Coord:MarkToCoalitionBlue( "Coalition: Blue\nGuard Zone: " .. ZoneName .. "\nStatus: " .. State ) - self.MarkRed = Coord:MarkToCoalitionRed( "Coalition: Blue\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State ) - elseif self.Coalition == coalition.side.RED then - self.MarkRed = Coord:MarkToCoalitionRed( "Coalition: Red\nGuard Zone: " .. ZoneName .. "\nStatus: " .. State ) - self.MarkBlue = Coord:MarkToCoalitionBlue( "Coalition: Red\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State ) - else - self.MarkRed = Coord:MarkToCoalitionRed( "Coalition: Neutral\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State ) - self.MarkBlue = Coord:MarkToCoalitionBlue( "Coalition: Neutral\nCapture Zone: " .. ZoneName .. "\nStatus: " .. State ) - end end - end diff --git a/Moose Development/Moose/Functional/ZoneGoal.lua b/Moose Development/Moose/Functional/ZoneGoal.lua index f3ba834dd..cd55b2603 100644 --- a/Moose Development/Moose/Functional/ZoneGoal.lua +++ b/Moose Development/Moose/Functional/ZoneGoal.lua @@ -8,6 +8,7 @@ -- === -- -- ### Author: **FlightControl** +-- ### Contributions: **funkyfranky** -- -- === -- @@ -111,14 +112,17 @@ do -- Zone --- Activate smoking of zone with the color or the current owner. -- @param #ZONE_GOAL self - -- @param #boolean switch If *true* or *nil* activate smoke. If false, no smoke. + -- @param #boolean switch If *true* or *nil* activate smoke. If *false* or *nil*, no smoke. -- @return #ZONE_GOAL function ZONE_GOAL:SetSmokeZone(switch) + self.SmokeZone=switch + --[[ if switch==nil or switch==true then self.SmokeZone=true else self.SmokeZone=false end + ]] return self end @@ -145,8 +149,9 @@ do -- Zone function ZONE_GOAL:onafterGuard() self:F("Guard") + -- Start smoke if self.SmokeZone and not self.SmokeScheduler then - self.SmokeScheduler = self:ScheduleRepeat( 1, 1, 0.1, nil, self.StatusSmoke, self ) + self.SmokeScheduler = self:ScheduleRepeat(1, 1, 0.1, nil, self.StatusSmoke, self) end end diff --git a/Moose Development/Moose/Functional/ZoneGoalCoalition.lua b/Moose Development/Moose/Functional/ZoneGoalCoalition.lua index a25d4e534..6296b4835 100644 --- a/Moose Development/Moose/Functional/ZoneGoalCoalition.lua +++ b/Moose Development/Moose/Functional/ZoneGoalCoalition.lua @@ -19,6 +19,7 @@ do -- ZoneGoal --- @type ZONE_GOAL_COALITION -- @field #string ClassName Name of the Class. -- @field #number Coalition The current coalition ID of the zone owner. + -- @field #number PreviousCoalition The previous owner of the zone. -- @field #table UnitCategories Table of unit categories that are able to capture and hold the zone. Default is only GROUND units. -- @field #table ObjectCategories Table of object categories that are able to hold a zone. Default is UNITS and STATICS. -- @extends Functional.ZoneGoal#ZONE_GOAL @@ -43,6 +44,7 @@ do -- ZoneGoal ZONE_GOAL_COALITION = { ClassName = "ZONE_GOAL_COALITION", Coalition = nil, + PreviousCoaliton = nil, UnitCategories = nil, ObjectCategories = nil, } @@ -83,6 +85,7 @@ do -- ZoneGoal -- @param DCSCoalition.DCSCoalition#coalition Coalition The coalition ID, e.g. *coalition.side.RED*. -- @return #ZONE_GOAL_COALITION function ZONE_GOAL_COALITION:SetCoalition( Coalition ) + self.PreviousCoalition=self.Coalition or Coalition self.Coalition = Coalition return self end @@ -124,25 +127,19 @@ do -- ZoneGoal return self.Coalition end + --- Get the previous coaliton, i.e. the one owning the zone before the current one. + -- @param #ZONE_GOAL_COALITION self + -- @return DCSCoalition.DCSCoalition#coalition Coalition. + function ZONE_GOAL_COALITION:GetPreviousCoalition() + return self.PreviousCoalition + end + --- Get the owning coalition name of the zone. -- @param #ZONE_GOAL_COALITION self -- @return #string Coalition name. function ZONE_GOAL_COALITION:GetCoalitionName() - - if self.Coalition == coalition.side.BLUE then - return "Blue" - end - - if self.Coalition == coalition.side.RED then - return "Red" - end - - if self.Coalition == coalition.side.NEUTRAL then - return "Neutral" - end - - return "Unknown" + return UTILS.GetCoalitionName(self.Coalition) end @@ -151,13 +148,14 @@ do -- ZoneGoal -- @return #ZONE_GOAL_COALITION function ZONE_GOAL_COALITION:StatusZone() + -- Get current state. local State = self:GetState() - self:F( { State = self:GetState() } ) -- Debug text. local text=string.format("Zone state=%s, Owner=%s, Scanning...", State, self:GetCoalitionName()) - env.info(text) - + self:F(text) + + -- Scan zone. self:Scan( self.ObjectCategories, self.UnitCategories ) return self diff --git a/Moose Development/Moose/Ops/RecoveryTanker.lua b/Moose Development/Moose/Ops/RecoveryTanker.lua index dae5f2ab4..b779f8efc 100644 --- a/Moose Development/Moose/Ops/RecoveryTanker.lua +++ b/Moose Development/Moose/Ops/RecoveryTanker.lua @@ -62,6 +62,7 @@ -- @field #string modex Tail number of the tanker. -- @field #boolean eplrs If true, enable data link, e.g. if used as AWACS. -- @field #boolean recovery If true, tanker will recover using the AIRBOSS marshal pattern. +-- @field #number terminaltype Terminal type of used parking spots on airbases. -- @extends Core.Fsm#FSM --- Recovery Tanker. @@ -298,6 +299,7 @@ RECOVERYTANKER = { modex = nil, eplrs = nil, recovery = nil, + terminaltype = nil, } --- Unique ID (global). @@ -306,7 +308,7 @@ _RECOVERYTANKERID=0 --- Class version. -- @field #string version -RECOVERYTANKER.version="1.0.8" +RECOVERYTANKER.version="1.0.9" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -381,6 +383,7 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname) self:SetPatternUpdateInterval() self:SetAWACS(false) self:SetRecoveryAirboss(false) + self.terminaltype=AIRBASE.TerminalType.OpenMedOrBig -- Debug trace. if false then @@ -615,8 +618,9 @@ end --- Set home airbase of the tanker. This is the airbase where the tanker will go when it is out of fuel. -- @param #RECOVERYTANKER self -- @param Wrapper.Airbase#AIRBASE airbase The home airbase. Can be the airbase name or a Moose AIRBASE object. +-- @param #number terminaltype (Optional) The terminal type of parking spots used for spawning at airbases. Default AIRBASE.TerminalType.OpenMedOrBig. -- @return #RECOVERYTANKER self -function RECOVERYTANKER:SetHomeBase(airbase) +function RECOVERYTANKER:SetHomeBase(airbase, terminaltype) if type(airbase)=="string" then self.airbase=AIRBASE:FindByName(airbase) else @@ -625,6 +629,9 @@ function RECOVERYTANKER:SetHomeBase(airbase) if not self.airbase then self:E(self.lid.."ERROR: Airbase is nil!") end + if termialtype then + self.terminaltype=terminaltype + end return self end @@ -937,7 +944,7 @@ function RECOVERYTANKER:onafterStart(From, Event, To) else -- Spawn tanker at airbase. - self.tanker=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, AIRBASE.TerminalType.OpenMedOrBig) + self.tanker=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, self.terminaltype) end diff --git a/Moose Development/Moose/Ops/RescueHelo.lua b/Moose Development/Moose/Ops/RescueHelo.lua index b3b0fc69f..8e979ccf9 100644 --- a/Moose Development/Moose/Ops/RescueHelo.lua +++ b/Moose Development/Moose/Ops/RescueHelo.lua @@ -237,7 +237,7 @@ _RESCUEHELOID=0 --- Class version. -- @field #string version -RESCUEHELO.version="1.0.9" +RESCUEHELO.version="1.1.0" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- TODO list @@ -902,7 +902,7 @@ function RESCUEHELO:onafterStart(From, Event, To) else -- Check if an uncontrolled helo group was requested. - if self.useuncontrolled then + if self.uncontrolledac then -- Use an uncontrolled aircraft group. self.helo=GROUP:FindByName(self.helogroupname) diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index 683252718..acfc30323 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -1037,3 +1037,26 @@ function UTILS.CheckMemory(output) end return mem end + + +--- Get the coalition name from its numerical ID, e.g. coaliton.side.RED. +-- @param #number Coalition The coalition ID. +-- @return #string The coalition name, i.e. "Neutral", "Red" or "Blue" (or "Unknown"). +function UTILS.GetCoalitionName(Coalition) + + if Coalition then + if Coalition==coalition.side.BLUE then + return "Blue" + elseif Coalition==coalition.side.RED then + return "Red" + elseif Coalition==coalition.side.NEUTRAL then + return "Neutral" + else + return "Unknown" + end + else + return "Unknown" + end + +end + diff --git a/Moose Development/Moose/Wrapper/Identifiable.lua b/Moose Development/Moose/Wrapper/Identifiable.lua index 13a5b3234..7943fe049 100644 --- a/Moose Development/Moose/Wrapper/Identifiable.lua +++ b/Moose Development/Moose/Wrapper/Identifiable.lua @@ -168,20 +168,13 @@ function IDENTIFIABLE:GetCoalitionName() local DCSIdentifiable = self:GetDCSObject() if DCSIdentifiable then + + -- Get coaliton ID. local IdentifiableCoalition = DCSIdentifiable:getCoalition() self:T3( IdentifiableCoalition ) - if IdentifiableCoalition == coalition.side.BLUE then - return "Blue" - end + return UTILS.GetCoalitionName(IdentifiableCoalition) - if IdentifiableCoalition == coalition.side.RED then - return "Red" - end - - if IdentifiableCoalition == coalition.side.NEUTRAL then - return "Neutral" - end end self:F( self.ClassName .. " " .. self.IdentifiableName .. " not found!" )