From 804b8a800ef4cfe664e20f3342fb4a8d4374ea1e Mon Sep 17 00:00:00 2001 From: Ewald Zietsman Date: Sun, 10 Jun 2018 01:46:22 +0200 Subject: [PATCH 1/7] Added basic offset support to ZoneUnit --- Moose Development/Moose/Core/Zone.lua | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 72317d2ba..fd65dcf2d 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -961,7 +961,7 @@ end --- # ZONE_UNIT class, extends @{Zone#ZONE_RADIUS} -- --- The ZONE_UNIT class defined by a zone around a @{Unit#UNIT} with a radius. +-- The ZONE_UNIT class defined by a zone attached to a @{Unit#UNIT} with a radius and optional x and y offsets. -- This class implements the inherited functions from @{#ZONE_RADIUS} taking into account the own zone format and properties. -- -- @field #ZONE_UNIT @@ -969,14 +969,21 @@ ZONE_UNIT = { ClassName="ZONE_UNIT", } ---- Constructor to create a ZONE_UNIT instance, taking the zone name, a zone unit and a radius. +--- Constructor to create a ZONE_UNIT instance, taking the zone name, a zone unit and a radius and optional offsets in X and Y directions. -- @param #ZONE_UNIT self -- @param #string ZoneName Name of the zone. -- @param Wrapper.Unit#UNIT ZoneUNIT The unit as the center of the zone. -- @param Dcs.DCSTypes#Distance Radius The radius of the zone. +-- @param Dcs.DCSTypes#Distance dx The offset in X direction, +x is north. +-- @param Dcs.DCSTypes#Distance dy The offset in Y direction, +y is east. -- @return #ZONE_UNIT self -function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius ) +function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, dx, dy ) + + self.dy = dy or 0.0 + self.dx = dx or 0.0 + local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius ) ) + self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } ) self.ZoneUNIT = ZoneUNIT @@ -988,12 +995,18 @@ end --- Returns the current location of the @{Unit#UNIT}. -- @param #ZONE_UNIT self --- @return Dcs.DCSTypes#Vec2 The location of the zone based on the @{Unit#UNIT}location. +-- @return Dcs.DCSTypes#Vec2 The location of the zone based on the @{Unit#UNIT}location and the offset, if any. function ZONE_UNIT:GetVec2() self:F2( self.ZoneName ) local ZoneVec2 = self.ZoneUNIT:GetVec2() if ZoneVec2 then + env.info(self.dx .. " " .. self.dy) + + -- update the zone position with the offsets. + ZoneVec2.x = ZoneVec2.x + self.dx + ZoneVec2.y = ZoneVec2.y + self.dy + self.LastVec2 = ZoneVec2 return ZoneVec2 else From ec0b32321a95c757900d76fe35b119b2d9c6ab2f Mon Sep 17 00:00:00 2001 From: Ewald Zietsman Date: Fri, 15 Jun 2018 19:58:26 +0200 Subject: [PATCH 2/7] Added Rho/Theta offset handling to ZoneUnit --- Moose Development/Moose/Core/Zone.lua | 34 +++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index fd65dcf2d..b1893213f 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -976,12 +976,24 @@ ZONE_UNIT = { -- @param Dcs.DCSTypes#Distance Radius The radius of the zone. -- @param Dcs.DCSTypes#Distance dx The offset in X direction, +x is north. -- @param Dcs.DCSTypes#Distance dy The offset in Y direction, +y is east. +-- @param Dcs.DCSTypes#Distance rho The distance of the zone from the unit +-- @param Dcs.DCSTypes#Angle theta The azimuth of the zone relative to unit +-- @param Dcs.DCSTypes#Boolean relative_to_unit if true, theta is measured clockwise from unit's direction else clockwise from north. -- @return #ZONE_UNIT self -function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, dx, dy ) +function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, dx, dy, rho, theta, relative_to_unit) self.dy = dy or 0.0 self.dx = dx or 0.0 + self.rho = rho or 0.0 + self.theta = theta * math.pi / 180.0 or 0.0 + self.relative_to_unit = relative_to_unit or false + -- check if the inputs was reasonable, either (dx, dy) or (rho, theta) can be given, else raise an exception. + + if (dx or dy) and (rho or theta) then + error("Cannot use arguments (dx, dy) with (rho, theta)") + end + local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius ) ) self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } ) @@ -1001,11 +1013,23 @@ function ZONE_UNIT:GetVec2() local ZoneVec2 = self.ZoneUNIT:GetVec2() if ZoneVec2 then - env.info(self.dx .. " " .. self.dy) - -- update the zone position with the offsets. - ZoneVec2.x = ZoneVec2.x + self.dx - ZoneVec2.y = ZoneVec2.y + self.dy + if (self.dx or self.dy) then + ZoneVec2.x = ZoneVec2.x + self.dx + ZoneVec2.y = ZoneVec2.y + self.dy + end + + if (self.rho or self.theta) then + -- check if theta is relative to unit or relative to north + if self.relative_to_unit then + heading = self.ZoneUNIT:GetHeading() * math.pi / 180.0 or 0.0 + else + heading = 0.0 + end + + ZoneVec2.x = ZoneVec2.x + self.rho * math.cos( self.theta + heading ) + ZoneVec2.y = ZoneVec2.y + self.rho * math.sin( self.theta + heading ) + end self.LastVec2 = ZoneVec2 return ZoneVec2 From 58e5ffa2834e204db5c1442d4ac0e6b58b17000b Mon Sep 17 00:00:00 2001 From: Ewald Zietsman Date: Sat, 16 Jun 2018 15:33:59 +0200 Subject: [PATCH 3/7] Changed offsets argument to use a table for clarity. --- Moose Development/Moose/Core/Zone.lua | 63 +++++++++++++++------------ 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index b1893213f..27741c2a3 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -974,26 +974,27 @@ ZONE_UNIT = { -- @param #string ZoneName Name of the zone. -- @param Wrapper.Unit#UNIT ZoneUNIT The unit as the center of the zone. -- @param Dcs.DCSTypes#Distance Radius The radius of the zone. --- @param Dcs.DCSTypes#Distance dx The offset in X direction, +x is north. --- @param Dcs.DCSTypes#Distance dy The offset in Y direction, +y is east. --- @param Dcs.DCSTypes#Distance rho The distance of the zone from the unit --- @param Dcs.DCSTypes#Angle theta The azimuth of the zone relative to unit --- @param Dcs.DCSTypes#Boolean relative_to_unit if true, theta is measured clockwise from unit's direction else clockwise from north. +-- @param #table Offset A table specifying the offset. The offset table may have the following elements: +-- dx The offset in X direction, +x is north. +-- dy The offset in Y direction, +y is east. +-- rho The distance of the zone from the unit +-- theta The azimuth of the zone relative to unit +-- relative_to_unit If true, theta is measured clockwise from unit's direction else clockwise from north. If using dx, dy setting this to true makes +x parallel to unit heading. +-- dx, dy OR rho, theta may be used, not both. -- @return #ZONE_UNIT self -function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, dx, dy, rho, theta, relative_to_unit) - - self.dy = dy or 0.0 - self.dx = dx or 0.0 - self.rho = rho or 0.0 - self.theta = theta * math.pi / 180.0 or 0.0 - self.relative_to_unit = relative_to_unit or false +function ZONE_UNIT:New( ZoneName, ZoneUNIT, Radius, Offset) - -- check if the inputs was reasonable, either (dx, dy) or (rho, theta) can be given, else raise an exception. - - if (dx or dy) and (rho or theta) then - error("Cannot use arguments (dx, dy) with (rho, theta)") + -- check if the inputs was reasonable, either (dx, dy) or (rho, theta) can be given, else raise an exception. + if (Offset.dx or Offset.dy) and (Offset.rho or Offset.theta) then + error("Cannot use (dx, dy) with (rho, theta)") end - + + self.dy = Offset.dy or 0.0 + self.dx = Offset.dx or 0.0 + self.rho = Offset.rho or 0.0 + self.theta = (Offset.theta or 0.0) * math.pi / 180.0 + self.relative_to_unit = Offset.relative_to_unit or false + local self = BASE:Inherit( self, ZONE_RADIUS:New( ZoneName, ZoneUNIT:GetVec2(), Radius ) ) self:F( { ZoneName, ZoneUNIT:GetVec2(), Radius } ) @@ -1013,20 +1014,24 @@ function ZONE_UNIT:GetVec2() local ZoneVec2 = self.ZoneUNIT:GetVec2() if ZoneVec2 then - -- update the zone position with the offsets. - if (self.dx or self.dy) then - ZoneVec2.x = ZoneVec2.x + self.dx - ZoneVec2.y = ZoneVec2.y + self.dy - end - - if (self.rho or self.theta) then - -- check if theta is relative to unit or relative to north - if self.relative_to_unit then - heading = self.ZoneUNIT:GetHeading() * math.pi / 180.0 or 0.0 + + if self.relative_to_unit then + heading = ( self.ZoneUNIT:GetHeading() or 0.0 ) * math.pi / 180.0 else heading = 0.0 - end - + end + + -- update the zone position with the offsets. + if (self.dx or self.dy) then + + -- use heading to rotate offset relative to unit using rotation matrix in 2D. + -- see: https://en.wikipedia.org/wiki/Rotation_matrix + ZoneVec2.x = ZoneVec2.x + self.dx * math.cos( -heading ) + self.dy * math.sin( -heading ) + ZoneVec2.y = ZoneVec2.y - self.dx * math.sin( -heading ) + self.dy * math.cos( -heading ) + end + + -- if using the polar coordinates + if (self.rho or self.theta) then ZoneVec2.x = ZoneVec2.x + self.rho * math.cos( self.theta + heading ) ZoneVec2.y = ZoneVec2.y + self.rho * math.sin( self.theta + heading ) end From 20c1f6bab4f8946a2a67f0449b5aeae1b6eed141 Mon Sep 17 00:00:00 2001 From: Jonathan Toppins Date: Mon, 18 Jun 2018 10:00:34 -0400 Subject: [PATCH 4/7] GROUP: provide a new GetFuelMin() method Taking the average fuel available across an entire flight is not really realistic and does not present an accurate representation of if a group needs to be sent to refuel or rtb. An example, a flight of 2 planes; plane 1 has 45% and plane 2 has 25% (45 + 25)/2 = 35, and 25% is the RTB threshold, plane 2 needs to go home now. However with the current averaging function plane 2 will have as little as 15% fuel (assume equal consumption) before the flight gets ordered home. Signed-off-by: Jonathan Toppins --- Moose Development/Moose/Wrapper/Group.lua | 44 +++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 776cf923c..0ea42e035 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -768,11 +768,41 @@ function GROUP:GetHeading() end ---- Returns relative amount of fuel (from 0.0 to 1.0) the group has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. +--- Return the fuel state and unit reference for the unit with the least +-- amount of fuel in the group. +-- @param #GROUP self +-- @return #number The fuel state of the unit with the least amount of fuel +-- @return #Unit reference to #Unit object for further processing +function GROUP:GetFuelMin() + self:F(self.ControllableName) + + if not self:GetDCSObject() then + BASE:E( { "Cannot GetFuel", Group = self, Alive = self:IsAlive() } ) + return 0 + end + + local min = 65535 -- some sufficiently large number to init with + local unit = nil + local tmp = nil + + for UnitID, UnitData in pairs( self:GetUnits() ) do + tmp = UnitData:GetFuel() + if tmp < min then + min = tmp + unit = UnitData + end + end + + return min, unit +end + +--- Returns relative amount of fuel (from 0.0 to 1.0) the group has in its +-- internal tanks. If there are additional fuel tanks the value may be +-- greater than 1.0. -- @param #GROUP self -- @return #number The relative amount of fuel (from 0.0 to 1.0). --- @return #nil The GROUP is not existing or alive. -function GROUP:GetFuel() +-- @return #nil The GROUP is not existing or alive. +function GROUP:GetFuelAvg() self:F( self.ControllableName ) local DCSControllable = self:GetDCSObject() @@ -795,6 +825,14 @@ function GROUP:GetFuel() return 0 end +--- Returns relative amount of fuel (from 0.0 to 1.0) the group has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. +-- @param #GROUP self +-- @return #number The relative amount of fuel (from 0.0 to 1.0). +-- @return #nil The GROUP is not existing or alive. +function GROUP:GetFuel() + return self:GetFuelAvg() +end + do -- Is Zone methods From 19197bf23463c61d8d149607b212c0d319569056 Mon Sep 17 00:00:00 2001 From: funkyfranky Date: Mon, 18 Jun 2018 23:13:21 +0200 Subject: [PATCH 5/7] Min Fuel Fixes AI_A2A and AI_Patrol: Changed average fuel for controllable to new min fuel function. Hopefully provides better RTB behavior. CONTROLLABLE: Added GetFuelMin and GetFuelAve functions to ensure polymorphic behavior. UNIT: Added GetFuelMin and GetFuelAve functions for completeness and potential polymorphism. --- Moose Development/Moose/AI/AI_A2A.lua | 2 +- Moose Development/Moose/AI/AI_Patrol.lua | 2 +- .../Moose/Wrapper/Controllable.lua | 22 +++++++++++++++++-- Moose Development/Moose/Wrapper/Unit.lua | 20 +++++++++++++++++ 4 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/AI/AI_A2A.lua b/Moose Development/Moose/AI/AI_A2A.lua index 4fbe0f37d..154e99013 100644 --- a/Moose Development/Moose/AI/AI_A2A.lua +++ b/Moose Development/Moose/AI/AI_A2A.lua @@ -452,7 +452,7 @@ function AI_A2A:onafterStatus() if not self:Is( "Fuel" ) and not self:Is( "Home" ) then - local Fuel = self.Controllable:GetFuel() + local Fuel = self.Controllable:GetFuelMin() self:F({Fuel=Fuel}) if Fuel < self.PatrolFuelThresholdPercentage then if self.TankerName then diff --git a/Moose Development/Moose/AI/AI_Patrol.lua b/Moose Development/Moose/AI/AI_Patrol.lua index 1f70d0015..ecedcf697 100644 --- a/Moose Development/Moose/AI/AI_Patrol.lua +++ b/Moose Development/Moose/AI/AI_Patrol.lua @@ -824,7 +824,7 @@ function AI_PATROL_ZONE:onafterStatus() local RTB = false - local Fuel = self.Controllable:GetUnit(1):GetFuel() + local Fuel = self.Controllable:GetFuelMin() if Fuel < self.PatrolFuelThresholdPercentage then self:E( self.Controllable:GetName() .. " is out of fuel:" .. Fuel .. ", RTB!" ) local OldAIControllable = self.Controllable diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 0b56cc0d7..3199393b4 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -259,6 +259,26 @@ function CONTROLLABLE:GetLife0() return nil end +--- Returns relative minimum amount of fuel (from 0.0 to 1.0) a unit or group has in its internal tanks. +-- This method returns nil to ensure polymorphic behaviour! This method needs to be overridden by GROUP or UNIT. +-- @param #CONTROLLABLE self +-- @return #nil The CONTROLLABLE is not existing or alive. +function CONTROLLABLE:GetFuelMin() + self:F( self.ControllableName ) + + return nil +end + +--- Returns relative average amount of fuel (from 0.0 to 1.0) a unit or group has in its internal tanks. +-- This method returns nil to ensure polymorphic behaviour! This method needs to be overridden by GROUP or UNIT. +-- @param #CONTROLLABLE self +-- @return #nil The CONTROLLABLE is not existing or alive. +function CONTROLLABLE:GetFuelAve() + self:F( self.ControllableName ) + + return nil +end + --- Returns relative amount of fuel (from 0.0 to 1.0) the unit has in its internal tanks. -- This method returns nil to ensure polymorphic behaviour! This method needs to be overridden by GROUP or UNIT. -- @param #CONTROLLABLE self @@ -270,8 +290,6 @@ function CONTROLLABLE:GetFuel() end - - -- Tasks --- Clear all tasks from the controllable. diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 753b842f4..91d138ab8 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -571,6 +571,26 @@ function UNIT:GetFuel() return nil end +--- Returns relative amount of fuel (from 0.0 to 1.0) the UNIT has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. +-- @param #UNIT self +-- @return #number The relative amount of fuel (from 0.0 to 1.0). +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetFuelMin() + self:F( self.UnitName ) + + self:GetFuel() +end + +--- Returns relative amount of fuel (from 0.0 to 1.0) the UNIT has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. +-- @param #UNIT self +-- @return #number The relative amount of fuel (from 0.0 to 1.0). +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:GetFuelAve() + self:F( self.UnitName ) + + self:GetFuel() +end + --- Returns a list of one @{Wrapper.Unit}. -- @param #UNIT self -- @return #list A list of one @{Wrapper.Unit}. From 82d40759b5d0aaf72243d93641b87067a3d9d620 Mon Sep 17 00:00:00 2001 From: funkyfranky <> Date: Mon, 18 Jun 2018 23:55:31 +0200 Subject: [PATCH 6/7] Get Fuel Min AI_A2A_Dispatcher Changed tac display from ave fuel to min fuel --- .../Moose/AI/AI_A2A_Dispatcher.lua | 18 ++++++++--------- Moose Development/Moose/Wrapper/Unit.lua | 20 ------------------- 2 files changed, 9 insertions(+), 29 deletions(-) diff --git a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua index 7a017f854..d8018b2fe 100644 --- a/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua +++ b/Moose Development/Moose/AI/AI_A2A_Dispatcher.lua @@ -356,7 +356,7 @@ do -- AI_A2A_DISPATCHER -- -- ![Banner Image](..\Presentations\AI_A2A_DISPATCHER\Dia9.JPG) -- - -- If it’s a cold war then the **borders of red and blue territory** need to be defined using a @{zone} object derived from @{Core.Zone#ZONE_BASE}. + -- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{zone} object derived from @{Core.Zone#ZONE_BASE}. -- If a hot war is chosen then **no borders** actually need to be defined using the helicopter units other than -- it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are. -- In a hot war the borders are effectively defined by the ground based radar coverage of a coalition. @@ -557,15 +557,15 @@ do -- AI_A2A_DISPATCHER -- * CAP zones can be of any type, and are derived from the @{Core.Zone#ZONE_BASE} class. Zones can be @{Core.Zone#ZONE}, @{Core.Zone#ZONE_POLYGON}, @{Core.Zone#ZONE_UNIT}, @{Core.Zone#ZONE_GROUP}, etc. -- This allows to setup **static, moving and/or complex zones** wherein aircraft will perform the CAP. -- - -- * Typically 20000-50000 metres width is used and they are spaced so that aircraft in the zone waiting for tasks don’t have to far to travel to protect their coalitions important targets. + -- * Typically 20000-50000 metres width is used and they are spaced so that aircraft in the zone waiting for tasks don't have to far to travel to protect their coalitions important targets. -- These targets are chosen as part of the mission design and might be an important airfield or town etc. -- Zone size is also determined somewhat by territory size, plane types -- (eg WW2 aircraft might mean smaller zones or more zones because they are slower and take longer to intercept enemy aircraft). -- - -- * In a **cold war** it is important to make sure a CAP zone doesn’t intrude into enemy territory as otherwise CAP flights will likely cross borders + -- * In a **cold war** it is important to make sure a CAP zone doesn't intrude into enemy territory as otherwise CAP flights will likely cross borders -- and spark a full scale conflict which will escalate rapidly. -- - -- * CAP flights do not need to be in the CAP zone before they are “on station” and ready for tasking. + -- * CAP flights do not need to be in the CAP zone before they are "on station" and ready for tasking. -- -- * Typically if a CAP flight is tasked and therefore leaves their zone empty while they go off and intercept their target another CAP flight will spawn to take their place. -- @@ -805,11 +805,11 @@ do -- AI_A2A_DISPATCHER -- For example because the mission calls for a EWR radar on the blue side the Ukraine might be chosen as a blue country -- so that the 55G6 EWR radar unit is available to blue. -- Some countries assign different tasking to aircraft, for example Germany assigns the CAP task to F-4E Phantoms but the USA does not. - -- Therefore if F4s are wanted as a coalition’s CAP or GCI aircraft Germany will need to be assigned to that coalition. + -- Therefore if F4s are wanted as a coalition's CAP or GCI aircraft Germany will need to be assigned to that coalition. -- -- ### 11.2. Country, type, load out, skill and skins for CAP and GCI aircraft? -- - -- * Note these can be from any countries within the coalition but must be an aircraft with one of the main tasks being “CAP”. + -- * Note these can be from any countries within the coalition but must be an aircraft with one of the main tasks being "CAP". -- * Obviously skins which are selected must be available to all players that join the mission otherwise they will see a default skin. -- * Load outs should be appropriate to a CAP mission eg perhaps drop tanks for CAP flights and extra missiles for GCI flights. -- * These decisions will eventually lead to template aircraft units being placed as late activation units that the script will use as templates for spawning CAP and GCI flights. Up to 4 different aircraft configurations can be chosen for each coalition. The spawned aircraft will inherit the characteristics of the template aircraft. @@ -1152,7 +1152,7 @@ do -- AI_A2A_DISPATCHER --- Define a border area to simulate a **cold war** scenario. -- A **cold war** is one where CAP aircraft patrol their territory but will not attack enemy aircraft or launch GCI aircraft unless enemy aircraft enter their territory. In other words the EWR may detect an enemy aircraft but will only send aircraft to attack it if it crosses the border. -- A **hot war** is one where CAP aircraft will intercept any detected enemy aircraft and GCI aircraft will launch against detected enemy aircraft without regard for territory. In other words if the ground radar can detect the enemy aircraft then it will send CAP and GCI aircraft to attack it. - -- If it’s a cold war then the **borders of red and blue territory** need to be defined using a @{zone} object derived from @{Core.Zone#ZONE_BASE}. This method needs to be used for this. + -- If it's a cold war then the **borders of red and blue territory** need to be defined using a @{zone} object derived from @{Core.Zone#ZONE_BASE}. This method needs to be used for this. -- If a hot war is chosen then **no borders** actually need to be defined using the helicopter units other than it makes it easier sometimes for the mission maker to envisage where the red and blue territories roughly are. In a hot war the borders are effectively defined by the ground based radar coverage of a coalition. Set the noborders parameter to 1 -- @param #AI_A2A_DISPATCHER self -- @param Core.Zone#ZONE_BASE BorderZone An object derived from ZONE_BASE, or a list of objects derived from ZONE_BASE. @@ -3031,7 +3031,7 @@ do -- AI_A2A_DISPATCHER for Defender, DefenderTask in pairs( self:GetDefenderTasks() ) do local Defender = Defender -- Wrapper.Group#GROUP if DefenderTask.Target and DefenderTask.Target.Index == DetectedItem.Index then - local Fuel = Defender:GetFuel() * 100 + local Fuel = Defender:GetFuelMin() * 100 local Damage = Defender:GetLife() / Defender:GetLife0() * 100 Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s", Defender:GetName(), @@ -3054,7 +3054,7 @@ do -- AI_A2A_DISPATCHER local Defender = Defender -- Wrapper.Group#GROUP if not DefenderTask.Target then local DefenderHasTask = Defender:HasTask() - local Fuel = Defender:GetFuel() * 100 + local Fuel = Defender:GetFuelMin() * 100 local Damage = Defender:GetLife() / Defender:GetLife0() * 100 Report:Add( string.format( " - %s ( %s - %s ): ( #%d ) F: %3d, D:%3d - %s", Defender:GetName(), diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 91d138ab8..753b842f4 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -571,26 +571,6 @@ function UNIT:GetFuel() return nil end ---- Returns relative amount of fuel (from 0.0 to 1.0) the UNIT has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. --- @param #UNIT self --- @return #number The relative amount of fuel (from 0.0 to 1.0). --- @return #nil The DCS Unit is not existing or alive. -function UNIT:GetFuelMin() - self:F( self.UnitName ) - - self:GetFuel() -end - ---- Returns relative amount of fuel (from 0.0 to 1.0) the UNIT has in its internal tanks. If there are additional fuel tanks the value may be greater than 1.0. --- @param #UNIT self --- @return #number The relative amount of fuel (from 0.0 to 1.0). --- @return #nil The DCS Unit is not existing or alive. -function UNIT:GetFuelAve() - self:F( self.UnitName ) - - self:GetFuel() -end - --- Returns a list of one @{Wrapper.Unit}. -- @param #UNIT self -- @return #list A list of one @{Wrapper.Unit}. From 7d90a94927d2003a6a3c60b342da3cdd8ad1eb66 Mon Sep 17 00:00:00 2001 From: funkyfranky <> Date: Tue, 19 Jun 2018 23:10:08 +0200 Subject: [PATCH 7/7] ARTY Updated docs. Added SetSpeed() function. --- .../Moose/Functional/Artillery.lua | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index c2ab7b275..126ef78b9 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -237,8 +237,8 @@ -- * @{#ARTY.WeaponType}.IlluminationShells: Use illumination shells. This works only with units that have shells and is described below. -- * @{#ARTY.WeaponType}.SmokeShells: Use smoke shells. This works only with units that have shells and is described below. -- --- ## Assigning Moves --- The ARTY group can be commanded to move. This is done by the @{#ARTY.AssignMoveCoord}(*coord*,*time*,*speed*,*onroad*,*cancel*,*name*) function. +-- ## Assigning Relocation Movements +-- The ARTY group can be commanded to move. This is done by the @{#ARTY.AssignMoveCoord}(*coord*, *time*, *speed*, *onroad*, *cancel*, *name*) function. -- With this multiple timed moves of the group can be scheduled easily. By default, these moves will only be executed if the group is state **CombatReady**. -- -- ### Parameters @@ -274,7 +274,11 @@ -- -- After the rearming is complete, both groups will move back to their original positions. -- --- ## Tactical Nukes +-- ## Simulated Weapons +-- +-- In addtion to the standard weapons a group has available some special weapon types that are not possible to use in the native DCS environment are simulated. +-- +-- ### Tactical Nukes -- -- ARTY groups that can fire shells can also be used to fire tactical nukes. This is achieved by setting the weapon type to **ARTY.WeaponType.TacticalNukes** in the -- @{#ARTY.AssignTargetCoord}() function. @@ -284,6 +288,27 @@ -- Note that the group must always have convenctional shells left in order to fire a nuclear shell. -- -- The default explostion strength is 0.075 kilo tons TNT. The can be changed with the @{#ARTY.SetTacNukeWarhead}(*strength*), where *strength* is given in kilo tons TNT. +-- +-- ### Illumination Shells +-- +-- ARTY groups that possess shells can fire shells with illumination bombs. First, the group needs to be equipped with this weapon. This is done by the +-- function @{ARTY.SetIlluminationShells}(*n*, *power*), where *n* is the number of shells the group has available and *power* the illumination power in mega candela (mcd). +-- +-- In order to execute an engagement with illumination shells one has to use the weapon type *ARTY.WeaponType.IlluminationShells* in the +-- @{#ARTY.AssignTargetCoord}() function. +-- +-- In the simulation, the explosive shell that is fired is destroyed once it gets close to the target point but before it can actually impact. +-- At this position an illumination bomb is triggered at a random altitude between 500 and 1000 meters. This interval can be set by the function +-- @{ARTY.SetIlluminationMinMaxAlt}(*minalt*, *maxalt*). +-- +-- ### Smoke Shells +-- +-- In a similar way to illumination shells, ARTY groups can also employ smoke shells. The numer of smoke shells the group has available is set by the function +-- @{#ARTY.SetSmokeShells}(*n*, *color*), where *n* is the number of shells and *color* defines the smoke color. Default is SMOKECOLOR.Red. +-- +-- The weapon type to be used in the @{#ARTY.AssignTargetCoord}() function is *ARTY.WeaponType.SmokeShells*. +-- +-- The explosive shell the group fired is destroyed shortly before its impact on the ground and smoke of the speficied color is triggered at that position. -- -- -- ## Assignments via Markers on F10 Map @@ -403,6 +428,7 @@ -- * @{#ARTY.SetAutoRelocateAfterEngagement}(*rmax*, *rmin*) will cause the ARTY group to change its position after each firing assignment. -- Optional parameters *rmax*, *rmin* define the max/min distance for relocation of the group. Default distance is randomly between 300 and 800 m. -- * @{#ARTY.AddToCluster}(*clusters*) Can be used to add the ARTY group to one or more clusters. All groups in a cluster can be addressed simultaniously with one marker command. +-- * @{#ARTY.SetSpeed}(*speed*) sets the speed in km/h the group moves at if not explicitly stated otherwise. -- * @{#ARTY.RemoveAllTargets}() removes all targets from the target queue. -- * @{#ARTY.RemoveTarget}(*name*) deletes the target with *name* from the target queue. -- * @{#ARTY.SetMaxFiringRange}(*range*) defines the maximum firing range. Targets further away than this distance are not engaged. @@ -1355,6 +1381,13 @@ function ARTY:SetDebugOFF() self.Debug=false end +--- Set default speed the group is moving at if not specified otherwise. +-- @param #ARTY self +-- @param #number speed Speed in km/h. +function ARTY:SetSpeed(speed) + self.Speed=speed +end + --- Delete a target from target list. If the target is currently engaged, it is cancelled. -- @param #ARTY self -- @param #string name Name of the target. @@ -1601,6 +1634,9 @@ function ARTY:onafterStart(Controllable, From, Event, To) self.autorelocate=false self.RearmingGroupSpeed=20 end + + -- Check that default speed is below max speed. + self.Speed=math.min(self.Speed, self.SpeedMax) -- Set Rearming group speed if not specified by user if self.RearmingGroup then