mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Merge branch 'develop' into FF/Develop
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user