From fcfcfeae00cf234ba1bad12468a2b7862b8c9d5f Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 6 Jan 2020 00:15:44 +0100 Subject: [PATCH] Misc --- .../Moose/AI/AI_Cargo_Dispatcher.lua | 4 + Moose Development/Moose/Core/Set.lua | 4 +- Moose Development/Moose/Core/Spawn.lua | 7 +- .../Moose/Functional/Suppression.lua | 12 +- .../Moose/Functional/ZoneCaptureCoalition.lua | 6 + Moose Development/Moose/Utilities/Utils.lua | 2 +- .../Moose/Wrapper/Controllable.lua | 161 ++++++++++++++++++ Moose Development/Moose/Wrapper/Unit.lua | 39 +++++ 8 files changed, 223 insertions(+), 12 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua index 311a07b59..424a0f814 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Dispatcher.lua @@ -1151,6 +1151,10 @@ function AI_CARGO_DISPATCHER:onafterMonitor() self.PickupCargo[Carrier] = CargoCoordinate PickupCargo = Cargo break + else + local text=string.format("WARNING: Cargo %s is too heavy to be loaded into transport. Cargo weight %.1f > %.1f load capacity of carrier %s.", + tostring(Cargo:GetName()), Cargo:GetWeight(), LargestLoadCapacity, tostring(Carrier:GetName())) + self:I(text) end end end diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 149d22d23..dedec77c9 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -1576,8 +1576,8 @@ do -- SET_GROUP --- Iterate the SET_GROUP and count how many GROUPs and UNITs are alive. -- @param #SET_GROUP self - -- @return #number The number of GROUPs completely in the Zone - -- @return #number The number of UNITS alive. + -- @return #number The number of GROUPs alive. + -- @return #number The number of UNITs alive. function SET_GROUP:CountAlive() local CountG = 0 local CountU = 0 diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index 4865754ca..200d8a7a0 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -214,9 +214,8 @@ -- ### **Scheduled** spawning methods -- -- * @{#SPAWN.SpawnScheduled}(): Spawn groups at scheduled but randomized intervals. --- * @{#SPAWN.SpawnScheduledStart}(): Start or continue to spawn groups at scheduled time intervals. --- * @{#SPAWN.SpawnScheduledStop}(): Stop the spawning of groups at scheduled time intervals. --- +--- * @{#SPAWN.SpawnScheduleStart}(): Start or continue to spawn groups at scheduled time intervals. +-- * @{#SPAWN.SpawnScheduleStop}(): Stop the spawning of groups at scheduled time intervals. -- -- -- ## Retrieve alive GROUPs spawned by the SPAWN object @@ -260,7 +259,7 @@ -- immediately when :SpawnScheduled() is initiated. The methods @{#SPAWN.InitDelayOnOff}() and @{#SPAWN.InitDelayOn}() can be used to -- activate a delay before the first @{Wrapper.Group} is spawned. For completeness, a method @{#SPAWN.InitDelayOff}() is also available, that -- can be used to switch off the initial delay. Because there is no delay by default, this method would only be used when a --- @{#SPAWN.SpawnScheduledStop}() ; @{#SPAWN.SpawnScheduledStart}() sequence would have been used. +-- @{#SPAWN.SpawnScheduleStop}() ; @{#SPAWN.SpawnScheduleStart}() sequence would have been used. -- -- -- @field #SPAWN SPAWN diff --git a/Moose Development/Moose/Functional/Suppression.lua b/Moose Development/Moose/Functional/Suppression.lua index 92e6c170b..c66cc1906 100644 --- a/Moose Development/Moose/Functional/Suppression.lua +++ b/Moose Development/Moose/Functional/Suppression.lua @@ -22,7 +22,7 @@ -- -- The implementation is based on an idea and script by MBot. See the [DCS forum threat](https://forums.eagle.ru/showthread.php?t=107635) for details. -- --- In addition to suppressing the fire, conditions can be specified which let the group retreat to a defined zone, move away from the attacker +-- In addition to suppressing the fire, conditions can be specified, which let the group retreat to a defined zone, move away from the attacker -- or hide at a nearby scenery object. -- -- ==== @@ -882,10 +882,11 @@ function SUPPRESSION:StatusReport(message) local state=self.CurrentAlarmState local life_min, life_max, life_ave, life_ave0, groupstrength=self:_GetLife() local ammotot=group:GetAmmunition() + local detectedG=group:GetDetectedGroupSet():CountAlive() + local detectedU=group:GetDetectedUnitSet():Count() - - local text=string.format("State %s, Units=%d/%d, ROE=%s, AlarmState=%s, Hits=%d, Life(min/max/ave/ave0)=%d/%d/%d/%d, Total Ammo=%d", - self:GetState(), nunits, self.IniGroupStrength, self.CurrentROE, self.CurrentAlarmState, self.Nhit, life_min, life_max, life_ave, life_ave0, ammotot) + local text=string.format("State %s, Units=%d/%d, ROE=%s, AlarmState=%s, Hits=%d, Life(min/max/ave/ave0)=%d/%d/%d/%d, Total Ammo=%d, Detected=%d/%d", + self:GetState(), nunits, self.IniGroupStrength, self.CurrentROE, self.CurrentAlarmState, self.Nhit, life_min, life_max, life_ave, life_ave0, ammotot, detectedG, detectedU) MESSAGE:New(text, 10):ToAllIf(message or self.Debug) self:I(self.lid..text) @@ -997,11 +998,12 @@ function SUPPRESSION:onafterStatus(Controllable, From, Event, To) local nunits=group:CountAliveUnits() -- Check if there are units. - if nunits>0 then + if nunits>0 then -- 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() end diff --git a/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua b/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua index 81c2aefd1..1e9417e96 100644 --- a/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua +++ b/Moose Development/Moose/Functional/ZoneCaptureCoalition.lua @@ -874,6 +874,12 @@ do -- ZONE_CAPTURE_COALITION self:Capture() end + if self:IsAttacked() then + local unitset=self:GetScannedSetUnit() --Core.Set#SET_UNIT + + unitset:ForEachUnitInZone(self) + end + -- 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() diff --git a/Moose Development/Moose/Utilities/Utils.lua b/Moose Development/Moose/Utilities/Utils.lua index acfc30323..26ef8c76e 100644 --- a/Moose Development/Moose/Utilities/Utils.lua +++ b/Moose Development/Moose/Utilities/Utils.lua @@ -78,7 +78,7 @@ CALLSIGN={ }, -- AWACS AWACS={ - Overloard=1, + Overlord=1, Magic=2, Wizard=3, Focus=4, diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index b42085516..28eaff805 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -2802,7 +2802,9 @@ function CONTROLLABLE:GetDetectedTargets( DetectVisual, DetectOptical, DetectRad self:F2( self.ControllableName ) local DCSControllable = self:GetDCSObject() + if DCSControllable then + local DetectionVisual = ( DetectVisual and DetectVisual == true ) and Controller.Detection.VISUAL or nil local DetectionOptical = ( DetectOptical and DetectOptical == true ) and Controller.Detection.OPTICAL or nil local DetectionRadar = ( DetectRadar and DetectRadar == true ) and Controller.Detection.RADAR or nil @@ -2841,7 +2843,25 @@ function CONTROLLABLE:GetDetectedTargets( DetectVisual, DetectOptical, DetectRad end --- Check if a target is detected. +-- The optional parametes specify the detection methods that can be applied. +-- If **no** detection method is given, the detection will use **all** the available methods by default. +-- If **at least one** detection method is specified, only the methods set to *true* will be used. -- @param Wrapper.Controllable#CONTROLLABLE self +-- @param DCS#Object DCSObject The DCS object that is checked. +-- @param Wrapper.Controllable#CONTROLLABLE self +-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets. +-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets. +-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar. +-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST. +-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR. +-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link. +-- @return #boolean True if target is detected. +-- @return #boolean True if target is visible by line of sight. +-- @return #number Mission time when target was detected. +-- @return #boolean True if target type is known. +-- @return #boolean True if distance to target is known. +-- @return DCS#Vec3 Last known position vector of the target. +-- @return DCS#Vec3 Last known velocity vector of the target. function CONTROLLABLE:IsTargetDetected( DCSObject, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK ) self:F2( self.ControllableName ) @@ -2867,6 +2887,147 @@ function CONTROLLABLE:IsTargetDetected( DCSObject, DetectVisual, DetectOptical, return nil end +--- Check if a certain UNIT is detected by the controllable. +-- The optional parametes specify the detection methods that can be applied. +-- If **no** detection method is given, the detection will use **all** the available methods by default. +-- If **at least one** detection method is specified, only the methods set to *true* will be used. +-- @param #CONTROLLABLE self +-- @param Wrapper.Unit#UNIT Unit The unit that is supposed to be detected. +-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets. +-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets. +-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar. +-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST. +-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR. +-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link. +-- @return #boolean True if target is detected. +-- @return #boolean True if target is visible by line of sight. +-- @return #number Mission time when target was detected. +-- @return #boolean True if target type is known. +-- @return #boolean True if distance to target is known. +-- @return DCS#Vec3 Last known position vector of the target. +-- @return DCS#Vec3 Last known velocity vector of the target. +function CONTROLLABLE:IsUnitDetected( Unit, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK ) + self:F2( self.ControllableName ) + + if Unit and Unit:IsAlive() then + return self:IsTargetDetected(Unit:GetDCSObject(), DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK) + end + + return nil +end + +--- Check if a certain GROUP is detected by the controllable. +-- The optional parametes specify the detection methods that can be applied. +-- If **no** detection method is given, the detection will use **all** the available methods by default. +-- If **at least one** detection method is specified, only the methods set to *true* will be used. +-- @param #CONTROLLABLE self +-- @param Wrapper.Group#GROUP Group The group that is supposed to be detected. +-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets. +-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets. +-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar. +-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST. +-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR. +-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link. +-- @return #boolean True if any unit of the group is detected. +function CONTROLLABLE:IsGroupDetected( Group, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK ) + self:F2( self.ControllableName ) + + if Group and Group:IsAlive() then + for _,_unit in pairs(Group:GetUnits()) do + local unit=_unit --Wrapper.Unit#UNIT + if unit and unit:IsAlive() then + + local isdetected=self:IsUnitDetected(unit, DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK) + + if isdetected then + return true + end + end + end + return false + end + + return nil +end + + +--- Return the detected targets of the controllable. +-- The optional parametes specify the detection methods that can be applied. +-- If **no** detection method is given, the detection will use **all** the available methods by default. +-- If **at least one** detection method is specified, only the methods set to *true* will be used. +-- @param Wrapper.Controllable#CONTROLLABLE self +-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets. +-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets. +-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar. +-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST. +-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR. +-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link. +-- @return Core.Set#SET_UNIT Set of detected units. +function CONTROLLABLE:GetDetectedUnitSet(DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK) + + -- Get detected DCS units. + local detectedtargets=self:GetDetectedTargets(DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK) + + local unitset=SET_UNIT:New() + + for DetectionObjectID, Detection in pairs(detectedtargets or {}) do + local DetectedObject=Detection.object -- DCS#Object + + if DetectedObject and DetectedObject:isExist() and DetectedObject.id_<50000000 then + local unit=UNIT:Find(DetectedObject) + + if unit and unit:IsAlive() then + + if not unitset:FindUnit(unit:GetName()) then + unitset:AddUnit(unit) + end + + end + end + end + + return unitset +end + +--- Return the detected target groups of the controllable as a @{SET_GROUP}. +-- The optional parametes specify the detection methods that can be applied. +-- If no detection method is given, the detection will use all the available methods by default. +-- @param Wrapper.Controllable#CONTROLLABLE self +-- @param #boolean DetectVisual (Optional) If *false*, do not include visually detected targets. +-- @param #boolean DetectOptical (Optional) If *false*, do not include optically detected targets. +-- @param #boolean DetectRadar (Optional) If *false*, do not include targets detected by radar. +-- @param #boolean DetectIRST (Optional) If *false*, do not include targets detected by IRST. +-- @param #boolean DetectRWR (Optional) If *false*, do not include targets detected by RWR. +-- @param #boolean DetectDLINK (Optional) If *false*, do not include targets detected by data link. +-- @return Core.Set#SET_GROUP Set of detected groups. +function CONTROLLABLE:GetDetectedGroupSet(DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK) + + -- Get detected DCS units. + local detectedtargets=self:GetDetectedTargets(DetectVisual, DetectOptical, DetectRadar, DetectIRST, DetectRWR, DetectDLINK) + + local groupset=SET_GROUP:New() + + for DetectionObjectID, Detection in pairs(detectedtargets or {}) do + local DetectedObject=Detection.object -- DCS#Object + + if DetectedObject and DetectedObject:isExist() and DetectedObject.id_<50000000 then + local unit=UNIT:Find(DetectedObject) + + if unit and unit:IsAlive() then + local group=unit:GetGroup() + + if group and not groupset:FindGroup(group:GetName()) then + groupset:AddGroup(group) + end + + end + end + end + + return groupset +end + + -- Options --- Can the CONTROLLABLE hold their weapons? diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 7f974be19..c747bc92e 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -1165,6 +1165,45 @@ do -- Detection return IsLOS end + + --- Forces the unit to become aware of the specified target, without the unit manually detecting the other unit itself. + -- Applies only to a Unit Controller. Cannot be used at the group level. + -- @param #UNIT self + -- @param #UNIT TargetUnit The unit to be known. + -- @param #boolean TypeKnown The target type is known. If *false*, the type is not known. + -- @param #boolean DistanceKnown The distance to the target is known. If *false*, distance is unknown. + function UNIT:KnowUnit(TargetUnit, TypeKnown, DistanceKnown) + + -- Defaults. + if TypeKnown~=false then + TypeKnown=true + end + if DistanceKnown~=false then + DistanceKnown=true + end + local DCSControllable = self:GetDCSObject() + + if DCSControllable then + + local Controller = DCSControllable:getController() --self:_GetController() + + if Controller then + + local object=TargetUnit:GetDCSObject() + + if object then + + self:I(string.format("Unit %s now knows target unit %s. Type known=%s, distance known=%s", self:GetName(), TargetUnit:GetName(), tostring(TypeKnown), tostring(DistanceKnown))) + + Controller:knowTarget(object, TypeKnown, DistanceKnown) + + end + + end + + end + + end end \ No newline at end of file