Merge branch 'develop' into FF/Develop

This commit is contained in:
Frank
2018-11-27 18:13:58 +01:00
23 changed files with 7104 additions and 1083 deletions

View File

@@ -216,7 +216,7 @@
-- One way to determin which types of ammo the unit carries, one can use the debug mode of the arty class via @{#ARTY.SetDebugON}().
-- In debug mode, the all ammo types of the group are printed to the monitor as message and can be found in the DCS.log file.
--
-- ## Employing Selected Weapons
-- ## Empoying Selected Weapons
--
-- If an ARTY group carries multiple weapons, which can be used for artillery task, a certain weapon type can be selected to attack the target.
-- This is done via the *weapontype* parameter of the @{#ARTY.AssignTargetCoord}(..., *weapontype*, ...) function.
@@ -674,13 +674,11 @@ ARTY.id="ARTY | "
--- Arty script version.
-- @field #string version
ARTY.version="1.0.7"
ARTY.version="1.0.6"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO list:
-- TODO: Add hit event and make the arty group relocate.
-- TODO: Handle rearming for ships. How?
-- DONE: Delete targets from queue user function.
-- DONE: Delete entire target queue user function.
-- DONE: Add weapon types. Done but needs improvements.
@@ -699,9 +697,11 @@ ARTY.version="1.0.7"
-- DONE: Add command move to make arty group move.
-- DONE: remove schedulers for status event.
-- DONE: Improve handling of special weapons. When winchester if using selected weapons?
-- TODO: Handle rearming for ships. How?
-- DONE: Make coordinate after rearming general, i.e. also work after the group has moved to anonther location.
-- DONE: Add set commands via markers. E.g. set rearming place.
-- DONE: Test stationary types like mortas ==> rearming etc.
-- TODO: Add hit event and make the arty group relocate.
-- DONE: Add illumination and smoke.
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@@ -4253,116 +4253,101 @@ end
-- @param #ARTY self
function ARTY:_CheckTargetsInRange()
local targets2delete={}
for i=1,#self.targets do
local _target=self.targets[i]
self:T3(ARTY.id..string.format("Before: Target %s - in range = %s", _target.name, tostring(_target.inrange)))
-- Check if target is in range.
local _inrange,_toofar,_tooclose,_remove=self:_TargetInRange(_target)
local _inrange,_toofar,_tooclose=self:_TargetInRange(_target)
self:T3(ARTY.id..string.format("Inbetw: Target %s - in range = %s, toofar = %s, tooclose = %s", _target.name, tostring(_target.inrange), tostring(_toofar), tostring(_tooclose)))
if _remove then
-- Init default for assigning moves into range.
local _movetowards=false
local _moveaway=false
-- The ARTY group is immobile and not cargo but the target is not in range!
table.insert(targets2delete, _target.name)
else
if _target.inrange==nil then
-- Init default for assigning moves into range.
local _movetowards=false
local _moveaway=false
if _target.inrange==nil then
-- First time the check is performed. We call the function again and send a message.
_target.inrange,_toofar,_tooclose=self:_TargetInRange(_target, self.report or self.Debug)
-- Send group towards/away from target.
if _toofar then
_movetowards=true
elseif _tooclose then
_moveaway=true
end
elseif _target.inrange==true then
-- Target was in range at previous check...
if _toofar then --...but is now too far away.
_movetowards=true
elseif _tooclose then --...but is now too close.
_moveaway=true
end
elseif _target.inrange==false then
-- Target was out of range at previous check.
if _inrange then
-- Inform coalition that target is now in range.
local text=string.format("%s, target %s is now in range.", self.alias, _target.name)
self:T(ARTY.id..text)
MESSAGE:New(text,10):ToCoalitionIf(self.Controllable:GetCoalition(), self.report or self.Debug)
end
-- First time the check is performed. We call the function again and send a message.
_target.inrange,_toofar,_tooclose=self:_TargetInRange(_target, self.report or self.Debug)
-- Send group towards/away from target.
if _toofar then
_movetowards=true
elseif _tooclose then
_moveaway=true
end
-- Assign a relocation command so that the unit will be in range of the requested target.
if self.autorelocate and (_movetowards or _moveaway) then
-- Get current position.
local _from=self.Controllable:GetCoordinate()
local _dist=_from:Get2DDistance(_target.coord)
if _dist<=self.autorelocatemaxdist then
local _tocoord --Core.Point#COORDINATE
local _name=""
local _safetymargin=500
if _movetowards then
-- Target was in range on previous check but now we are too far away.
local _waytogo=_dist-self.maxrange+_safetymargin
local _heading=self:_GetHeading(_from,_target.coord)
_tocoord=_from:Translate(_waytogo, _heading)
_name=string.format("%s, relocation to within max firing range of target %s", self.alias, _target.name)
elseif _moveaway then
-- Target was in range on previous check but now we are too far away.
local _waytogo=_dist-self.minrange+_safetymargin
local _heading=self:_GetHeading(_target.coord,_from)
_tocoord=_from:Translate(_waytogo, _heading)
_name=string.format("%s, relocation to within min firing range of target %s", self.alias, _target.name)
end
-- Send info message.
MESSAGE:New(_name.." assigned.", 10):ToCoalitionIf(self.Controllable:GetCoalition(), self.report or self.Debug)
-- Assign relocation move.
self:AssignMoveCoord(_tocoord, nil, nil, self.autorelocateonroad, false, _name, true)
end
elseif _target.inrange==true then
-- Target was in range at previous check...
if _toofar then --...but is now too far away.
_movetowards=true
elseif _tooclose then --...but is now too close.
_moveaway=true
end
elseif _target.inrange==false then
-- Target was out of range at previous check.
-- Update value.
_target.inrange=_inrange
self:T3(ARTY.id..string.format("After: Target %s - in range = %s", _target.name, tostring(_target.inrange)))
if _inrange then
-- Inform coalition that target is now in range.
local text=string.format("%s, target %s is now in range.", self.alias, _target.name)
self:T(ARTY.id..text)
MESSAGE:New(text,10):ToCoalitionIf(self.Controllable:GetCoalition(), self.report or self.Debug)
end
end
end
-- Assign a relocation command so that the unit will be in range of the requested target.
if self.autorelocate and (_movetowards or _moveaway) then
-- Get current position.
local _from=self.Controllable:GetCoordinate()
local _dist=_from:Get2DDistance(_target.coord)
if _dist<=self.autorelocatemaxdist then
local _tocoord --Core.Point#COORDINATE
local _name=""
local _safetymargin=500
if _movetowards then
-- Target was in range on previous check but now we are too far away.
local _waytogo=_dist-self.maxrange+_safetymargin
local _heading=self:_GetHeading(_from,_target.coord)
_tocoord=_from:Translate(_waytogo, _heading)
_name=string.format("%s, relocation to within max firing range of target %s", self.alias, _target.name)
elseif _moveaway then
-- Target was in range on previous check but now we are too far away.
local _waytogo=_dist-self.minrange+_safetymargin
local _heading=self:_GetHeading(_target.coord,_from)
_tocoord=_from:Translate(_waytogo, _heading)
_name=string.format("%s, relocation to within min firing range of target %s", self.alias, _target.name)
end
-- Remove targets not in range.
for _,targetname in pairs(targets2delete) do
self:RemoveTarget(targetname)
-- Send info message.
MESSAGE:New(_name.." assigned.", 10):ToCoalitionIf(self.Controllable:GetCoalition(), self.report or self.Debug)
-- Assign relocation move.
self:AssignMoveCoord(_tocoord, nil, nil, self.autorelocateonroad, false, _name, true)
end
end
-- Update value.
_target.inrange=_inrange
self:T3(ARTY.id..string.format("After: Target %s - in range = %s", _target.name, tostring(_target.inrange)))
end
end
--- Check all normal (untimed) targets and return the target with the highest priority which has been engaged the fewest times.
@@ -4743,7 +4728,6 @@ end
-- @return #boolean True if target is in range, false otherwise.
-- @return #boolean True if ARTY group is too far away from the target, i.e. distance > max firing range.
-- @return #boolean True if ARTY group is too close to the target, i.e. distance < min finring range.
-- @return #boolean True if target should be removed since ARTY group is immobile and not cargo.
function ARTY:_TargetInRange(target, message)
self:F3(target)
@@ -4779,13 +4763,11 @@ function ARTY:_TargetInRange(target, message)
end
-- Remove target if ARTY group cannot move, e.g. Mortas. No chance to be ever in range - unless they are cargo.
local _remove=false
if not (self.ismobile or self.iscargo) and _inrange==false then
--self:RemoveTarget(target.name)
_remove=true
self:RemoveTarget(target.name)
end
return _inrange,_toofar,_tooclose,_remove
return _inrange,_toofar,_tooclose
end
--- Get the weapon type name, which should be used to attack the target.

View File

@@ -286,9 +286,9 @@ do -- DESIGNATE
-- * The status report can be automatically flashed by selecting "Status" -> "Flash Status On".
-- * The automatic flashing of the status report can be deactivated by selecting "Status" -> "Flash Status Off".
-- * The flashing of the status menu is disabled by default.
-- * The method @{#DESIGNATE.FlashStatusMenu}() can be used to enable or disable to flashing of the status menu.
-- * The method @{#DESIGNATE.SetFlashStatusMenu}() can be used to enable or disable to flashing of the status menu.
--
-- Designate:FlashStatusMenu( true )
-- Designate:SetFlashStatusMenu( true )
--
-- The example will activate the flashing of the status menu for this Designate object.
--
@@ -474,7 +474,7 @@ do -- DESIGNATE
self.Designating = {}
self:SetDesignateName()
self.LaseDuration = 60
self:SetLaseDuration() -- Default is 120 seconds.
self:SetFlashStatusMenu( false )
self:SetFlashDetectionMessages( true )
@@ -677,6 +677,14 @@ do -- DESIGNATE
return self
end
--- Set the lase duration for designations.
-- @param #DESIGNATE self
-- @param #number LaseDuration The time in seconds a lase will continue to hold on target. The default is 120 seconds.
-- @return #DESIGNATE
function DESIGNATE:SetLaseDuration( LaseDuration )
self.LaseDuration = LaseDuration or 120
return self
end
--- Generate an array of possible laser codes.
-- Each new lase will select a code from this table.
@@ -1000,9 +1008,9 @@ do -- DESIGNATE
if string.find( Designating, "L", 1, true ) == nil then
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Search other target", DetectedMenu, self.MenuForget, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
for LaserCode, MenuText in pairs( self.MenuLaserCodes ) do
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, string.format( MenuText, LaserCode ), DetectedMenu, self.MenuLaseCode, self, DesignateIndex, 60, LaserCode ):SetTime( MenuTime ):SetTag( self.DesignateName )
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, string.format( MenuText, LaserCode ), DetectedMenu, self.MenuLaseCode, self, DesignateIndex, self.LaseDuration, LaserCode ):SetTime( MenuTime ):SetTag( self.DesignateName )
end
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Lase with random laser code(s)", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, 60 ):SetTime( MenuTime ):SetTag( self.DesignateName )
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Lase with random laser code(s)", DetectedMenu, self.MenuLaseOn, self, DesignateIndex, self.LaseDuration ):SetTime( MenuTime ):SetTag( self.DesignateName )
else
MENU_GROUP_COMMAND_DELAYED:New( AttackGroup, "Stop lasing", DetectedMenu, self.MenuLaseOff, self, DesignateIndex ):SetTime( MenuTime ):SetTag( self.DesignateName )
end
@@ -1160,10 +1168,10 @@ do -- DESIGNATE
if string.find( self.Designating[Index], "L", 1, true ) == nil then
self.Designating[Index] = self.Designating[Index] .. "L"
self.LaseStart = timer.getTime()
self.LaseDuration = Duration
self:Lasing( Index, Duration, LaserCode )
end
self.LaseStart = timer.getTime()
self.LaseDuration = Duration
self:Lasing( Index, Duration, LaserCode )
end
@@ -1322,7 +1330,7 @@ do -- DESIGNATE
local MarkedLaserCodesText = ReportLaserCodes:Text(', ')
self.CC:GetPositionable():MessageToSetGroup( "Marking " .. MarkingCount .. " x " .. MarkedTypesText .. ", code " .. MarkedLaserCodesText .. ".", 5, self.AttackSet, self.DesignateName )
self:__Lasing( -30, Index, Duration, LaserCodeRequested )
self:__Lasing( -self.LaseDuration, Index, Duration, LaserCodeRequested )
self:SetDesignateMenu()

View File

@@ -5435,7 +5435,7 @@ function RAT:_ATCInit(airports_map)
if not RAT.ATC.init then
local text
text="Starting RAT ATC.\nSimultanious = "..RAT.ATC.Nclearance.."\n".."Delay = "..RAT.ATC.delay
BASE:T(RAT.id..text)
self:T(RAT.id..text)
RAT.ATC.init=true
for _,ap in pairs(airports_map) do
local name=ap:GetName()
@@ -5458,7 +5458,7 @@ end
-- @param #string name Group name of the flight.
-- @param #string dest Name of the destination airport.
function RAT:_ATCAddFlight(name, dest)
BASE:T(string.format("%sATC %s: Adding flight %s with destination %s.", RAT.id, dest, name, dest))
self:T(string.format("%sATC %s: Adding flight %s with destination %s.", RAT.id, dest, name, dest))
RAT.ATC.flight[name]={}
RAT.ATC.flight[name].destination=dest
RAT.ATC.flight[name].Tarrive=-1
@@ -5483,7 +5483,7 @@ end
-- @param #string name Group name of the flight.
-- @param #number time Time the fight first registered.
function RAT:_ATCRegisterFlight(name, time)
BASE:T(RAT.id.."Flight ".. name.." registered at ATC for landing clearance.")
self:T(RAT.id.."Flight ".. name.." registered at ATC for landing clearance.")
RAT.ATC.flight[name].Tarrive=time
RAT.ATC.flight[name].holding=0
end
@@ -5514,7 +5514,7 @@ function RAT:_ATCStatus()
-- Aircraft is holding.
local text=string.format("ATC %s: Flight %s is holding for %i:%02d. %s.", dest, name, hold/60, hold%60, busy)
BASE:T(RAT.id..text)
self:T(RAT.id..text)
elseif hold==RAT.ATC.onfinal then
@@ -5522,7 +5522,7 @@ function RAT:_ATCStatus()
local Tfinal=Tnow-RAT.ATC.flight[name].Tonfinal
local text=string.format("ATC %s: Flight %s is on final. Waiting %i:%02d for landing event.", dest, name, Tfinal/60, Tfinal%60)
BASE:T(RAT.id..text)
self:T(RAT.id..text)
elseif hold==RAT.ATC.unregistered then
@@ -5530,7 +5530,7 @@ function RAT:_ATCStatus()
--self:T(string.format("ATC %s: Flight %s is not registered yet (hold %d).", dest, name, hold))
else
BASE:E(RAT.id.."ERROR: Unknown holding time in RAT:_ATCStatus().")
self:E(RAT.id.."ERROR: Unknown holding time in RAT:_ATCStatus().")
end
end
@@ -5572,12 +5572,12 @@ function RAT:_ATCCheck()
-- Debug message.
local text=string.format("ATC %s: Flight %s runway is busy. You are #%d of %d in landing queue. Your holding time is %i:%02d.", name, flight,qID, nqueue, RAT.ATC.flight[flight].holding/60, RAT.ATC.flight[flight].holding%60)
BASE:T(RAT.id..text)
self:T(RAT.id..text)
else
local text=string.format("ATC %s: Flight %s was cleared for landing. Your holding time was %i:%02d.", name, flight, RAT.ATC.flight[flight].holding/60, RAT.ATC.flight[flight].holding%60)
BASE:T(RAT.id..text)
self:T(RAT.id..text)
-- Clear flight for landing.
RAT:_ATCClearForLanding(name, flight)
@@ -5705,7 +5705,12 @@ function RAT:_ATCQueue()
for k,v in ipairs(_queue) do
table.insert(RAT.ATC.airport[airport].queue, v[1])
end
--fvh
--for k,v in ipairs(RAT.ATC.airport[airport].queue) do
--print(string.format("queue #%02i flight \"%s\" holding %d seconds",k, v, RAT.ATC.flight[v].holding))
--end
end
end

File diff suppressed because it is too large Load Diff

View File

@@ -69,7 +69,6 @@
-- @field #boolean autosave Automatically save assets to file when mission ends.
-- @field #string autosavepath Path where the asset file is saved on auto save.
-- @field #string autosavefilename File name of the auto asset save file. Default is auto generated from warehouse id and name.
-- @field #boolean safeparking If true, parking spots for aircraft are considered as occupied if e.g. a client aircraft is parked there. Default false.
-- @extends Core.Fsm#FSM
--- Have your assets at the right place at the right time - or not!
@@ -625,8 +624,7 @@
-- The @{#WAREHOUSE.OnAfterAttacked} function can be used by the mission designer to react to the enemy attack. For example by deploying some or all ground troops
-- currently in stock to defend the warehouse. Note that the warehouse also has a self defence option which can be enabled by the @{#WAREHOUSE.SetAutoDefenceOn}()
-- function. In this case, the warehouse will automatically spawn all ground troops. If the spawn zone is further away from the warehouse zone, all mobile troops
-- are routed to the warehouse zone. The self request which is triggered on an automatic defence has the assignment "AutoDefence". So you can use this to
-- give orders to the groups that were spawned using the @{#WAREHOUSE.OnAfterSelfRequest} function.
-- are routed to the warehouse zone.
--
-- If only ground troops of the enemy coalition are present in the warehouse zone, the warehouse and all its assets falls into the hands of the enemy.
-- In this case the event **Captured** is triggered which can be captured by the @{#WAREHOUSE.OnAfterCaptured} function.
@@ -1557,7 +1555,6 @@ WAREHOUSE = {
autosave = false,
autosavepath = nil,
autosavefile = nil,
saveparking = false,
}
--- Item of the warehouse stock table.
@@ -1729,7 +1726,7 @@ WAREHOUSE.db = {
--- Warehouse class version.
-- @field #string version
WAREHOUSE.version="0.6.6"
WAREHOUSE.version="0.6.4"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Warehouse todo list.
@@ -1738,12 +1735,12 @@ WAREHOUSE.version="0.6.6"
-- TODO: Add check if assets "on the move" are stationary. Can happen if ground units get stuck in buildings. If stationary auto complete transport by adding assets to request warehouse? Time?
-- TODO: Optimize findpathonroad. Do it only once (first time) and safe paths between warehouses similar to off-road paths.
-- TODO: Spawn assets only virtually, i.e. remove requested assets from stock but do NOT spawn them ==> Interface to A2A dispatcher! Maybe do a negative sign on asset number?
-- TODO: Test capturing a neutral warehouse.
-- TODO: Make more examples: ARTY, CAP, ...
-- TODO: Check also general requests like all ground. Is this a problem for self propelled if immobile units are among the assets? Check if transport.
-- TODO: Handle the case when units of a group die during the transfer.
-- TODO: Added habours as interface for transport to from warehouses? Could make a rudimentary shipping dispatcher.
-- DONE: Test capturing a neutral warehouse.
-- DONE: Add save/load capability of warehouse <==> percistance after mission restart. Difficult in lua!
-- TODO: Add save/load capability of warehouse <==> percistance after mission restart. Difficult in lua!
-- DONE: Get cargo bay and weight from CARGO_GROUP and GROUP. No necessary any more!
-- DONE: Add possibility to set weight and cargo bay manually in AddAsset function as optional parameters.
-- DONE: Check overlapping aircraft sometimes.
@@ -1869,7 +1866,7 @@ function WAREHOUSE:New(warehouse, alias)
self:AddTransition("*", "Stop", "Stopped") -- Stop the warehouse.
self:AddTransition("Stopped", "Restart", "Running") -- Restart the warehouse when it was stopped before.
self:AddTransition("Loaded", "Restart", "Running") -- Restart the warehouse when assets were loaded from file before.
self:AddTransition("*", "Save", "*") -- Save the warehouse state to disk.
self:AddTransition("*", "Save", "*") -- TODO Save the warehouse state to disk.
self:AddTransition("*", "Attacked", "Attacked") -- Warehouse is under attack by enemy coalition.
self:AddTransition("Attacked", "Defeated", "Running") -- Attack by other coalition was defeated!
self:AddTransition("*", "ChangeCountry", "*") -- Change country (and coalition) of the warehouse. Warehouse is respawned!
@@ -2370,24 +2367,6 @@ function WAREHOUSE:SetReportOff()
return self
end
--- Enable safe parking option, i.e. parking spots at an airbase will be considered as occupied when a client aircraft is parked there (even if the client slot is not taken by a player yet).
-- Note that also incoming aircraft can reserve/occupie parking spaces.
-- @param #WAREHOUSE self
-- @return #WAREHOUSE self
function WAREHOUSE:SetSafeParkingOn()
self.safeparking=true
return self
end
--- Disable safe parking option. Note that is the default setting.
-- @param #WAREHOUSE self
-- @return #WAREHOUSE self
function WAREHOUSE:SetSafeParkingOff()
self.safeparking=false
return self
end
--- Set interval of status updates. Note that normally only one request can be processed per time interval.
-- @param #WAREHOUSE self
-- @param #number timeinterval Time interval in seconds.
@@ -3555,13 +3534,13 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu
else
self:T(warehouse.wid..string.format("WARNING: Group %s is neither cargo nor transport!", group:GetName()))
end
-- If no assignment was given we take the assignment of the request if there is any.
if assignment==nil and request.assignment~=nil then
assignment=request.assignment
end
end
-- If no assignment was given we take the assignment of the request if there is any.
if assignment==nil and request.assignment~=nil then
assignment=request.assignment
end
end
-- Get the asset from the global DB.
@@ -3613,7 +3592,6 @@ function WAREHOUSE:onafterAddAsset(From, Event, To, group, ngroups, forceattribu
else
self:E(self.wid.."ERROR: Unknown group added as asset!")
self:E({unknowngroup=group})
end
-- Update status.
@@ -4646,7 +4624,7 @@ function WAREHOUSE:onafterAttacked(From, Event, To, Coalition, Country)
text=text..string.format("Deploying all %d ground assets.", nground)
-- Add self request.
self:AddRequest(self, WAREHOUSE.Descriptor.CATEGORY, Group.Category.GROUND, WAREHOUSE.Quantity.ALL, nil, nil , 0, "AutoDefence")
self:AddRequest(self, WAREHOUSE.Descriptor.CATEGORY, Group.Category.GROUND, WAREHOUSE.Quantity.ALL, nil, nil , 0)
else
text=text..string.format("No ground assets currently available.")
end
@@ -6322,26 +6300,25 @@ function WAREHOUSE:_CheckRequestValid(request)
-- TODO: maybe only check if spots > 0 for the necessary terminal type? At least for FARPS.
-- Get necessary terminal type.
local termtype_dep=self:_GetTerminal(asset.attribute, self:GetAirbaseCategory())
local termtype_des=self:_GetTerminal(asset.attribute, request.warehouse:GetAirbaseCategory())
local termtype=self:_GetTerminal(asset.attribute)
-- Get number of parking spots.
local np_departure=self.airbase:GetParkingSpotsNumber(termtype_dep)
local np_destination=request.airbase:GetParkingSpotsNumber(termtype_des)
local np_departure=self.airbase:GetParkingSpotsNumber(termtype)
local np_destination=request.airbase:GetParkingSpotsNumber(termtype)
-- Debug info.
self:T(string.format("Asset attribute = %s, DEPARTURE: terminal type = %d, spots = %d, DESTINATION: terminal type = %d, spots = %d", asset.attribute, termtype_dep, np_departure, termtype_des, np_destination))
self:T(string.format("Asset attribute = %s, terminal type = %d, spots at departure = %d, destination = %d", asset.attribute, termtype, np_departure, np_destination))
-- Not enough parking at sending warehouse.
--if (np_departure < request.nasset) and not (self.category==Airbase.Category.SHIP or self.category==Airbase.Category.HELIPAD) then
if np_departure < nasset then
self:E(string.format("ERROR: Incorrect request. Not enough parking spots of terminal type %d at warehouse. Available spots %d < %d necessary.", termtype_dep, np_departure, nasset))
self:E(string.format("ERROR: Incorrect request. Not enough parking spots of terminal type %d at warehouse. Available spots %d < %d necessary.", termtype, np_departure, nasset))
valid=false
end
-- No parking at requesting warehouse.
if np_destination == 0 then
self:E(string.format("ERROR: Incorrect request. No parking spots of terminal type %d at requesting warehouse. Available spots = %d!", termtype_des, np_destination))
self:E(string.format("ERROR: Incorrect request. No parking spots of terminal type %d at requesting warehouse. Available spots = %d!", termtype, np_destination))
valid=false
end
@@ -6479,7 +6456,7 @@ function WAREHOUSE:_CheckRequestValid(request)
self:T(text)
-- Get necessary terminal type for helos or transport aircraft.
local termtype=self:_GetTerminal(request.transporttype, self:GetAirbaseCategory())
local termtype=self:_GetTerminal(request.transporttype)
-- Get number of parking spots.
local np_departure=self.airbase:GetParkingSpotsNumber(termtype)
@@ -6498,7 +6475,6 @@ function WAREHOUSE:_CheckRequestValid(request)
if request.transporttype==WAREHOUSE.TransportType.AIRPLANE then
-- Total number of parking spots for transport planes at destination.
termtype=self:_GetTerminal(request.transporttype, request.warehouse:GetAirbaseCategory())
local np_destination=request.airbase:GetParkingSpotsNumber(termtype)
-- Debug info.
@@ -6940,13 +6916,13 @@ end
--- Get the proper terminal type based on generalized attribute of the group.
--@param #WAREHOUSE self
--@param #WAREHOUSE.Attribute _attribute Generlized attibute of unit.
--@param #number _category Airbase category.
--@return Wrapper.Airbase#AIRBASE.TerminalType Terminal type for this group.
function WAREHOUSE:_GetTerminal(_attribute, _category)
function WAREHOUSE:_GetTerminal(_attribute)
-- Default terminal is "large".
local _terminal=AIRBASE.TerminalType.OpenBig
if _attribute==WAREHOUSE.Attribute.AIR_FIGHTER then
-- Fighter ==> small.
_terminal=AIRBASE.TerminalType.FighterAircraft
@@ -6956,15 +6932,6 @@ function WAREHOUSE:_GetTerminal(_attribute, _category)
elseif _attribute==WAREHOUSE.Attribute.AIR_TRANSPORTHELO or _attribute==WAREHOUSE.Attribute.AIR_ATTACKHELO then
-- Helicopter.
_terminal=AIRBASE.TerminalType.HelicopterUsable
else
--_terminal=AIRBASE.TerminalType.OpenMedOrBig
end
-- For ships, we allow medium spots for all fixed wing aircraft. There are smaller tankers and AWACS aircraft that can use a carrier.
if _category==Airbase.Category.SHIP then
if not (_attribute==WAREHOUSE.Attribute.AIR_TRANSPORTHELO or _attribute==WAREHOUSE.Attribute.AIR_ATTACKHELO) then
_terminal=AIRBASE.TerminalType.OpenMedOrBig
end
end
return _terminal
@@ -7039,6 +7006,20 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
table.insert(obstacles,{coord=_coord, size=_size, name=_name, type="scenery"})
end
--[[
-- TODO Clients? Unoccupied client aircraft are also important! Are they already included in scanned units maybe?
local clients=_DATABASE.CLIENTS
for _,_client in pairs(clients) do
local client=_client --Wrapper.Client#CLIENT
env.info(string.format("FF Client name %s", client:GetName()))
local unit=UNIT:FindByName(client:GetName())
--local unit=client:GetClientGroupUnit()
local _coord=unit:GetCoordinate()
local _name=unit:GetName()
local _size=self:_GetObjectSize(client:GetClientGroupDCSUnit())
table.insert(obstacles,{coord=_coord, size=_size, name=_name, type="client"})
end
]]
end
-- Parking data for all assets.
@@ -7049,7 +7030,7 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
local _asset=asset --#WAREHOUSE.Assetitem
-- Get terminal type of this asset
local terminaltype=self:_GetTerminal(asset.attribute, self:GetAirbaseCategory())
local terminaltype=self:_GetTerminal(asset.attribute)
-- Asset specific parking.
parking[_asset.uid]={}
@@ -7071,17 +7052,10 @@ function WAREHOUSE:_FindParkingForAssets(airbase, assets)
local _toac=parkingspot.TOAC
--env.info(string.format("FF asset=%s (id=%d): needs terminal type=%d, id=%d, #obstacles=%d", _asset.templatename, _asset.uid, terminaltype, _termid, #obstacles))
local free=true
local problem=nil
-- Safe parking using TO_AC from DCS result.
if self.safeparking and _toac then
free=false
self:T("Parking spot %d is occupied by other aircraft taking off or landing.", _termid)
end
-- Loop over all obstacles.
local free=true
local problem=nil
for _,obstacle in pairs(obstacles) do
-- Check if aircraft overlaps with any obstacle.

View File

@@ -545,6 +545,10 @@ do -- ZONE_CAPTURE_COALITION
-- @param #ZONE_CAPTURE_COALITION self
-- @param #number Delay
-- We check if a unit within the zone is hit.
-- If it is, then we must move the zone to attack state.
self:HandleEvent( EVENTS.Hit, self.OnEventHit )
return self
end
@@ -789,5 +793,20 @@ do -- ZONE_CAPTURE_COALITION
end
end
--- @param #ZONE_CAPTURE_COALITION self
-- @param Core.Event#EVENTDATA EventData The event data.
function ZONE_CAPTURE_COALITION:OnEventHit( EventData )
local UnitHit = EventData.TgtUnit
if UnitHit then
if UnitHit:IsInZone( self.Zone ) then
self:Attack()
end
end
end
end