DETECTION, SET, ARTY, WAREHOUSE, AIRBOSS, A2A_DISPATCHER

DETECTION
- Fixed bug with late activated groups.

ARTY v1.1.2
- Added attack group task for ships.
- Added respawn option.

WAREHOUSE v0.9.5
- Added respawn option.

AIRBOSS v1.0.3
- Recovery time extended if flights are still in the pattern.

SET
- Added CountAlive() function.

A2A_DISPATCHER
- Bug fixes in :ParkDefender() function.
This commit is contained in:
Frank 2019-06-26 19:19:17 +02:00
parent 1224fb2d5a
commit 2a7b9cf898
6 changed files with 269 additions and 52 deletions

View File

@ -1095,7 +1095,7 @@ do -- AI_A2A_DISPATCHER
self:RemoveDefenderFromSquadron( Squadron, Defender )
end
DefenderUnit:Destroy()
self:ParkDefender( Squadron, Defender )
self:ParkDefender( Squadron )
return
end
if DefenderUnit:GetLife() ~= DefenderUnit:GetLife0() then
@ -1122,7 +1122,7 @@ do -- AI_A2A_DISPATCHER
self:RemoveDefenderFromSquadron( Squadron, Defender )
end
DefenderUnit:Destroy()
self:ParkDefender( Squadron, Defender )
self:ParkDefender( Squadron )
end
end
end
@ -2873,7 +2873,7 @@ do -- AI_A2A_DISPATCHER
if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2A_DISPATCHER.Landing.NearAirbase then
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
Defender:Destroy()
self:ParkDefender( Squadron, Defender )
Dispatcher:ParkDefender( Squadron )
end
end
end
@ -3060,7 +3060,7 @@ do -- AI_A2A_DISPATCHER
if Dispatcher:GetSquadronLanding( Squadron.Name ) == AI_A2A_DISPATCHER.Landing.NearAirbase then
Dispatcher:RemoveDefenderFromSquadron( Squadron, Defender )
Defender:Destroy()
self:ParkDefender( Squadron, Defender )
Dispatcher:ParkDefender( Squadron )
end
end
end -- if DefenderGCI then

View File

@ -1571,6 +1571,35 @@ do -- SET_GROUP
return Count
end
--- Iterate the SET_GROUP and count how many GROUPs and UNITs are alive.
-- @param #SET_GROUP self
-- @return #number The number of GROUPs completely in the Zone
-- @return #number The number of UNITS alive.
function SET_GROUP:CountAlive()
local CountG = 0
local CountU = 0
local Set = self:GetSet()
for GroupID, GroupData in pairs(Set) do -- For each GROUP in SET_GROUP
if GroupData and GroupData:IsAlive() then
CountG = CountG + 1
--Count Units.
for _,_unit in pairs(GroupData:GetUnits()) do
local unit=_unit --Wrapper.Unit#UNIT
if unit and unit:IsAlive() then
CountU=CountU+1
end
end
end
end
return CountG,CountU
end
----- Iterate the SET_GROUP and call an interator function for each **alive** player, providing the Group of the player and optional parameters.
---- @param #SET_GROUP self
---- @param #function IteratorFunction The function that will be called when there is an alive player in the SET_GROUP. The function needs to accept a GROUP parameter.

View File

@ -100,6 +100,8 @@
-- @field #number autorelocatemaxdist Max distance [m] the ARTY group will travel to get within firing range. Default 50000 m = 50 km.
-- @field #boolean autorelocateonroad ARTY group will use mainly road to automatically get within firing range. Default is false.
-- @field #number coalition The coalition of the arty group.
-- @field #boolean respawnafterdeath Respawn arty group after all units are dead.
-- @field #number respawndelay Respawn delay in seconds.
-- @extends Core.Fsm#FSM_CONTROLLABLE
--- Enables mission designers easily to assign targets for artillery units. Since the implementation is based on a Finite State Model (FSM), the mission designer can
@ -589,6 +591,8 @@ ARTY={
autorelocatemaxdist=50000,
autorelocateonroad=false,
coalition=nil,
respawnafterdeath=false,
respawndelay=nil
}
--- Weapong type ID. See [here](http://wiki.hoggit.us/view/DCS_enum_weapon_flag).
@ -691,7 +695,7 @@ ARTY.id="ARTY | "
--- Arty script version.
-- @field #string version
ARTY.version="1.1.1"
ARTY.version="1.1.2"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -863,6 +867,7 @@ function ARTY:New(group, alias)
self:AddTransition("*", "Status", "*")
self:AddTransition("*", "NewMove", "*")
self:AddTransition("*", "Dead", "*")
self:AddTransition("*", "Respawn", "CombatReady")
-- Transport as cargo (not in diagram).
self:AddTransition("*", "Loaded", "InTransit")
@ -973,7 +978,15 @@ function ARTY:New(group, alias)
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #string Unitname Name of the dead unit.
--- User function for OnAfter "Respawn" event.
-- @function [parent=#ARTY] OnAfterRespawn
-- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- User function for OnEnter "CombatReady" state.
-- @function [parent=#ARTY] OnEnterCombatReady
@ -1021,7 +1034,7 @@ function ARTY:New(group, alias)
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
-- @param #string To To state.
--- Function to start the ARTY FSM process.
@ -1045,11 +1058,13 @@ function ARTY:New(group, alias)
--- Function called when a unit of the ARTY group died. Triggers the FSM event "Dead".
-- @function [parent=#ARTY] Dead
-- @param #ARTY self
-- @param #string unitname Name of the unit that died.
--- Function called when a unit of the ARTY group died after a delay. Triggers the FSM event "Dead".
-- @function [parent=#ARTY] __Dead
-- @param #ARTY self
-- @param #number Delay in seconds.
-- @param #string unitname Name of the unit that died.
--- Add a new target for the ARTY group. Triggers the FSM event "NewTarget".
-- @function [parent=#ARTY] NewTarget
@ -1133,7 +1148,15 @@ function ARTY:New(group, alias)
-- @param #ARTY self
-- @param #number delay Delay in seconds.
--- Respawn ARTY group.
-- @function [parent=#ARTY] Respawn
-- @param #ARTY self
--- Respawn ARTY group after a delay.
-- @function [parent=#ARTY] __Respawn
-- @param #ARTY self
-- @param #number delay Delay in seconds.
return self
end
@ -1399,14 +1422,17 @@ end
--- Set alias, i.e. the name the group will use when sending messages.
-- @param #ARTY self
-- @param #string alias The alias for the group.
-- @return self
function ARTY:SetAlias(alias)
self:F({alias=alias})
self.alias=tostring(alias)
return self
end
--- Add ARTY group to one or more clusters. Enables addressing all ARTY groups within a cluster simultaniously via marker assignments.
-- @param #ARTY self
-- @param #table clusters Table of cluster names the group should belong to.
-- @return self
function ARTY:AddToCluster(clusters)
self:F({clusters=clusters})
@ -1425,99 +1451,122 @@ function ARTY:AddToCluster(clusters)
-- Add names to cluster array.
for _,cluster in pairs(names) do
table.insert(self.clusters, cluster)
end
end
return self
end
--- Set minimum firing range. Targets closer than this distance are not engaged.
-- @param #ARTY self
-- @param #number range Min range in kilometers. Default is 0.1 km.
-- @return self
function ARTY:SetMinFiringRange(range)
self:F({range=range})
self.minrange=range*1000 or 100
return self
end
--- Set maximum firing range. Targets further away than this distance are not engaged.
-- @param #ARTY self
-- @param #number range Max range in kilometers. Default is 1000 km.
-- @return self
function ARTY:SetMaxFiringRange(range)
self:F({range=range})
self.maxrange=range*1000 or 1000*1000
return self
end
--- Set time interval between status updates. During the status check, new events are triggered.
-- @param #ARTY self
-- @param #number interval Time interval in seconds. Default 10 seconds.
-- @return self
function ARTY:SetStatusInterval(interval)
self:F({interval=interval})
self.StatusInterval=interval or 10
return self
end
--- Set time how it is waited a unit the first shot event happens. If no shot is fired after this time, the task to fire is aborted and the target removed.
-- @param #ARTY self
-- @param #number waittime Time in seconds. Default 300 seconds.
-- @return self
function ARTY:SetWaitForShotTime(waittime)
self:F({waittime=waittime})
self.WaitForShotTime=waittime or 300
return self
end
--- Define the safe distance between ARTY group and rearming unit or rearming place at which rearming process is possible.
-- @param #ARTY self
-- @param #number distance Safe distance in meters. Default is 100 m.
-- @param #number distance Safe distance in meters. Default is 100 m.
-- @return self
function ARTY:SetRearmingDistance(distance)
self:F({distance=distance})
self.RearmingDistance=distance or 100
return self
end
--- Assign a group, which is responsible for rearming the ARTY group. If the group is too far away from the ARTY group it will be guided towards the ARTY group.
-- @param #ARTY self
-- @param Wrapper.Group#GROUP group Group that is supposed to rearm the ARTY group. For the blue coalition, this is often a unarmed M818 transport whilst for red an unarmed Ural-375 transport can be used.
-- @return self
function ARTY:SetRearmingGroup(group)
self:F({group=group})
self.RearmingGroup=group
return self
end
--- Set the speed the rearming group moves at towards the ARTY group or the rearming place.
-- @param #ARTY self
-- @param #number speed Speed in km/h.
-- @return self
function ARTY:SetRearmingGroupSpeed(speed)
self:F({speed=speed})
self.RearmingGroupSpeed=speed
return self
end
--- Define if rearming group uses mainly roads to drive to the ARTY group or rearming place.
-- @param #ARTY self
-- @param #boolean onroad If true, rearming group uses mainly roads. If false, it drives directly to the ARTY group or rearming place.
-- @return self
function ARTY:SetRearmingGroupOnRoad(onroad)
self:F({onroad=onroad})
if onroad==nil then
onroad=true
end
self.RearmingGroupOnRoad=onroad
return self
end
--- Define if ARTY group uses mainly roads to drive to the rearming place.
-- @param #ARTY self
-- @param #boolean onroad If true, ARTY group uses mainly roads. If false, it drives directly to the rearming place.
-- @return self
function ARTY:SetRearmingArtyOnRoad(onroad)
self:F({onroad=onroad})
if onroad==nil then
onroad=true
end
self.RearmingArtyOnRoad=onroad
return self
end
--- Defines the rearming place of the ARTY group. If the place is too far away from the ARTY group it will be routed to the place.
-- @param #ARTY self
-- @param Core.Point#COORDINATE coord Coordinates of the rearming place.
-- @return self
function ARTY:SetRearmingPlace(coord)
self:F({coord=coord})
self.RearmingPlaceCoord=coord
return self
end
--- Set automatic relocation of ARTY group if a target is assigned which is out of range. The unit will drive automatically towards or away from the target to be in max/min firing range.
-- @param #ARTY self
-- @param #number maxdistance (Optional) The maximum distance in km the group will travel to get within firing range. Default is 50 km. No automatic relocation is performed if targets are assigned which are further away.
-- @param #boolean onroad (Optional) If true, ARTY group uses roads whenever possible. Default false, i.e. group will move in a straight line to the assigned coordinate.
-- @param #boolean onroad (Optional) If true, ARTY group uses roads whenever possible. Default false, i.e. group will move in a straight line to the assigned coordinate.
-- @return self
function ARTY:SetAutoRelocateToFiringRange(maxdistance, onroad)
self:F({distance=maxdistance, onroad=onroad})
self.autorelocate=true
@ -1527,12 +1576,14 @@ function ARTY:SetAutoRelocateToFiringRange(maxdistance, onroad)
onroad=false
end
self.autorelocateonroad=onroad
return self
end
--- Set relocate after firing. Group will find a new location after each engagement. Default is off
-- @param #ARTY self
-- @param #number rmax (Optional) Max distance in meters, the group will move to relocate. Default is 800 m.
-- @param #number rmin (Optional) Min distance in meters, the group will move to relocate. Default is 300 m.
-- @return self
function ARTY:SetAutoRelocateAfterEngagement(rmax, rmin)
self.relocateafterfire=true
self.relocateRmax=rmax or 800
@ -1540,37 +1591,59 @@ function ARTY:SetAutoRelocateAfterEngagement(rmax, rmin)
-- Ensure that Rmin<=Rmax
self.relocateRmin=math.min(self.relocateRmin, self.relocateRmax)
return self
end
--- Report messages of ARTY group turned on. This is the default.
-- @param #ARTY self
-- @return self
function ARTY:SetReportON()
self.report=true
return self
end
--- Report messages of ARTY group turned off. Default is on.
-- @param #ARTY self
-- @return self
function ARTY:SetReportOFF()
self.report=false
return self
end
--- Respawn group once all units are dead.
-- @param #ARTY self
-- @param #number delay (Optional) Delay before respawn in seconds.
-- @return self
function ARTY:SetRespawnOnDeath(delay)
self.respawnafterdeath=true
self.respawndelay=delay
return self
end
--- Turn debug mode on. Information is printed to screen.
-- @param #ARTY self
-- @return self
function ARTY:SetDebugON()
self.Debug=true
return self
end
--- Turn debug mode off. This is the default setting.
-- @param #ARTY self
-- @return self
function ARTY:SetDebugOFF()
self.Debug=false
return self
end
--- Set default speed the group is moving at if not specified otherwise.
-- @param #ARTY self
-- @param #number speed Speed in km/h.
-- @return self
function ARTY:SetSpeed(speed)
self.Speed=speed
return self
end
--- Delete a target from target list. If the target is currently engaged, it is cancelled.
@ -1639,50 +1712,60 @@ end
--- Define shell types that are counted to determine the ammo amount the ARTY group has.
-- @param #ARTY self
-- @param #table tableofnames Table of shell type names.
-- @return self
function ARTY:SetShellTypes(tableofnames)
self:F2(tableofnames)
self.ammoshells={}
for _,_type in pairs(tableofnames) do
table.insert(self.ammoshells, _type)
end
return self
end
--- Define rocket types that are counted to determine the ammo amount the ARTY group has.
-- @param #ARTY self
-- @param #table tableofnames Table of rocket type names.
-- @return self
function ARTY:SetRocketTypes(tableofnames)
self:F2(tableofnames)
self.ammorockets={}
for _,_type in pairs(tableofnames) do
table.insert(self.ammorockets, _type)
end
return self
end
--- Define missile types that are counted to determine the ammo amount the ARTY group has.
-- @param #ARTY self
-- @param #table tableofnames Table of rocket type names.
-- @return self
function ARTY:SetMissileTypes(tableofnames)
self:F2(tableofnames)
self.ammomissiles={}
for _,_type in pairs(tableofnames) do
table.insert(self.ammomissiles, _type)
end
return self
end
--- Set number of tactical nuclear warheads available to the group.
-- Note that it can be max the number of normal shells. Also if all normal shells are empty, firing nuclear shells is also not possible any more until group gets rearmed.
-- @param #ARTY self
-- @param #number n Number of warheads for the whole group.
-- @return self
function ARTY:SetTacNukeShells(n)
self.Nukes=n
return self
end
--- Set nuclear warhead explosion strength.
-- @param #ARTY self
-- @param #number strength Explosion strength in kilo tons TNT. Default is 0.075 kt.
-- @return self
function ARTY:SetTacNukeWarhead(strength)
self.nukewarhead=strength or 0.075
self.nukewarhead=self.nukewarhead*1000*1000 -- convert to kg TNT.
return self
end
--- Set number of illumination shells available to the group.
@ -1690,10 +1773,12 @@ end
-- @param #ARTY self
-- @param #number n Number of illumination shells for the whole group.
-- @param #number power (Optional) Power of illumination warhead in mega candela. Default 1.0 mcd.
-- @return self
function ARTY:SetIlluminationShells(n, power)
self.Nillu=n
self.illuPower=power or 1.0
self.illuPower=self.illuPower * 1000000
return self
end
--- Set minimum and maximum detotation altitude for illumination shells. A value between min/max is selected randomly.
@ -1701,6 +1786,7 @@ end
-- @param #ARTY self
-- @param #number minalt (Optional) Minium altitude in meters. Default 500 m.
-- @param #number maxalt (Optional) Maximum altitude in meters. Default 1000 m.
-- @return self
function ARTY:SetIlluminationMinMaxAlt(minalt, maxalt)
self.illuMinalt=minalt or 500
self.illuMaxalt=maxalt or 1000
@ -1708,6 +1794,7 @@ function ARTY:SetIlluminationMinMaxAlt(minalt, maxalt)
if self.illuMinalt>self.illuMaxalt then
self.illuMinalt=self.illuMaxalt
end
return self
end
--- Set number of smoke shells available to the group.
@ -1715,38 +1802,46 @@ end
-- @param #ARTY self
-- @param #number n Number of smoke shells for the whole group.
-- @param Utilities.Utils#SMOKECOLOR color (Optional) Color of the smoke. Default SMOKECOLOR.Red.
-- @return self
function ARTY:SetSmokeShells(n, color)
self.Nsmoke=n
self.smokeColor=color or SMOKECOLOR.Red
return self
end
--- Set nuclear fires and extra demolition explosions.
-- @param #ARTY self
-- @param #number nfires (Optional) Number of big smoke and fire objects created in the demolition zone.
-- @param #number demolitionrange (Optional) Demolition range in meters.
-- @return self
function ARTY:SetTacNukeFires(nfires, range)
self.nukefire=true
self.nukefires=nfires
self.nukerange=range
return self
end
--- Enable assigning targets and moves by placing markers on the F10 map.
-- @param #ARTY self
-- @param #number key (Optional) Authorization key. Only players knowing this key can assign targets. Default is no authorization required.
-- @param #boolean readonly (Optional) Marks are readonly and cannot be removed by players. This also means that targets cannot be cancelled by removing the mark. Default false.
-- @return self
function ARTY:SetMarkAssignmentsOn(key, readonly)
self.markkey=key
self.markallow=true
if readonly==nil then
self.markreadonly=false
end
return self
end
--- Disable assigning targets by placing markers on the F10 map.
-- @param #ARTY self
-- @return self
function ARTY:SetMarkTargetsOff()
self.markallow=false
self.markkey=nil
return self
end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
@ -2618,17 +2713,19 @@ function ARTY:OnEventDead(EventData)
-- Name of controllable.
local _name=self.groupname
env.info("FF Dead event for arty group")
-- Check for correct group.
if EventData.IniGroupName==_name then
if EventData and EventData.IniGroupName and EventData.IniGroupName==_name then
-- Name of the dead unit.
local unitname=tostring(EventData.IniUnitName)
-- Dead Unit.
self:I(string.format("%s: Captured dead event for unit %s.", _name, tostring(EventData.IniUnitName)))
self:T(ARTY.id..string.format("%s: Captured dead event for unit %s.", _name, unitname))
-- FSM Dead event. We give one second for update of data base.
self:__Dead(1)
--self:__Dead(1, unitname)
self:Dead(unitname)
end
end
@ -2793,7 +2890,7 @@ function ARTY:onafterStatus(Controllable, From, Event, To)
self:__Status(self.StatusInterval)
else
self:E(string.format("Arty group %s is not alive!", self.groupname))
self:E(ARTY.id..string.format("Arty group %s is not alive!", self.groupname))
end
end
@ -3367,32 +3464,64 @@ end
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function ARTY:onafterDead(Controllable, From, Event, To)
-- @param #string Unitname Name of the unit that died.
function ARTY:onafterDead(Controllable, From, Event, To, Unitname)
self:_EventFromTo("onafterDead", Event, From, To)
-- Number of units left in the group.
--[[
local units=self.Controllable:GetUnits()
local nunits=0
if units~=nil then
nunits=#units
end
]]
-- Number of units still alive.
--local nunits=self.Controllable and self.Controllable:CountAliveUnits() or 0
local nunits=self.Controllable:CountAliveUnits()
-- Message.
local text=string.format("%s, one of our units just died! %d units left.", self.groupname, nunits)
local text=string.format("%s, our unit %s just died! %d units left.", self.groupname, Unitname, nunits)
MESSAGE:New(text, 5):ToAllIf(self.Debug)
self:I(ARTY.id..text)
-- Go to stop state.
if nunits==0 then
self:Stop()
-- Cease Fire on current target.
if self.currentTarget then
self:CeaseFire(self.currentTarget)
end
if self.respawnafterdeath then
-- Respawn group.
if not self.respawning then
self.respawning=true
self:__Respawn(self.respawndelay or 1)
end
else
-- Stop FSM.
self:Stop()
end
end
end
--- After "Dead" event, when a unit has died. When all units of a group are dead trigger "Stop" event.
-- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function ARTY:onafterRespawn(Controllable, From, Event, To)
self:_EventFromTo("onafterRespawn", Event, From, To)
env.info("FF Respawning arty group")
local group=self.Controllable --Wrapper.Group#GROUP
-- Respawn group.
self.Controllable=group:Respawn()
self.respawning=false
-- Call status again.
self:__Status(-1)
end
--- After "Stop" event. Unhandle events and cease fire on current target.
-- @param #ARTY self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable Controllable of the group.
@ -3452,7 +3581,7 @@ function ARTY:_FireAtCoord(coord, radius, nshells, weapontype)
group:SetTask(fire)
end
--- Set task for firing at a coordinate.
--- Set task for attacking a group.
-- @param #ARTY self
-- @param #ARTY.Target target Target data.
function ARTY:_AttackGroup(target)
@ -3476,11 +3605,8 @@ function ARTY:_AttackGroup(target)
-- Get task.
local fire=group:TaskAttackGroup(targetgroup, weapontype, AI.Task.WeaponExpend.ONE, 1)
self:E("FF")
self:E(fire)
-- Execute task.
group:PushTask(fire)
group:SetTask(fire)
end

View File

@ -541,7 +541,8 @@ do -- DETECTION_BASE
end
self.DetectionCount = self.DetectionSet:Count()
-- Count alive(!) groups only. Solves issue #1173 https://github.com/FlightControl-Master/MOOSE/issues/1173
self.DetectionCount = self.DetectionSet:CountAlive()
self.DetectionSet:ForEachGroupAlive(
function( DetectionGroup )

View File

@ -77,6 +77,8 @@
-- @field #boolean safeparking If true, parking spots for aircraft are considered as occupied if e.g. a client aircraft is parked there. Default false.
-- @field #boolean isunit If true, warehouse is represented by a unit instead of a static.
-- @field #number lowfuelthresh Low fuel threshold. Triggers the event AssetLowFuel if for any unit fuel goes below this number.
-- @field #boolean respawnafterdestroyed If true, warehouse is respawned after it was destroyed. Assets are kept.
-- @field #number respawndelay Delay before respawn in seconds.
-- @extends Core.Fsm#FSM
--- Have your assets at the right place at the right time - or not!
@ -1569,6 +1571,8 @@ WAREHOUSE = {
saveparking = false,
isunit = false,
lowfuelthresh = 0.15,
respawnafterdestroyed=false,
respawndelay = nil,
}
--- Item of the warehouse stock table.
@ -1745,7 +1749,7 @@ _WAREHOUSEDB = {
--- Warehouse class version.
-- @field #string version
WAREHOUSE.version="0.9.4"
WAREHOUSE.version="0.9.5"
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- TODO: Warehouse todo list.
@ -1908,6 +1912,7 @@ function WAREHOUSE:New(warehouse, alias)
self:AddTransition("*", "AirbaseRecaptured", "*") -- Airbase was re-captured from other coalition.
self:AddTransition("*", "AssetDead", "*") -- An asset group died.
self:AddTransition("*", "Destroyed", "Destroyed") -- Warehouse was destroyed. All assets in stock are gone and warehouse is stopped.
self:AddTransition("Destroyed", "Respawn", "Running") -- Respawn warehouse after it was destroyed.
------------------------
--- Pseudo Functions ---
@ -1940,6 +1945,22 @@ function WAREHOUSE:New(warehouse, alias)
-- @param #WAREHOUSE self
-- @param #number delay Delay in seconds.
--- Triggers the FSM event "Respawn".
-- @function [parent=#WAREHOUSE] Respawn
-- @param #WAREHOUSE self
--- Triggers the FSM event "Respawn" after a delay.
-- @function [parent=#WAREHOUSE] __Respawn
-- @param #WAREHOUSE self
-- @param #number delay Delay in seconds.
--- On after "Respawn" event user function.
-- @function [parent=#WAREHOUSE] OnAfterRespawn
-- @param #WAREHOUSE self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
--- Triggers the FSM event "Pause". Pauses the warehouse. Assets can still be added and requests be made. However, requests are not processed.
-- @function [parent=#WAREHOUSE] Pause
-- @param #WAREHOUSE self
@ -2533,6 +2554,15 @@ function WAREHOUSE:SetSaveOnMissionEnd(path, filename)
return self
end
--- Set respawn after destroy.
-- @param #WAREHOUSE self
-- @return #WAREHOUSE self
function WAREHOUSE:SetRespawnAfterDestroyed(delay)
self.respawnafterdestroyed=true
self.respawndelay=delay
return self
end
--- Set the airbase belonging to this warehouse.
-- Note that it has to be of the same coalition as the warehouse.
@ -3960,7 +3990,7 @@ function WAREHOUSE:onbeforeAddRequest(From, Event, To, warehouse, AssetDescripto
end
-- Warehouse is destroyed?
if self:IsDestroyed() then
if self:IsDestroyed() and not self.respawnafterdestroyed then
self:_ErrorMessage("ERROR: Invalid request. Warehouse is destroyed!", 0)
okay=false
end
@ -4827,6 +4857,21 @@ function WAREHOUSE:onbeforeChangeCountry(From, Event, To, Country)
return false
end
--- Respawn warehouse.
-- @param #WAREHOUSE self
-- @param #string From From state.
-- @param #string Event Event.
-- @param #string To To state.
function WAREHOUSE:onafterRespawn(From, Event, To)
-- Info message.
local text=string.format("Respawning warehouse %s.", self.alias)
self:_InfoMessage(text)
-- Respawn warehouse.
self.warehouse:ReSpawn()
end
--- On after "ChangeCountry" event. Warehouse is respawned with the specified country. All queued requests are deleted and the owned airbase is reset if the coalition is changed by changing the
-- country.
@ -4963,22 +5008,34 @@ end
function WAREHOUSE:onafterDestroyed(From, Event, To)
-- Message.
local text=string.format("Warehouse %s was destroyed! Assets lost %d.", self.alias, #self.stock)
local text=string.format("Warehouse %s was destroyed! Assets lost %d. Respawn=%s", self.alias, #self.stock, tostring(self.respawnafterdestroyed))
self:_InfoMessage(text)
-- Remove all table entries from waiting queue and stock.
for k,_ in pairs(self.queue) do
self.queue[k]=nil
if self.respawnafterdestroyed then
if self.respawndelay then
self:Pause()
self:__Respawn(self.respawndelay)
else
self:Respawn()
end
else
-- Remove all table entries from waiting queue and stock.
for k,_ in pairs(self.queue) do
self.queue[k]=nil
end
for k,_ in pairs(self.stock) do
self.stock[k]=nil
end
--self.queue=nil
--self.queue={}
--self.stock=nil
--self.stock={}
end
for k,_ in pairs(self.stock) do
self.stock[k]=nil
end
--self.queue=nil
--self.queue={}
--self.stock=nil
--self.stock={}
end
@ -6343,7 +6400,7 @@ function WAREHOUSE:_CheckRequestConsistancy(queue)
end
-- Is receiving warehouse destroyed?
if request.warehouse:IsDestroyed() then
if request.warehouse:IsDestroyed() and not self.respawnafterdestroyed then
self:E(self.wid..string.format("ERROR: INVALID request. Requesting warehouse is destroyed!"))
valid=false
end

View File

@ -3620,9 +3620,13 @@ function AIRBOSS:_CheckRecoveryTimes()
if self:IsRecovering() and not recovery.OVER then
if #self.Qpattern>0 then
-- Get number of airborne aircraft units(!) currently in pattern.
local _,npattern=self:_GetQueueInfo(self.Qpattern)
if npattern>0 then
local extmin=5*#self.Qpattern
-- Extend recovery time. 5 min per flight.
local extmin=5*npattern
recovery.STOP=recovery.STOP+extmin*60
local text=string.format("We still got flights in the pattern.\nRecovery time prolonged by %d minutes.\nNow get your act together and no more bolters!", extmin)