From 37d2c729451a1a3ad8133c3a5a508adc69c1bbd3 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Thu, 2 Dec 2021 10:13:38 +0100 Subject: [PATCH] MANTIS - added variable ranges for short, med and long range systems. Altered engage range to 95% and shoradactivation to 25km as defaults AUFTRAG/CHIEF/OPSGROUP - added Auftrag type ARMOREDGUARD to have an ONGUARD mission for tanks w/o triggering transport by CHIEF Made classes around CHIEF & AIRBOSS a bit less noisy as it kills my logfile --- Moose Development/Moose/Functional/Mantis.lua | 54 +++++++++++-------- Moose Development/Moose/Ops/Airboss.lua | 42 +++++++-------- Moose Development/Moose/Ops/Auftrag.lua | 38 +++++++++++-- Moose Development/Moose/Ops/Chief.lua | 51 +++++++++++++----- Moose Development/Moose/Ops/Cohort.lua | 12 ++--- Moose Development/Moose/Ops/Commander.lua | 18 +++---- Moose Development/Moose/Ops/FlightGroup.lua | 24 ++++----- Moose Development/Moose/Ops/Legion.lua | 14 ++--- Moose Development/Moose/Ops/OpsGroup.lua | 14 ++--- Moose Development/Moose/Ops/Platoon.lua | 2 +- 10 files changed, 169 insertions(+), 100 deletions(-) diff --git a/Moose Development/Moose/Functional/Mantis.lua b/Moose Development/Moose/Functional/Mantis.lua index ea776ef49..9162df5bb 100644 --- a/Moose Development/Moose/Functional/Mantis.lua +++ b/Moose Development/Moose/Functional/Mantis.lua @@ -20,7 +20,7 @@ -- @module Functional.Mantis -- @image Functional.Mantis.jpg -- --- Date: Nov 2021 +-- Date: Dec 2021 ------------------------------------------------------------------------- --- **MANTIS** class, extends Core.Base#BASE @@ -194,9 +194,11 @@ -- -- switch off auto shorad **before** you start MANTIS. -- `mybluemantis.autoshorad = false` -- --- -- scale of the activation range, i.e. don't activate at the fringes of max range, default 90%. +-- -- scale of the activation range, i.e. don't activate at the fringes of max range, defaults below. -- -- also see engagerange below. --- `mybluemantis.radiusscale = 0.9` +-- ` self.radiusscale[MANTIS.SamType.LONG] = 1.1` +-- ` self.radiusscale[MANTIS.SamType.MEDIUM] = 1.2` +-- ` self.radiusscale[MANTIS.SamType.SHORT] = 1.3` -- -- # 3. Default settings [both modes unless stated otherwise] -- @@ -207,7 +209,7 @@ -- * [classic mode] checkradius = 25000 (meters) - SAMs will engage enemy flights, if they are within a 25km around each SAM site - `MANTIS:SetSAMRadius(radius)` -- * grouping = 5000 (meters) - Detection (EWR) will group enemy flights to areas of 5km for tracking - `MANTIS:SetEWRGrouping(radius)` -- * detectinterval = 30 (seconds) - MANTIS will decide every 30 seconds which SAM to activate - `MANTIS:SetDetectInterval(interval)` --- * engagerange = 85 (percent) - SAMs will only fire if flights are inside of a 85% radius of their max firerange - `MANTIS:SetSAMRange(range)` +-- * engagerange = 95 (percent) - SAMs will only fire if flights are inside of a 95% radius of their max firerange - `MANTIS:SetSAMRange(range)` -- * dynamic = false - Group filtering is set to once, i.e. newly added groups will not be part of the setup by default - `MANTIS:New(name,samprefix,ewrprefix,hq,coaltion,dynamic)` -- * autorelocate = false - HQ and (mobile) EWR system will not relocate in random intervals between 30mins and 1 hour - `MANTIS:SetAutoRelocate(hq, ewr)` -- * debug = false - Debugging reports on screen are set to off - `MANTIS:Debug(onoff)` @@ -284,7 +286,7 @@ MANTIS = { grouping = 5000, acceptrange = 80000, detectinterval = 30, - engagerange = 75, + engagerange = 95, autorelocate = false, advanced = false, adv_ratio = 100, @@ -296,7 +298,7 @@ MANTIS = { Shorad = nil, ShoradLink = false, ShoradTime = 600, - ShoradActDistance = 15000, + ShoradActDistance = 25000, UseEmOnOff = false, TimeStamp = 0, state2flag = false, @@ -440,7 +442,7 @@ do self.grouping = 5000 self.acceptrange = 80000 self.detectinterval = 30 - self.engagerange = 85 + self.engagerange = 95 self.autorelocate = false self.autorelocateunits = { HQ = false, EWR = false} self.advanced = false @@ -453,7 +455,7 @@ do self.Shorad = nil self.ShoradLink = false self.ShoradTime = 600 - self.ShoradActDistance = 15000 + self.ShoradActDistance = 25000 self.TimeStamp = timer.getAbsTime() self.relointerval = math.random(1800,3600) -- random between 30 and 60 mins self.state2flag = false @@ -463,8 +465,11 @@ do self.SuppressedGroups = {} -- 0.8 additions self.automode = true - self.radiusscale = 0.9 - self.SAMCheckRanges = {} + self.radiusscale = {} + self.radiusscale[MANTIS.SamType.LONG] = 1.1 + self.radiusscale[MANTIS.SamType.MEDIUM] = 1.2 + self.radiusscale[MANTIS.SamType.SHORT] = 1.3 + --self.SAMCheckRanges = {} self.usezones = false self.AcceptZones = {} self.RejectZones = {} @@ -540,9 +545,10 @@ do if self.HQ_Template_CC then self.HQ_CC = GROUP:FindByName(self.HQ_Template_CC) end - + + -- TODO Version -- @field #string version - self.version="0.8.7" + self.version="0.8.8" self:I(string.format("***** Starting MANTIS Version %s *****", self.version)) --- FSM Functions --- @@ -753,9 +759,9 @@ do -- @param #number range Percent of the max fire range function MANTIS:SetSAMRange(range) self:T(self.lid .. "SetSAMRange") - local range = range or 85 + local range = range or 95 if range < 0 or range > 100 then - range = 85 + range = 95 end self.engagerange = range return self @@ -782,9 +788,9 @@ do -- @param #number range Percent of the max fire range function MANTIS:SetNewSAMRangeWhileRunning(range) self:T(self.lid .. "SetNewSAMRangeWhileRunning") - local range = range or 75 + local range = range or 95 if range < 0 or range > 100 then - range = 75 + range = 95 end self.engagerange = range self:_RefreshSAMTable() @@ -1272,6 +1278,7 @@ do local range = self.checkradius local height = 3000 local type = MANTIS.SamType.MEDIUM + local radiusscale = self.radiusscale[type] local blind = 0 local group = GROUP:FindByName(grpname) -- Wrapper.Group#GROUP local units = group:GetUnits() @@ -1289,9 +1296,10 @@ do local _radar = string.lower(_entry.Radar) --self:I(string.format("Trying typename: %s",_radar)) if string.find(type,_radar,1,true) then - range = _entry.Range * 1000 * self.radiusscale -- max firing range - height = _entry.Height * 1000 -- max firing height type = _entry.Type + radiusscale = self.radiusscale[type] + range = _entry.Range * 1000 * radiusscale -- max firing range used as switch-on + height = _entry.Height * 1000 -- max firing height blind = _entry.Blindspot * 100 -- blind spot range --self:I(string.format("Match: %s - %s",_radar,type)) found = true @@ -1318,6 +1326,7 @@ do local range = self.checkradius local height = 3000 local type = MANTIS.SamType.MEDIUM + local radiusscale = self.radiusscale[type] local blind = 0 local found = false local HDSmod = false @@ -1329,9 +1338,10 @@ do --self:I("ID = " .. idx) if string.find(grpname,idx,1,true) then local _entry = entry -- #MANTIS.SamData - range = _entry.Range * 1000 * self.radiusscale -- max firing range - height = _entry.Height * 1000 -- max firing height type = _entry.Type + radiusscale = self.radiusscale[type] + range = _entry.Range * 1000 * radiusscale -- max firing range + height = _entry.Height * 1000 -- max firing height blind = _entry.Blindspot --self:I("Matching Groupname = " .. grpname .. " Range= " .. range) found = true @@ -1376,7 +1386,7 @@ do else group:OptionAlarmStateGreen() -- AI off end - group:OptionEngageRange(engagerange) --default engagement will be 85% of firing range + group:OptionEngageRange(engagerange) --default engagement will be 95% of firing range local grpname = group:GetName() local grpcoord = group:GetCoordinate() local grprange,grpheight,type,blind = self:_GetSAMRange(grpname) @@ -1434,7 +1444,7 @@ do --cycle through groups and set alarm state etc for _i,_group in pairs (SAM_Grps) do local group = _group -- Wrapper.Group#GROUP - group:OptionEngageRange(engagerange) --engagement will be 85% of firing range + group:OptionEngageRange(engagerange) --engagement will be 95% of firing range if group:IsGround() and group:IsAlive() then local grpname = group:GetName() local grpcoord = group:GetCoordinate() diff --git a/Moose Development/Moose/Ops/Airboss.lua b/Moose Development/Moose/Ops/Airboss.lua index d720e8803..1e0de67c9 100644 --- a/Moose Development/Moose/Ops/Airboss.lua +++ b/Moose Development/Moose/Ops/Airboss.lua @@ -2629,7 +2629,7 @@ function AIRBOSS:DeleteAllRecoveryWindows(delay) -- Loop over all recovery windows. for _,recovery in pairs(self.recoverytimes) do - self:I(self.lid..string.format("Deleting recovery window ID %s", tostring(recovery.ID))) + self:T(self.lid..string.format("Deleting recovery window ID %s", tostring(recovery.ID))) self:DeleteRecoveryWindow(recovery, delay) end @@ -3126,7 +3126,7 @@ function AIRBOSS:SoundCheckLSO(delay) end -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) end end @@ -3162,7 +3162,7 @@ function AIRBOSS:SoundCheckMarshal(delay) end -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) end end @@ -3542,7 +3542,7 @@ function AIRBOSS:onafterStatus(From, Event, To) if i==0 then text=text.." none" end - self:I(self.lid..text) + self:T(self.lid..text) -- Check for collision. if collision then @@ -4202,7 +4202,7 @@ end -- @param #number n Number of waypoint that was passed. function AIRBOSS:onafterPassingWaypoint(From, Event, To, n) -- Debug output. - self:I(self.lid..string.format("Carrier passed waypoint %d.", n)) + self:T(self.lid..string.format("Carrier passed waypoint %d.", n)) end --- On after "Idle" event. Carrier goes to state "Idle". @@ -4221,7 +4221,7 @@ end -- @param #string Event Event. -- @param #string To To state. function AIRBOSS:onafterStop(From, Event, To) - self:I(self.lid..string.format("Stopping airboss script.")) + self:T(self.lid..string.format("Stopping airboss script.")) -- Unhandle events. self:UnHandleEvent(EVENTS.Birth) @@ -7375,7 +7375,7 @@ function AIRBOSS:_GetFreeStack(ai, case, empty) end - self:I(self.lid..string.format("Returning free stack %s", tostring(nfree))) + self:T(self.lid..string.format("Returning free stack %s", tostring(nfree))) return nfree end @@ -8314,7 +8314,7 @@ function AIRBOSS:_RemoveFlight(flight, completely) -- Remove player from players table. local playerdata=self.players[flight.name] if playerdata then - self:I(self.lid..string.format("Removing player %s completely.", flight.name)) + self:T(self.lid..string.format("Removing player %s completely.", flight.name)) self.players[flight.name]=nil end @@ -13953,7 +13953,7 @@ function AIRBOSS:CarrierTurnIntoWind(time, vdeck, uturn) local distNM=UTILS.MetersToNM(dist) -- Debug output - self:I(self.lid..string.format("Carrier steaming into the wind (%.1f kts). Distance=%.1f NM, Speed=%.1f knots, Time=%d sec.", UTILS.MpsToKnots(vwind), distNM, speedknots, time)) + self:T(self.lid..string.format("Carrier steaming into the wind (%.1f kts). Distance=%.1f NM, Speed=%.1f knots, Time=%d sec.", UTILS.MpsToKnots(vwind), distNM, speedknots, time)) -- Get heading into the wind accounting for angled runway. local hiw=self:GetHeadingIntoWind() @@ -15817,7 +15817,7 @@ function AIRBOSS:_MarshallInboundCall(unit, modex) -- Pilot: "Marshall, [modex], marking mom's [bearing] for [distance], angels [XX], state [X.X]" local text=string.format("Marshal, %s, marking mom's %d for %d, angels %d, state %.1f", modex, bearing, distance, angels, state) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Fuel state. local FS=UTILS.Split(string.format("%.1f", state), ".") @@ -15865,7 +15865,7 @@ function AIRBOSS:_CommencingCall(unit, modex) -- Pilot: "[modex], commencing" local text=string.format("%s, commencing", modex) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call to display complete subtitle. local commencingCall=self:_NewRadioCall(self.MarshalCall.CLICK, unit.UnitName:upper() , text, self.Tmessage, nil, unit.UnitName:upper()) @@ -15892,7 +15892,7 @@ function AIRBOSS:_LSOCallAircraftBall(modex, nickname, fuelstate) local text=string.format("%s Ball, %.1f.", nickname, fuelstate) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Nickname UPPERCASE. local NICKNAME=nickname:upper() @@ -15928,7 +15928,7 @@ function AIRBOSS:_MarshalCallGasAtTanker(modex) local text=string.format("Bingo fuel! Going for gas at the recovery tanker.") -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call to display complete subtitle. local call=self:_NewRadioCall(self.PilotCall.BINGOFUEL, modex, text, self.Tmessage, nil, modex) @@ -15951,7 +15951,7 @@ function AIRBOSS:_MarshalCallGasAtDivert(modex, divertname) local text=string.format("Bingo fuel! Going for gas at divert field %s.", divertname) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call to display complete subtitle. local call=self:_NewRadioCall(self.PilotCall.BINGOFUEL, modex, text, self.Tmessage, nil, modex) @@ -15974,7 +15974,7 @@ function AIRBOSS:_MarshalCallRecoveryStopped(case) local text=string.format("Case %d recovery ops are stopped. Deck is closed.", case) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call to display complete subtitle. local call=self:_NewRadioCall(self.MarshalCall.CASE, "AIRBOSS", text, self.Tmessage, "99") @@ -16015,7 +16015,7 @@ function AIRBOSS:_MarshalCallRecoveryPausedResumedAt(clock) local text=string.format("aircraft recovery is paused and will be resumed at %s.", clock) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call with full subtitle. local call=self:_NewRadioCall(self.MarshalCall.RECOVERYPAUSEDRESUMED, "AIRBOSS", text, self.Tmessage, "99") @@ -16043,7 +16043,7 @@ function AIRBOSS:_MarshalCallClearedForRecovery(modex, case) local text=string.format("you're cleared for Case %d recovery.", case) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call with full subtitle. local call=self:_NewRadioCall(self.MarshalCall.CLEAREDFORRECOVERY, "MARSHAL", text, self.Tmessage, modex) @@ -16081,7 +16081,7 @@ function AIRBOSS:_MarshalCallNewFinalBearing(FB) local text=string.format("new final bearing %03d°.", FB) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call with full subtitle. local call=self:_NewRadioCall(self.MarshalCall.NEWFB, "AIRBOSS", text, self.Tmessage, "99") @@ -16104,7 +16104,7 @@ function AIRBOSS:_MarshalCallCarrierTurnTo(hdg) local text=string.format("carrier is now starting turn to heading %03d°.", hdg) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call with full subtitle. local call=self:_NewRadioCall(self.MarshalCall.CARRIERTURNTOHEADING, "AIRBOSS", text, self.Tmessage, "99") @@ -16135,7 +16135,7 @@ function AIRBOSS:_MarshalCallStackFull(modex, nwaiting) end -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call with full subtitle. local call=self:_NewRadioCall(self.MarshalCall.STACKFULL, "AIRBOSS", text, self.Tmessage, modex) @@ -16206,7 +16206,7 @@ function AIRBOSS:_MarshalCallArrived(modex, case, brc, altitude, charlie, qfe) local text=string.format("Case %d, expected BRC %03d°, hold at angels %d. Expected Charlie Time %s. Altimeter %.2f. Report see me.", case, brc, angels, charlie, qfe) -- Debug message. - self:I(self.lid..text) + self:T(self.lid..text) -- Create new call to display complete subtitle. local casecall=self:_NewRadioCall(self.MarshalCall.CASE, "MARSHAL", text, self.Tmessage, modex) diff --git a/Moose Development/Moose/Ops/Auftrag.lua b/Moose Development/Moose/Ops/Auftrag.lua index dd704f932..278023032 100644 --- a/Moose Development/Moose/Ops/Auftrag.lua +++ b/Moose Development/Moose/Ops/Auftrag.lua @@ -380,6 +380,7 @@ _AUFTRAGSNR=0 -- @field #string FUELSUPPLY Fuel supply. -- @field #string ALERT5 Alert 5. -- @field #string ONGUARD On guard. +-- @field #string ARMOREDGUARD On guard - with armored groups. -- @field #string BARRAGE Barrage. -- @field #STRING ARMORATTACK Armor attack. AUFTRAG.Type={ @@ -411,6 +412,7 @@ AUFTRAG.Type={ FUELSUPPLY="Fuel Supply", ALERT5="Alert5", ONGUARD="On Guard", + ARMOREDGUARD="Armored Guard", BARRAGE="Barrage", ARMORATTACK="Armor Attack", } @@ -423,6 +425,7 @@ AUFTRAG.Type={ -- @field #string FUELSUPPLY Fuel Supply. -- @field #string ALERT5 Alert 5 task. -- @field #string ONGUARD On guard. +-- @field #string ARMOREDGUARD On guard with armor. -- @field #string BARRAGE Barrage. AUFTRAG.SpecialTask={ PATROLZONE="PatrolZone", @@ -431,6 +434,7 @@ AUFTRAG.SpecialTask={ FUELSUPPLY="Fuel Supply", ALERT5="Alert5", ONGUARD="On Guard", + ARMOREDGUARD="ArmoredGuard", BARRAGE="Barrage", ARMORATTACK="AmorAttack", } @@ -1686,7 +1690,7 @@ function AUFTRAG:NewARMORATTACK(Target, Speed, Formation) mission.optionROE=ENUMS.ROE.OpenFire mission.optionAlarm=ENUMS.AlarmState.Auto - mission.optionFormation="On Road" + mission.optionFormation="Off Road" mission.optionAttackFormation=Formation or "Wedge" mission.missionFraction=1.0 @@ -1826,6 +1830,30 @@ function AUFTRAG:NewONGUARD(Coordinate) return mission end +--- **[GROUND]** Create an ARMORED ON GUARD mission. +-- @param #AUFTRAG self +-- @param Core.Point#COORDINATE Coordinate Coordinate, where to stand guard. +-- @param #string Formation Formation to take, e.g. "on Road", "Vee" etc. +-- @return #AUFTRAG self +function AUFTRAG:NewARMOREDGUARD(Coordinate,Formation) + + local mission=AUFTRAG:New(AUFTRAG.Type.ARMOREDGUARD) + + mission:_TargetFromObject(Coordinate) + + mission.optionROE=ENUMS.ROE.OpenFire + mission.optionAlarm=ENUMS.AlarmState.Auto + mission.optionFormation=Formation or "On Road" + --mission.optionAttackFormation=Formation or "Wedge" + + mission.missionFraction=1.0 + + mission.categories={AUFTRAG.Category.GROUND} + + mission.DCStask=mission:GetDCSMissionTask() + + return mission +end --- Create a mission to attack a TARGET object. -- @param #AUFTRAG self @@ -1921,6 +1949,10 @@ function AUFTRAG:_DetermineAuftragType(Target) elseif attribute==GROUP.Attribute.GROUND_INFANTRY then + auftrag=AUFTRAG.Type.CAS + + elseif attribute==GROUP.Attribute.GROUND_TANK then + auftrag=AUFTRAG.Type.BAI else @@ -4959,7 +4991,7 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) table.insert(DCStasks, DCStask) - elseif self.type==AUFTRAG.Type.ONGUARD then + elseif self.type==AUFTRAG.Type.ONGUARD or self.type==AUFTRAG.Type.ARMOREDGUARD then ---------------------- -- ON GUARD Mission -- @@ -4967,7 +4999,7 @@ function AUFTRAG:GetDCSMissionTask(TaskControllable) local DCStask={} - DCStask.id=AUFTRAG.SpecialTask.ONGUARD + DCStask.id= self.type==AUFTRAG.Type.ONGUARD and AUFTRAG.SpecialTask.ONGUARD or AUFTRAG.SpecialTask.ARMOREDGUARD -- We create a "fake" DCS task and pass the parameters to the OPSGROUP. local param={} diff --git a/Moose Development/Moose/Ops/Chief.lua b/Moose Development/Moose/Ops/Chief.lua index e0059c9cb..d37fd5fc0 100644 --- a/Moose Development/Moose/Ops/Chief.lua +++ b/Moose Development/Moose/Ops/Chief.lua @@ -764,7 +764,7 @@ function CHIEF:RemoveTarget(Target) local target=_target --Ops.Target#TARGET if target.uid==Target.uid then - self:I(self.lid..string.format("Removing target %s from queue", Target.name)) + self:T(self.lid..string.format("Removing target %s from queue", Target.name)) table.remove(self.targetqueue, i) break end @@ -1077,7 +1077,7 @@ function CHIEF:onafterStatus(From, Event, To) -- Debug info. local text=string.format("Lost contact to target %s! %s mission %s will be cancelled.", contact.groupname, contact.mission.type:upper(), contact.mission.name) MESSAGE:New(text, 120, "CHIEF"):ToAll() - self:I(self.lid..text) + self:T(self.lid..text) -- Cancel this mission. contact.mission:Cancel() @@ -1283,7 +1283,7 @@ function CHIEF:onafterStatus(From, Event, To) text=text..string.format("\n- %s: %d", attribute, N) end end - self:I(self.lid..text) + self:T(self.lid..text) end end @@ -1302,7 +1302,7 @@ end function CHIEF:onafterMissionAssign(From, Event, To, Mission, Legions) if self.commander then - self:I(self.lid..string.format("Assigning mission %s (%s) to COMMANDER", Mission.name, Mission.type)) + self:T(self.lid..string.format("Assigning mission %s (%s) to COMMANDER", Mission.name, Mission.type)) Mission.chief=self Mission.statusChief=AUFTRAG.Status.QUEUED self.commander:MissionAssign(Mission, Legions) @@ -1321,7 +1321,7 @@ end function CHIEF:onafterMissionCancel(From, Event, To, Mission) -- Debug info. - self:I(self.lid..string.format("Cancelling mission %s (%s) in status %s", Mission.name, Mission.type, Mission.status)) + self:T(self.lid..string.format("Cancelling mission %s (%s) in status %s", Mission.name, Mission.type, Mission.status)) -- Set status to CANCELLED. Mission.statusChief=AUFTRAG.Status.CANCELLED @@ -1351,7 +1351,7 @@ end function CHIEF:onafterTransportCancel(From, Event, To, Transport) -- Debug info. - self:I(self.lid..string.format("Cancelling transport UID=%d in status %s", Transport.uid, Transport:GetState())) + self:T(self.lid..string.format("Cancelling transport UID=%d in status %s", Transport.uid, Transport:GetState())) if Transport:IsPlanned() then @@ -1376,7 +1376,7 @@ end -- @param #string To To state. -- @param #string Defcon New defence condition. function CHIEF:onafterDefconChange(From, Event, To, Defcon) - self:I(self.lid..string.format("Changing Defcon from %s --> %s", self.Defcon, Defcon)) + self:T(self.lid..string.format("Changing Defcon from %s --> %s", self.Defcon, Defcon)) end --- On after "StrategyChange" event. @@ -1386,7 +1386,7 @@ end -- @param #string To To state. -- @param #string Strategy function CHIEF:onafterStrategyChange(From, Event, To, Strategy) - self:I(self.lid..string.format("Changing Strategy from %s --> %s", self.strategy, Strategy)) + self:T(self.lid..string.format("Changing Strategy from %s --> %s", self.strategy, Strategy)) end --- On after "OpsOnMission". @@ -1574,7 +1574,7 @@ function CHIEF:CheckTargetQueue() if valid then -- Debug info. - self:I(self.lid..string.format("Got valid target %s: category=%s, threatlevel=%d", target:GetName(), target.category, threatlevel)) + self:T(self.lid..string.format("Got valid target %s: category=%s, threatlevel=%d", target:GetName(), target.category, threatlevel)) -- Get mission performances for the given target. local MissionPerformances=self:_GetMissionPerformanceFromTarget(target) @@ -1711,7 +1711,7 @@ function CHIEF:CheckOpsZoneQueue() if ownercoalition~=self.coalition and (stratzone.importance==nil or stratzone.importance<=vip) then -- Has a patrol mission? - local hasMissionPatrol=stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.ONGUARD) + local hasMissionPatrol=stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.ONGUARD) or stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.ARMOREDGUARD) -- Has a CAS mission? local hasMissionCAS=stratzone.opszone:_FindMissions(self.coalition,AUFTRAG.Type.CAS) -- Has a ARTY mission? @@ -1735,10 +1735,11 @@ function CHIEF:CheckOpsZoneQueue() -- Recruit ground assets that local recruited=self:RecruitAssetsForZone(stratzone, AUFTRAG.Type.ONGUARD, 1, 3, {Group.Category.GROUND}, {GROUP.Attribute.GROUND_INFANTRY, GROUP.Attribute.GROUND_TANK}) - + local recruited1=self:RecruitAssetsForZone(stratzone, AUFTRAG.Type.ARMOREDGUARD, 1, 1, {Group.Category.GROUND}, {GROUP.Attribute.GROUND_TANK}) + -- Debug info. self:T(self.lid..string.format("Zone is empty ==> Recruit Patrol zone infantry assets=%s", tostring(recruited))) - + self:T(self.lid..string.format("Zone is empty ==> Recruit Patrol zone armored assets=%s", tostring(recruited1))) end else @@ -2168,6 +2169,11 @@ function CHIEF:RecruitAssetsForZone(StratZone, MissionType, NassetsMin, NassetsM if MissionType==AUFTRAG.Type.PATROLZONE or MissionType==AUFTRAG.Type.ONGUARD then RangeMax=UTILS.NMToMeters(250) end + + -- Set max range to 50 NM because we use armor + if MissionType==AUFTRAG.Type.ARMOREDGUARD then + RangeMax=UTILS.NMToMeters(50) + end -- Recruite infantry assets. local recruited, assets, legions=LEGION.RecruitCohortAssets(Cohorts, MissionType, nil, NassetsMin, NassetsMax, TargetVec2, nil, RangeMax, nil, nil, Categories, Attributes) @@ -2274,6 +2280,27 @@ function CHIEF:RecruitAssetsForZone(StratZone, MissionType, NassetsMin, NassetsM StratZone.opszone:_AddMission(self.coalition,MissionType,mission) return true + elseif MissionType==AUFTRAG.Type.ARMOREDGUARD then + + -- Create Armored on guard mission + local TargetZone = StratZone.opszone.zone + local Target = TargetZone:GetCoordinate() + local mission=AUFTRAG:NewARMOREDGUARD(Target) + + -- Add assets to mission. + for _,asset in pairs(assets) do + mission:AddAsset(asset) + end + + -- Assign mission to legions. + self:MissionAssign(mission, legions) + + -- Attach mission to ops zone. + -- TODO: Need a better way! + --StratZone.missionARTY=mission + StratZone.opszone:_AddMission(self.coalition,MissionType,mission) + + return true end end diff --git a/Moose Development/Moose/Ops/Cohort.lua b/Moose Development/Moose/Ops/Cohort.lua index 3dde5b505..e7b6c7b4e 100644 --- a/Moose Development/Moose/Ops/Cohort.lua +++ b/Moose Development/Moose/Ops/Cohort.lua @@ -705,7 +705,7 @@ function COHORT:_CheckAssetStatus() end end - self:I(self.lid..text) + self:T(self.lid..text) end end @@ -718,7 +718,7 @@ end function COHORT:onafterStop(From, Event, To) -- Debug info. - self:I(self.lid.."STOPPING Cohort and removing all assets!") + self:T(self.lid.."STOPPING Cohort and removing all assets!") -- Remove all assets. for i=#self.assets,1,-1 do @@ -776,7 +776,7 @@ function COHORT:CanMission(Mission) -- Set range is valid. Mission engage distance can overrule the cohort engage range. if TargetDistance>engagerange then - self:I(self.lid..string.format("INFO: Cohort is not in range. Target dist=%d > %d NM max mission Range", UTILS.MetersToNM(TargetDistance), UTILS.MetersToNM(engagerange))) + self:T(self.lid..string.format("INFO: Cohort is not in range. Target dist=%d > %d NM max mission Range", UTILS.MetersToNM(TargetDistance), UTILS.MetersToNM(engagerange))) return false end @@ -847,13 +847,13 @@ function COHORT:RecruitAssets(MissionType, Npayloads) -- Check if the payload of this asset is compatible with the mission. -- Note: we do not check the payload as an asset that is on a GCICAP mission should be able to do an INTERCEPT as well! - self:I(self.lid..string.format("Adding asset on GCICAP mission for an INTERCEPT mission")) + self:T(self.lid..string.format("Adding asset on GCICAP mission for an INTERCEPT mission")) table.insert(assets, asset) elseif self.legion:IsAssetOnMission(asset, AUFTRAG.Type.ALERT5) and AUFTRAG.CheckMissionCapability(MissionType, asset.payload.capabilities) then -- Check if the payload of this asset is compatible with the mission. - self:I(self.lid..string.format("Adding asset on ALERT 5 mission for %s mission", MissionType)) + self:T(self.lid..string.format("Adding asset on ALERT 5 mission for %s mission", MissionType)) table.insert(assets, asset) end @@ -932,7 +932,7 @@ function COHORT:RecruitAssets(MissionType, Npayloads) -- This asset is "combatready". if combatready then - self:I(self.lid.."Adding SPAWNED asset to ANOTHER mission as it is COMBATREADY") + self:T(self.lid.."Adding SPAWNED asset to ANOTHER mission as it is COMBATREADY") table.insert(assets, asset) end diff --git a/Moose Development/Moose/Ops/Commander.lua b/Moose Development/Moose/Ops/Commander.lua index ad61ca2e2..4645c307b 100644 --- a/Moose Development/Moose/Ops/Commander.lua +++ b/Moose Development/Moose/Ops/Commander.lua @@ -449,7 +449,7 @@ function COMMANDER:RemoveMission(Mission) local mission=_mission --Ops.Auftrag#AUFTRAG if mission.auftragsnummer==Mission.auftragsnummer then - self:I(self.lid..string.format("Removing mission %s (%s) status=%s from queue", Mission.name, Mission.type, Mission.status)) + self:T(self.lid..string.format("Removing mission %s (%s) status=%s from queue", Mission.name, Mission.type, Mission.status)) mission.commander=nil table.remove(self.missionqueue, i) break @@ -470,7 +470,7 @@ function COMMANDER:RemoveTransport(Transport) local transport=_transport --Ops.OpsTransport#OPSTRANSPORT if transport.uid==Transport.uid then - self:I(self.lid..string.format("Removing transport UID=%d status=%s from queue", transport.uid, transport:GetState())) + self:T(self.lid..string.format("Removing transport UID=%d status=%s from queue", transport.uid, transport:GetState())) transport.commander=nil table.remove(self.transportqueue, i) break @@ -674,7 +674,7 @@ function COMMANDER:onafterStatus(From, Event, To) -- Status. if self.verbose>=1 then local text=string.format("Status %s: Legions=%d, Missions=%d, Transports", fsmstate, #self.legions, #self.missionqueue, #self.transportqueue) - self:I(self.lid..text) + self:T(self.lid..text) end -- Check mission queue and assign one PLANNED mission. @@ -769,7 +769,7 @@ function COMMANDER:onafterStatus(From, Event, To) end end end - self:I(self.lid..text) + self:T(self.lid..text) if self.verbose>=3 then @@ -905,7 +905,7 @@ function COMMANDER:onafterMissionAssign(From, Event, To, Mission, Legions) local Legion=_Legion --Ops.Legion#LEGION -- Debug info. - self:I(self.lid..string.format("Assigning mission \"%s\" [%s] to legion \"%s\"", Mission.name, Mission.type, Legion.alias)) + self:T(self.lid..string.format("Assigning mission \"%s\" [%s] to legion \"%s\"", Mission.name, Mission.type, Legion.alias)) -- Add mission to legion. Legion:AddMission(Mission) @@ -926,7 +926,7 @@ end function COMMANDER:onafterMissionCancel(From, Event, To, Mission) -- Debug info. - self:I(self.lid..string.format("Cancelling mission \"%s\" [%s] in status %s", Mission.name, Mission.type, Mission.status)) + self:T(self.lid..string.format("Cancelling mission \"%s\" [%s] in status %s", Mission.name, Mission.type, Mission.status)) -- Set commander status. Mission.statusCommander=AUFTRAG.Status.CANCELLED @@ -970,7 +970,7 @@ function COMMANDER:onafterTransportAssign(From, Event, To, Transport, Legions) local Legion=_Legion --Ops.Legion#LEGION -- Debug info. - self:I(self.lid..string.format("Assigning transport UID=%d to legion \"%s\"", Transport.uid, Legion.alias)) + self:T(self.lid..string.format("Assigning transport UID=%d to legion \"%s\"", Transport.uid, Legion.alias)) -- Add mission to legion. Legion:AddOpsTransport(Transport) @@ -991,7 +991,7 @@ end function COMMANDER:onafterTransportCancel(From, Event, To, Transport) -- Debug info. - self:I(self.lid..string.format("Cancelling Transport UID=%d in status %s", Transport.uid, Transport:GetState())) + self:T(self.lid..string.format("Cancelling Transport UID=%d in status %s", Transport.uid, Transport:GetState())) -- Set commander status. Transport.statusCommander=OPSTRANSPORT.Status.CANCELLED @@ -1479,7 +1479,7 @@ function COMMANDER:GetLegionsForMission(Mission) local dist=UTILS.Round(distance/10, 0) -- Debug info. - self:I(self.lid..string.format("Got legion %s with Nassets=%d and dist=%.1f NM, rounded=%.1f", legion.alias, Nassets, distance, dist)) + self:T(self.lid..string.format("Got legion %s with Nassets=%d and dist=%.1f NM, rounded=%.1f", legion.alias, Nassets, distance, dist)) -- Add legion to table of legions that can. table.insert(legions, {airwing=legion, distance=distance, dist=dist, targetcoord=coord, nassets=Nassets}) diff --git a/Moose Development/Moose/Ops/FlightGroup.lua b/Moose Development/Moose/Ops/FlightGroup.lua index 184438f90..92aa167f5 100644 --- a/Moose Development/Moose/Ops/FlightGroup.lua +++ b/Moose Development/Moose/Ops/FlightGroup.lua @@ -360,7 +360,7 @@ function FLIGHTGROUP:SetFlightControl(flightcontrol) end -- Set FC. - self:I(self.lid..string.format("Setting FLIGHTCONTROL to airbase %s", flightcontrol.airbasename)) + self:T(self.lid..string.format("Setting FLIGHTCONTROL to airbase %s", flightcontrol.airbasename)) self.flightcontrol=flightcontrol -- Add flight to all flights. @@ -1014,7 +1014,7 @@ function FLIGHTGROUP:Status() -- If we found a group, we engage it. if targetgroup then - self:I(self.lid..string.format("Engaging target group %s at distance %d meters", targetgroup:GetName(), targetdist)) + self:T(self.lid..string.format("Engaging target group %s at distance %d meters", targetgroup:GetName(), targetdist)) self:EngageTarget(targetgroup) end @@ -1160,7 +1160,7 @@ function FLIGHTGROUP:OnEventEngineShutdown(EventData) end else - --self:I(self.lid..string.format("EVENT: Element %s shut down engines but is NOT alive ==> waiting for crash event (==> dead)", element.name)) + --self:T(self.lid..string.format("EVENT: Element %s shut down engines but is NOT alive ==> waiting for crash event (==> dead)", element.name)) end end -- element nil? @@ -2061,7 +2061,7 @@ end -- @param #string Event Event. -- @param #string To To state. function FLIGHTGROUP:onafterOutOfMissilesAA(From, Event, To) - self:I(self.lid.."Group is out of AA Missiles!") + self:T(self.lid.."Group is out of AA Missiles!") if self.outofAAMrtb then -- Back to destination or home. local airbase=self.destbase or self.homebase @@ -2075,7 +2075,7 @@ end -- @param #string Event Event. -- @param #string To To state. function FLIGHTGROUP:onafterOutOfMissilesAG(From, Event, To) - self:I(self.lid.."Group is out of AG Missiles!") + self:T(self.lid.."Group is out of AG Missiles!") if self.outofAGMrtb then -- Back to destination or home. local airbase=self.destbase or self.homebase @@ -2660,7 +2660,7 @@ function FLIGHTGROUP:onafterRefuel(From, Event, To, Coordinate) -- Debug message. local text=string.format("Flight group set to refuel at the nearest tanker") - self:I(self.lid..text) + self:T(self.lid..text) --TODO: set ROE passive. introduce roe event/state/variable. --TODO: cancel current task @@ -2695,7 +2695,7 @@ function FLIGHTGROUP:onafterRefueled(From, Event, To) -- Debug message. local text=string.format("Flight group finished refuelling") - self:I(self.lid..text) + self:T(self.lid..text) -- Check if flight is done. self:_CheckGroupDone(1) @@ -2884,7 +2884,7 @@ function FLIGHTGROUP:onafterFuelLow(From, Event, To) -- Debug message. local text=string.format("Low fuel %d for flight group %s", fuel, self.groupname) - self:I(self.lid..text) + self:T(self.lid..text) -- Set switch to true. self.fuellow=true @@ -2900,7 +2900,7 @@ function FLIGHTGROUP:onafterFuelLow(From, Event, To) if tanker then -- Debug message. - self:I(self.lid..string.format("Send to refuel at tanker %s", tanker:GetName())) + self:T(self.lid..string.format("Send to refuel at tanker %s", tanker:GetName())) -- Get a coordinate towards the tanker. local coordinate=self:GetCoordinate():GetIntermediateCoordinate(tanker:GetCoordinate(), 0.75) @@ -2929,7 +2929,7 @@ function FLIGHTGROUP:onafterFuelCritical(From, Event, To) -- Debug message. local text=string.format("Critical fuel for flight group %s", self.groupname) - self:I(self.lid..text) + self:T(self.lid..text) -- Set switch to true. self.fuelcritical=true @@ -4017,11 +4017,11 @@ end function FLIGHTGROUP:_UpdateMenu(delay) if delay and delay>0 then - self:I(self.lid..string.format("FF updating menu in %.1f sec", delay)) + self:T(self.lid..string.format("FF updating menu in %.1f sec", delay)) self:ScheduleOnce(delay, FLIGHTGROUP._UpdateMenu, self) else - self:I(self.lid.."FF updating menu NOW") + self:T(self.lid.."FF updating menu NOW") -- Get current position of group. local position=self:GetCoordinate() diff --git a/Moose Development/Moose/Ops/Legion.lua b/Moose Development/Moose/Ops/Legion.lua index d85b696da..78ad12b77 100644 --- a/Moose Development/Moose/Ops/Legion.lua +++ b/Moose Development/Moose/Ops/Legion.lua @@ -627,7 +627,7 @@ function LEGION:onafterMissionAssign(From, Event, To, Mission, Legions) local Legion=_Legion --Ops.Legion#LEGION -- Debug info. - self:I(self.lid..string.format("Assigning mission %s (%s) to legion %s", Mission.name, Mission.type, Legion.alias)) + self:T(self.lid..string.format("Assigning mission %s (%s) to legion %s", Mission.name, Mission.type, Legion.alias)) -- Add mission to legion. Legion:AddMission(Mission) @@ -684,7 +684,7 @@ function LEGION:onafterMissionRequest(From, Event, To, Mission) -- Check if mission is INTERCEPT and asset is currently on GCI mission. If so, GCI is paused. if Mission.type==AUFTRAG.Type.INTERCEPT then if currM and currM.type==AUFTRAG.Type.GCICAP then - self:I(self.lid..string.format("Pausing %s mission %s to send flight on intercept mission %s", currM.type, currM.name, Mission.name)) + self:T(self.lid..string.format("Pausing %s mission %s to send flight on intercept mission %s", currM.type, currM.name, Mission.name)) asset.flightgroup:PauseMission() end end @@ -764,7 +764,7 @@ function LEGION:onafterTransportAssign(From, Event, To, Transport, Legions) local Legion=_Legion --Ops.Legion#LEGION -- Debug info. - self:I(self.lid..string.format("Assigning transport %d to legion %s", Transport.uid, Legion.alias)) + self:T(self.lid..string.format("Assigning transport %d to legion %s", Transport.uid, Legion.alias)) -- Add mission to legion. Legion:AddOpsTransport(Transport) @@ -837,7 +837,7 @@ end function LEGION:onafterTransportCancel(From, Event, To, Transport) -- Info message. - self:I(self.lid..string.format("Cancel transport UID=%d", Transport.uid)) + self:T(self.lid..string.format("Cancel transport UID=%d", Transport.uid)) -- Set status to cancelled. Transport:SetLegionStatus(self, OPSTRANSPORT.Status.CANCELLED) @@ -888,7 +888,7 @@ end function LEGION:onafterMissionCancel(From, Event, To, Mission) -- Info message. - self:I(self.lid..string.format("Cancel mission %s", Mission.name)) + self:T(self.lid..string.format("Cancel mission %s", Mission.name)) -- Set status to cancelled. Mission:SetLegionStatus(self, AUFTRAG.Status.CANCELLED) @@ -1235,7 +1235,7 @@ end function LEGION:onafterDestroyed(From, Event, To) -- Debug message. - self:I(self.lid.."Legion warehouse destroyed!") + self:T(self.lid.."Legion warehouse destroyed!") -- Cancel all missions. for _,_mission in pairs(self.missionqueue) do @@ -1845,7 +1845,7 @@ function LEGION:RecruitAssetsForEscort(Mission, Assets) if Mission.NescortMin and Mission.NescortMax and (Mission.NescortMin>0 or Mission.NescortMax>0) then -- Debug info. - self:I(self.lid..string.format("Requested escort for mission %s [%s]. Required assets=%d-%d", Mission:GetName(), Mission:GetType(), Mission.NescortMin,Mission.NescortMax)) + self:T(self.lid..string.format("Requested escort for mission %s [%s]. Required assets=%d-%d", Mission:GetName(), Mission:GetType(), Mission.NescortMin,Mission.NescortMax)) -- Get special escort legions and/or cohorts. local Cohorts={} diff --git a/Moose Development/Moose/Ops/OpsGroup.lua b/Moose Development/Moose/Ops/OpsGroup.lua index 1b753d2a6..001317a92 100644 --- a/Moose Development/Moose/Ops/OpsGroup.lua +++ b/Moose Development/Moose/Ops/OpsGroup.lua @@ -3645,7 +3645,7 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task) -- Just stay put on the airfield and wait until something happens. - elseif Task.dcstask.id==AUFTRAG.SpecialTask.ONGUARD then + elseif Task.dcstask.id==AUFTRAG.SpecialTask.ONGUARD or Task.dcstask.id==AUFTRAG.SpecialTask.ARMOREDGUARD then --- -- Task "On Guard" Mission. @@ -3678,7 +3678,7 @@ function OPSGROUP:onafterTaskExecute(From, Event, To, Task) local Alpha=param.angle or math.random(45, 85) local distance=Altitude/math.tan(math.rad(Alpha)) local tvec2=UTILS.Vec2Translate(vec2, distance, heading) - self:T(self.lid..string.format("Barrage: Shots=%s, Altitude=%d m, Angle=%d°, heading=%03d°, distance=%d m", tostring(param.shots), Altitude, Alpha, heading, distance)) + self:T(self.lid..string.format("Barrage: Shots=%s, Altitude=%d m, Angle=%d°, heading=%03d°, distance=%d m", tostring(param.shots), Altitude, Alpha, heading, distance)) DCSTask=CONTROLLABLE.TaskFireAtPoint(nil, tvec2, param.radius, param.shots, param.weaponType, Altitude) else DCSTask=Task.dcstask @@ -3776,7 +3776,7 @@ function OPSGROUP:onafterTaskCancel(From, Event, To, Task) done=true elseif Task.dcstask.id==AUFTRAG.SpecialTask.ALERT5 then done=true - elseif Task.dcstask.id==AUFTRAG.SpecialTask.ONGUARD then + elseif Task.dcstask.id==AUFTRAG.SpecialTask.ONGUARD or Task.dcstask.id==AUFTRAG.SpecialTask.ARMOREDGUARD then done=true elseif stopflag==1 or (not self:IsAlive()) or self:IsDead() or self:IsStopped() then -- Manual call TaskDone if setting flag to one was not successful. @@ -3879,7 +3879,7 @@ function OPSGROUP:onafterTaskDone(From, Event, To, Task) self:Disengage() end - if Task.description==AUFTRAG.SpecialTask.ONGUARD then + if Task.description==AUFTRAG.SpecialTask.ONGUARD or Task.description==AUFTRAG.SpecialTask.ARMOREDGUARD then self:T(self.lid.."Taske DONE OnGuard ==> Cruise") self:Cruise() end @@ -4334,7 +4334,7 @@ function OPSGROUP:onafterMissionCancel(From, Event, To, Mission) --- -- Alert 5 missoins dont have a task set, which could be cancelled. - if Mission.type==AUFTRAG.Type.ALERT5 or Mission.type==AUFTRAG.Type.ONGUARD then + if Mission.type==AUFTRAG.Type.ALERT5 or Mission.type==AUFTRAG.Type.ONGUARD or Mission.type==AUFTRAG.Type.ARMOREDGUARD then self:MissionDone(Mission) return end @@ -4540,7 +4540,7 @@ function OPSGROUP:RouteToMission(mission, delay) or mission.type.FUELSUPPLY then local zone=mission.engageTarget:GetObject() --Core.Zone#ZONE waypointcoord=zone:GetRandomCoordinate(nil , nil, surfacetypes) - elseif mission.type==AUFTRAG.Type.ONGUARD then + elseif mission.type==AUFTRAG.Type.ONGUARD or mission.type==AUFTRAG.Type.ARMOREDGUARD then waypointcoord=mission:GetMissionWaypointCoord(self.group, nil, surfacetypes) else waypointcoord=mission:GetMissionWaypointCoord(self.group, randomradius, surfacetypes) @@ -8326,7 +8326,7 @@ function OPSGROUP:onafterBoard(From, Event, To, CarrierGroup, Carrier) self:T(self.lid.."Carrier not ready for boarding yet ==> repeating boarding call in 10 sec") self:__Board(-10, CarrierGroup, Carrier) - -- Set carrier. As long as the group is not loaded, we only reserve the cargo space.� + -- Set carrier. As long as the group is not loaded, we only reserve the cargo space.� CarrierGroup:_AddCargobay(self, Carrier, true) end diff --git a/Moose Development/Moose/Ops/Platoon.lua b/Moose Development/Moose/Ops/Platoon.lua index cbaa8748f..f5479a62f 100644 --- a/Moose Development/Moose/Ops/Platoon.lua +++ b/Moose Development/Moose/Ops/Platoon.lua @@ -169,7 +169,7 @@ function PLATOON:onafterStatus(From, Event, To) -- Short info. local text=string.format("%s [Type=%s, Call=%s, Modex=%d, Skill=%s]: Assets Total=%d, Stock=%d, Mission=%d [Active=%d, Queue=%d]", fsmstate, self.aircrafttype, callsign, modex, skill, NassetsTot, NassetsInS, NassetsQP, NassetsP, NassetsQ) - self:I(self.lid..text) + self:T(self.lid..text) -- Weapon data info. if self.verbose>=3 and self.weaponData then