Merge branch 'develop' of https://github.com/FlightControl-Master/MOOSE into develop

This commit is contained in:
Van De Velde 2018-06-22 05:59:45 +02:00
commit 07aff74126
7 changed files with 162 additions and 24 deletions

View File

@ -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

View File

@ -356,7 +356,7 @@ do -- AI_A2A_DISPATCHER
--
-- ![Banner Image](..\Presentations\AI_A2A_DISPATCHER\Dia9.JPG)
--
-- If its 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 dont 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 doesnt 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 coalitions 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 its 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(),

View File

@ -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

View File

@ -1017,7 +1017,10 @@ end
-- @field Wrapper.Unit#UNIT ZoneUNIT
-- @extends Core.Zone#ZONE_RADIUS
--- The ZONE_UNIT class defined by a zone around a @{Wrapper.Unit#UNIT} with a radius.
--- # ZONE_UNIT class, extends @{Zone#ZONE_RADIUS}
--
-- The ZONE_UNIT class defined by a zone attached to a @{Wrapper.Unit#UNIT} with a radius and optional offsets.
-- This class implements the inherited functions from @{#ZONE_RADIUS} taking into account the own zone format and properties.
--
-- @field #ZONE_UNIT
@ -1025,14 +1028,35 @@ 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#Distance Radius The radius of the zone.
-- @param Dcs.DCSTypes#Distance Radius The radius of the zone.
-- @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 )
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 (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 } )
self.ZoneUNIT = ZoneUNIT
@ -1047,12 +1071,34 @@ end
--- Returns the current location of the @{Wrapper.Unit#UNIT}.
-- @param #ZONE_UNIT self
-- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Unit#UNIT}location.
-- @return DCS#Vec2 The location of the zone based on the @{Wrapper.Unit#UNIT}location and the offset, if any.
function ZONE_UNIT:GetVec2()
self:F2( self.ZoneName )
local ZoneVec2 = self.ZoneUNIT:GetVec2()
if ZoneVec2 then
if self.relative_to_unit then
heading = ( self.ZoneUNIT:GetHeading() or 0.0 ) * math.pi / 180.0
else
heading = 0.0
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
self.LastVec2 = ZoneVec2
return ZoneVec2
else

View File

@ -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

View File

@ -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.

View File

@ -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