mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Updates
This commit is contained in:
parent
345b0055f3
commit
d4b9fc9e40
@ -319,7 +319,7 @@ function SPAWN:New( SpawnTemplatePrefix )
|
|||||||
self.SpawnUnControlled = false
|
self.SpawnUnControlled = false
|
||||||
self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name.
|
self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name.
|
||||||
self.DelayOnOff = false -- No intial delay when spawning the first group.
|
self.DelayOnOff = false -- No intial delay when spawning the first group.
|
||||||
self.Grouping = nil -- No grouping.
|
self.SpawnGrouping = nil -- No grouping.
|
||||||
self.SpawnInitLivery = nil -- No special livery.
|
self.SpawnInitLivery = nil -- No special livery.
|
||||||
self.SpawnInitSkill = nil -- No special skill.
|
self.SpawnInitSkill = nil -- No special skill.
|
||||||
self.SpawnInitFreq = nil -- No special frequency.
|
self.SpawnInitFreq = nil -- No special frequency.
|
||||||
@ -371,7 +371,7 @@ function SPAWN:NewWithAlias( SpawnTemplatePrefix, SpawnAliasPrefix )
|
|||||||
self.SpawnUnControlled = false
|
self.SpawnUnControlled = false
|
||||||
self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name.
|
self.SpawnInitKeepUnitNames = false -- Overwrite unit names by default with group name.
|
||||||
self.DelayOnOff = false -- No intial delay when spawning the first group.
|
self.DelayOnOff = false -- No intial delay when spawning the first group.
|
||||||
self.Grouping = nil -- No grouping.
|
self.SpawnGrouping = nil -- No grouping.
|
||||||
self.SpawnInitLivery = nil -- No special livery.
|
self.SpawnInitLivery = nil -- No special livery.
|
||||||
self.SpawnInitSkill = nil -- No special skill.
|
self.SpawnInitSkill = nil -- No special skill.
|
||||||
self.SpawnInitFreq = nil -- No special frequency.
|
self.SpawnInitFreq = nil -- No special frequency.
|
||||||
@ -549,7 +549,7 @@ end
|
|||||||
|
|
||||||
--- Sets the country of the spawn group. Note that the country determins the coalition of the group depending on which country is defined to be on which side for each specific mission!
|
--- Sets the country of the spawn group. Note that the country determins the coalition of the group depending on which country is defined to be on which side for each specific mission!
|
||||||
-- @param #SPAWN self
|
-- @param #SPAWN self
|
||||||
-- @param #DCS.country Country Country id as number or enumerator:
|
-- @param #number Country Country id as number or enumerator:
|
||||||
--
|
--
|
||||||
-- * @{DCS#country.id.RUSSIA}
|
-- * @{DCS#country.id.RUSSIA}
|
||||||
-- * @{DCS#county.id.USA}
|
-- * @{DCS#county.id.USA}
|
||||||
@ -1438,7 +1438,7 @@ end
|
|||||||
-- @param Wrapper.Airbase#AIRBASE.TerminalType TerminalType (optional) The terminal type the aircraft should be spawned at. See @{Wrapper.Airbase#AIRBASE.TerminalType}.
|
-- @param Wrapper.Airbase#AIRBASE.TerminalType TerminalType (optional) The terminal type the aircraft should be spawned at. See @{Wrapper.Airbase#AIRBASE.TerminalType}.
|
||||||
-- @param #boolean EmergencyAirSpawn (optional) If true (default), groups are spawned in air if there is no parking spot at the airbase. If false, nothing is spawned if no parking spot is available.
|
-- @param #boolean EmergencyAirSpawn (optional) If true (default), groups are spawned in air if there is no parking spot at the airbase. If false, nothing is spawned if no parking spot is available.
|
||||||
-- @param #table Parkingdata (optional) Table holding the coordinates and terminal ids for all units of the group. Spawning will be forced to happen at exactily these spots!
|
-- @param #table Parkingdata (optional) Table holding the coordinates and terminal ids for all units of the group. Spawning will be forced to happen at exactily these spots!
|
||||||
-- @return Wrapper.Group#GROUP that was spawned or nil when nothing was spawned.
|
-- @return Wrapper.Group#GROUP The group that was spawned or nil when nothing was spawned.
|
||||||
-- @usage
|
-- @usage
|
||||||
-- Spawn_Plane = SPAWN:New( "Plane" )
|
-- Spawn_Plane = SPAWN:New( "Plane" )
|
||||||
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold )
|
-- Spawn_Plane:SpawnAtAirbase( AIRBASE:FindByName( AIRBASE.Caucasus.Krymsk ), SPAWN.Takeoff.Cold )
|
||||||
@ -1498,11 +1498,7 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
local TemplateGroup = GROUP:FindByName(self.SpawnTemplatePrefix)
|
local TemplateGroup = GROUP:FindByName(self.SpawnTemplatePrefix)
|
||||||
local TemplateUnit=TemplateGroup:GetUnit(1)
|
local TemplateUnit=TemplateGroup:GetUnit(1)
|
||||||
|
|
||||||
--local ishelo=TemplateUnit:HasAttribute("Helicopters")
|
-- General category of spawned group.
|
||||||
--local isbomber=TemplateUnit:HasAttribute("Bombers")
|
|
||||||
--local istransport=TemplateUnit:HasAttribute("Transports")
|
|
||||||
--local isfighter=TemplateUnit:HasAttribute("Battleplanes")
|
|
||||||
|
|
||||||
local group=TemplateGroup
|
local group=TemplateGroup
|
||||||
local istransport=group:HasAttribute("Transports") and group:HasAttribute("Planes")
|
local istransport=group:HasAttribute("Transports") and group:HasAttribute("Planes")
|
||||||
local isawacs=group:HasAttribute("AWACS")
|
local isawacs=group:HasAttribute("AWACS")
|
||||||
@ -1577,8 +1573,17 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
-- Set terminal type.
|
-- Set terminal type.
|
||||||
local termtype=TerminalType
|
local termtype=TerminalType
|
||||||
if spawnonrunway then
|
if spawnonrunway then
|
||||||
termtype=AIRBASE.TerminalType.Runway
|
if spawnonship then
|
||||||
|
-- Looks like there are no runway spawn spots on the stennis!
|
||||||
|
if ishelo then
|
||||||
|
termtype=AIRBASE.TerminalType.HelicopterUsable
|
||||||
|
else
|
||||||
|
termtype=AIRBASE.TerminalType.OpenMedOrBig
|
||||||
|
end
|
||||||
|
else
|
||||||
|
termtype=AIRBASE.TerminalType.Runway
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Scan options. Might make that input somehow.
|
-- Scan options. Might make that input somehow.
|
||||||
@ -1647,9 +1652,9 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
|
|
||||||
-- Get parking data.
|
-- Get parking data.
|
||||||
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
local parkingdata=SpawnAirbase:GetParkingSpotsTable(termtype)
|
||||||
self:T2(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
self:T(string.format("Parking at %s, terminal type %s:", SpawnAirbase:GetName(), tostring(termtype)))
|
||||||
for _,_spot in pairs(parkingdata) do
|
for _,_spot in pairs(parkingdata) do
|
||||||
self:T2(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
self:T(string.format("%s, Termin Index = %3d, Term Type = %03d, Free = %5s, TOAC = %5s, Term ID0 = %3d, Dist2Rwy = %4d",
|
||||||
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
SpawnAirbase:GetName(), _spot.TerminalID, _spot.TerminalType,tostring(_spot.Free),tostring(_spot.TOAC),_spot.TerminalID0,_spot.DistToRwy))
|
||||||
end
|
end
|
||||||
self:T(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, nunits))
|
self:T(string.format("%s at %s: free parking spots = %d - number of units = %d", self.SpawnTemplatePrefix, SpawnAirbase:GetName(), nfree, nunits))
|
||||||
@ -1802,8 +1807,8 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Debug output.
|
-- Debug output.
|
||||||
self:T2(string.format("Group %s unit number %d: Parking = %s",self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking)))
|
self:T(string.format("Group %s unit number %d: Parking = %s",self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking)))
|
||||||
self:T2(string.format("Group %s unit number %d: Parking ID = %s",self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking_id)))
|
self:T(string.format("Group %s unit number %d: Parking ID = %s",self.SpawnTemplatePrefix, UnitID, tostring(UnitTemplate.parking_id)))
|
||||||
self:T2('After Translation SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
|
self:T2('After Translation SpawnTemplate.units['..UnitID..'].x = '..SpawnTemplate.units[UnitID].x..', SpawnTemplate.units['..UnitID..'].y = '..SpawnTemplate.units[UnitID].y)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -1840,6 +1845,66 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude, TerminalT
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Spawn a group on an @{Wrapper.Airbase} at a specific parking spot.
|
||||||
|
-- @param #SPAWN self
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE Airbase The @{Wrapper.Airbase} where to spawn the group.
|
||||||
|
-- @param #table Spots Table of parking spot IDs. Note that these in general are different from the numbering in the mission editor!
|
||||||
|
-- @param #SPAWN.Takeoff Takeoff (Optional) Takeoff type, i.e. either SPAWN.Takeoff.Cold or SPAWN.Takeoff.Hot. Default is Hot.
|
||||||
|
-- @return Wrapper.Group#GROUP The group that was spawned or nil when nothing was spawned.
|
||||||
|
function SPAWN:SpawnAtParkingSpot(Airbase, Spots, Takeoff) -- R2.5
|
||||||
|
self:F({Airbase=Airbase, Spots=Spots, Takeoff=Takeoff})
|
||||||
|
|
||||||
|
-- Ensure that Spots parameter is a table.
|
||||||
|
if type(Spots)~="table" then
|
||||||
|
Spots={Spots}
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get template group.
|
||||||
|
local group=GROUP:FindByName(self.SpawnTemplatePrefix)
|
||||||
|
|
||||||
|
-- Get number of units in group.
|
||||||
|
local nunits=self.SpawnGrouping or #group:GetUnits()
|
||||||
|
|
||||||
|
-- Quick check.
|
||||||
|
if nunits then
|
||||||
|
|
||||||
|
-- Check that number of provided parking spots is large enough.
|
||||||
|
if #Spots<nunits then
|
||||||
|
self:E("ERROR: Number of provided parking spots is less than number of units in group!")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Table of parking data.
|
||||||
|
local Parkingdata={}
|
||||||
|
|
||||||
|
-- Loop over provided Terminal IDs.
|
||||||
|
for _,TerminalID in pairs(Spots) do
|
||||||
|
|
||||||
|
-- Get parking spot data.
|
||||||
|
local spot=Airbase:GetParkingSpotData(TerminalID)
|
||||||
|
|
||||||
|
self:T2({spot=spot})
|
||||||
|
|
||||||
|
if spot and spot.Free then
|
||||||
|
self:T(string.format("Adding parking spot ID=%d TermType=%d", spot.TerminalID, spot.TerminalType))
|
||||||
|
table.insert(Parkingdata, spot)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if #Parkingdata>=nunits then
|
||||||
|
return self:SpawnAtAirbase(Airbase, Takeoff, nil, nil, nil, Parkingdata)
|
||||||
|
else
|
||||||
|
self:E("ERROR: Could not find enough free parking spots!")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
else
|
||||||
|
self:E("ERROR: Could not get number of units in group!")
|
||||||
|
end
|
||||||
|
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Will park a group at an @{Wrapper.Airbase}.
|
--- Will park a group at an @{Wrapper.Airbase}.
|
||||||
--
|
--
|
||||||
@ -3023,6 +3088,9 @@ function SPAWN:_TranslateRotate( SpawnIndex, SpawnRootX, SpawnRootY, SpawnX, Spa
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Get the next index of the groups to be spawned. This method is complicated, as it is used at several spaces.
|
--- Get the next index of the groups to be spawned. This method is complicated, as it is used at several spaces.
|
||||||
|
-- @param #SPAWN self
|
||||||
|
-- @param #number SpawnIndex Spawn index.
|
||||||
|
-- @return #number self.SpawnIndex
|
||||||
function SPAWN:_GetSpawnIndex( SpawnIndex )
|
function SPAWN:_GetSpawnIndex( SpawnIndex )
|
||||||
self:F2( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups, self.SpawnMaxUnitsAlive, self.AliveUnits, #self.SpawnTemplate.units } )
|
self:F2( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups, self.SpawnMaxUnitsAlive, self.AliveUnits, #self.SpawnTemplate.units } )
|
||||||
|
|
||||||
|
|||||||
@ -57,8 +57,10 @@ SEAD = {
|
|||||||
-- -- Defends the Russian SA installations from SEAD attacks.
|
-- -- Defends the Russian SA installations from SEAD attacks.
|
||||||
-- SEAD_RU_SAM_Defenses = SEAD:New( { 'RU SA-6 Kub', 'RU SA-6 Defenses', 'RU MI-26 Troops', 'RU Attack Gori' } )
|
-- SEAD_RU_SAM_Defenses = SEAD:New( { 'RU SA-6 Kub', 'RU SA-6 Defenses', 'RU MI-26 Troops', 'RU Attack Gori' } )
|
||||||
function SEAD:New( SEADGroupPrefixes )
|
function SEAD:New( SEADGroupPrefixes )
|
||||||
|
|
||||||
local self = BASE:Inherit( self, BASE:New() )
|
local self = BASE:Inherit( self, BASE:New() )
|
||||||
self:F( SEADGroupPrefixes )
|
self:F( SEADGroupPrefixes )
|
||||||
|
|
||||||
if type( SEADGroupPrefixes ) == 'table' then
|
if type( SEADGroupPrefixes ) == 'table' then
|
||||||
for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do
|
for SEADGroupPrefixID, SEADGroupPrefix in pairs( SEADGroupPrefixes ) do
|
||||||
self.SEADGroupPrefixes[SEADGroupPrefix] = SEADGroupPrefix
|
self.SEADGroupPrefixes[SEADGroupPrefix] = SEADGroupPrefix
|
||||||
@ -85,7 +87,29 @@ function SEAD:OnEventShot( EventData )
|
|||||||
local SEADWeaponName = EventData.WeaponName -- return weapon type
|
local SEADWeaponName = EventData.WeaponName -- return weapon type
|
||||||
-- Start of the 2nd loop
|
-- Start of the 2nd loop
|
||||||
self:T( "Missile Launched = " .. SEADWeaponName )
|
self:T( "Missile Launched = " .. SEADWeaponName )
|
||||||
if SEADWeaponName == "KH-58" or SEADWeaponName == "KH-25MPU" or SEADWeaponName == "AGM-88" or SEADWeaponName == "KH-31A" or SEADWeaponName == "KH-31P" then -- Check if the missile is a SEAD
|
|
||||||
|
--if SEADWeaponName == "KH-58" or SEADWeaponName == "KH-25MPU" or SEADWeaponName == "AGM-88" or SEADWeaponName == "KH-31A" or SEADWeaponName == "KH-31P" then -- Check if the missile is a SEAD
|
||||||
|
if SEADWeaponName == "weapons.missiles.X_58" --Kh-58U anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.Kh25MP_PRGS1VP" --Kh-25MP anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.X_25MP" --Kh-25MPU anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.X_28" --Kh-28 anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.X_31P" --Kh-31P anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.AGM_45A" --AGM-45A anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.AGM_45" --AGM-45B anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.AGM_88" --AGM-88C anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.AGM_122" --AGM-122 Sidearm anti-radiation missiles fired
|
||||||
|
or
|
||||||
|
SEADWeaponName == "weapons.missiles.ALARM" --ALARM anti-radiation missiles fired
|
||||||
|
then
|
||||||
|
|
||||||
local _evade = math.random (1,100) -- random number for chance of evading action
|
local _evade = math.random (1,100) -- random number for chance of evading action
|
||||||
local _targetMim = EventData.Weapon:getTarget() -- Identify target
|
local _targetMim = EventData.Weapon:getTarget() -- Identify target
|
||||||
local _targetMimname = Unit.getName(_targetMim)
|
local _targetMimname = Unit.getName(_targetMim)
|
||||||
@ -111,47 +135,62 @@ function SEAD:OnEventShot( EventData )
|
|||||||
self:T( _targetskill )
|
self:T( _targetskill )
|
||||||
if self.TargetSkill[_targetskill] then
|
if self.TargetSkill[_targetskill] then
|
||||||
if (_evade > self.TargetSkill[_targetskill].Evade) then
|
if (_evade > self.TargetSkill[_targetskill].Evade) then
|
||||||
|
|
||||||
self:T( string.format("Evading, target skill " ..string.format(_targetskill)) )
|
self:T( string.format("Evading, target skill " ..string.format(_targetskill)) )
|
||||||
|
|
||||||
local _targetMim = Weapon.getTarget(SEADWeapon)
|
local _targetMim = Weapon.getTarget(SEADWeapon)
|
||||||
local _targetMimname = Unit.getName(_targetMim)
|
local _targetMimname = Unit.getName(_targetMim)
|
||||||
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
|
local _targetMimgroup = Unit.getGroup(Weapon.getTarget(SEADWeapon))
|
||||||
local _targetMimcont= _targetMimgroup:getController()
|
local _targetMimcont= _targetMimgroup:getController()
|
||||||
|
|
||||||
routines.groupRandomDistSelf(_targetMimgroup,300,'Diamond',250,20) -- move randomly
|
routines.groupRandomDistSelf(_targetMimgroup,300,'Diamond',250,20) -- move randomly
|
||||||
|
|
||||||
local SuppressedGroups1 = {} -- unit suppressed radar off for a random time
|
local SuppressedGroups1 = {} -- unit suppressed radar off for a random time
|
||||||
|
|
||||||
local function SuppressionEnd1(id)
|
local function SuppressionEnd1(id)
|
||||||
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
|
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
|
||||||
SuppressedGroups1[id.groupName] = nil
|
SuppressedGroups1[id.groupName] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local id = {
|
local id = {
|
||||||
groupName = _targetMimgroup,
|
groupName = _targetMimgroup,
|
||||||
ctrl = _targetMimcont
|
ctrl = _targetMimcont
|
||||||
}
|
}
|
||||||
|
|
||||||
local delay1 = math.random(self.TargetSkill[_targetskill].DelayOff[1], self.TargetSkill[_targetskill].DelayOff[2])
|
local delay1 = math.random(self.TargetSkill[_targetskill].DelayOff[1], self.TargetSkill[_targetskill].DelayOff[2])
|
||||||
|
|
||||||
if SuppressedGroups1[id.groupName] == nil then
|
if SuppressedGroups1[id.groupName] == nil then
|
||||||
|
|
||||||
SuppressedGroups1[id.groupName] = {
|
SuppressedGroups1[id.groupName] = {
|
||||||
SuppressionEndTime1 = timer.getTime() + delay1,
|
SuppressionEndTime1 = timer.getTime() + delay1,
|
||||||
SuppressionEndN1 = SuppressionEndCounter1 --Store instance of SuppressionEnd() scheduled function
|
SuppressionEndN1 = SuppressionEndCounter1 --Store instance of SuppressionEnd() scheduled function
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.setOption(_targetMimcont, AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
|
Controller.setOption(_targetMimcont, AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.GREEN)
|
||||||
timer.scheduleFunction(SuppressionEnd1, id, SuppressedGroups1[id.groupName].SuppressionEndTime1) --Schedule the SuppressionEnd() function
|
timer.scheduleFunction(SuppressionEnd1, id, SuppressedGroups1[id.groupName].SuppressionEndTime1) --Schedule the SuppressionEnd() function
|
||||||
--trigger.action.outText( string.format("Radar Off " ..string.format(delay1)), 20)
|
--trigger.action.outText( string.format("Radar Off " ..string.format(delay1)), 20)
|
||||||
end
|
end
|
||||||
|
|
||||||
local SuppressedGroups = {}
|
local SuppressedGroups = {}
|
||||||
|
|
||||||
local function SuppressionEnd(id)
|
local function SuppressionEnd(id)
|
||||||
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.RED)
|
id.ctrl:setOption(AI.Option.Ground.id.ALARM_STATE,AI.Option.Ground.val.ALARM_STATE.RED)
|
||||||
SuppressedGroups[id.groupName] = nil
|
SuppressedGroups[id.groupName] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local id = {
|
local id = {
|
||||||
groupName = _targetMimgroup,
|
groupName = _targetMimgroup,
|
||||||
ctrl = _targetMimcont
|
ctrl = _targetMimcont
|
||||||
}
|
}
|
||||||
|
|
||||||
local delay = math.random(self.TargetSkill[_targetskill].DelayOn[1], self.TargetSkill[_targetskill].DelayOn[2])
|
local delay = math.random(self.TargetSkill[_targetskill].DelayOn[1], self.TargetSkill[_targetskill].DelayOn[2])
|
||||||
|
|
||||||
if SuppressedGroups[id.groupName] == nil then
|
if SuppressedGroups[id.groupName] == nil then
|
||||||
SuppressedGroups[id.groupName] = {
|
SuppressedGroups[id.groupName] = {
|
||||||
SuppressionEndTime = timer.getTime() + delay,
|
SuppressionEndTime = timer.getTime() + delay,
|
||||||
SuppressionEndN = SuppressionEndCounter --Store instance of SuppressionEnd() scheduled function
|
SuppressionEndN = SuppressionEndCounter --Store instance of SuppressionEnd() scheduled function
|
||||||
}
|
}
|
||||||
|
|
||||||
timer.scheduleFunction(SuppressionEnd, id, SuppressedGroups[id.groupName].SuppressionEndTime) --Schedule the SuppressionEnd() function
|
timer.scheduleFunction(SuppressionEnd, id, SuppressedGroups[id.groupName].SuppressionEndTime) --Schedule the SuppressionEnd() function
|
||||||
--trigger.action.outText( string.format("Radar On " ..string.format(delay)), 20)
|
--trigger.action.outText( string.format("Radar On " ..string.format(delay)), 20)
|
||||||
end
|
end
|
||||||
|
|||||||
@ -205,7 +205,7 @@
|
|||||||
-- @field Core.Set#SET_GROUP excludesetAI AI groups in this set will be explicitly excluded from handling by the airboss and not forced into the Marshal pattern.
|
-- @field Core.Set#SET_GROUP excludesetAI AI groups in this set will be explicitly excluded from handling by the airboss and not forced into the Marshal pattern.
|
||||||
-- @field #boolean menusingle If true, menu is optimized for a single carrier.
|
-- @field #boolean menusingle If true, menu is optimized for a single carrier.
|
||||||
-- @field #number collisiondist Distance up to which collision checks are done.
|
-- @field #number collisiondist Distance up to which collision checks are done.
|
||||||
-- @field #nubmer holdtimestamp Timestamp when the carrier first came to an unexpected hold.
|
-- @field #number holdtimestamp Timestamp when the carrier first came to an unexpected hold.
|
||||||
-- @field #number Tmessage Default duration in seconds messages are displayed to players.
|
-- @field #number Tmessage Default duration in seconds messages are displayed to players.
|
||||||
-- @field #string soundfolder Folder within the mission (miz) file where airboss sound files are located.
|
-- @field #string soundfolder Folder within the mission (miz) file where airboss sound files are located.
|
||||||
-- @field #string soundfolderLSO Folder withing the mission (miz) file where LSO sound files are stored.
|
-- @field #string soundfolderLSO Folder withing the mission (miz) file where LSO sound files are stored.
|
||||||
@ -1559,7 +1559,7 @@ AIRBOSS.Difficulty={
|
|||||||
-- @field #number Time Time in seconds.
|
-- @field #number Time Time in seconds.
|
||||||
-- @field #number Rho Distance in meters.
|
-- @field #number Rho Distance in meters.
|
||||||
-- @field #number X Distance in meters.
|
-- @field #number X Distance in meters.
|
||||||
-- @field #nubmer Z Distance in meters.
|
-- @field #number Z Distance in meters.
|
||||||
-- @field #number AoA Angle of Attack.
|
-- @field #number AoA Angle of Attack.
|
||||||
-- @field #number Alt Altitude in meters.
|
-- @field #number Alt Altitude in meters.
|
||||||
-- @field #number GSE Glideslope error in degrees.
|
-- @field #number GSE Glideslope error in degrees.
|
||||||
@ -1681,7 +1681,7 @@ AIRBOSS.MenuF10Root=nil
|
|||||||
|
|
||||||
--- Airboss class version.
|
--- Airboss class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
AIRBOSS.version="1.0.4"
|
AIRBOSS.version="1.0.5"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@ -2128,6 +2128,13 @@ function AIRBOSS:New(carriername, alias)
|
|||||||
-- @param #AIRBOSS self
|
-- @param #AIRBOSS self
|
||||||
-- @param #number delay Delay in seconds.
|
-- @param #number delay Delay in seconds.
|
||||||
|
|
||||||
|
--- On after "RecoveryStop" user function. Called when recovery of aircraft is stopped.
|
||||||
|
-- @function [parent=#AIRBOSS] OnAfterRecoveryStop
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
|
||||||
|
|
||||||
--- Triggers the FSM event "RecoveryPause" that pauses the recovery of aircraft.
|
--- Triggers the FSM event "RecoveryPause" that pauses the recovery of aircraft.
|
||||||
-- @function [parent=#AIRBOSS] RecoveryPause
|
-- @function [parent=#AIRBOSS] RecoveryPause
|
||||||
@ -3063,6 +3070,15 @@ function AIRBOSS:SetRecoveryTanker(recoverytanker)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Define an AWACS associated with the carrier.
|
||||||
|
-- @param #AIRBOSS self
|
||||||
|
-- @param Ops.RecoveryTanker#RECOVERYTANKER awacs AWACS (recovery tanker) object.
|
||||||
|
-- @return #AIRBOSS self
|
||||||
|
function AIRBOSS:SetAWACS(awacs)
|
||||||
|
self.awacs=awacs
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set default player skill. New players will be initialized with this skill.
|
--- Set default player skill. New players will be initialized with this skill.
|
||||||
--
|
--
|
||||||
-- * "Flight Student" = @{#AIRBOSS.Difficulty.Easy}
|
-- * "Flight Student" = @{#AIRBOSS.Difficulty.Easy}
|
||||||
@ -5914,38 +5930,48 @@ function AIRBOSS:_ScanCarrierZone()
|
|||||||
-- Debug info.
|
-- Debug info.
|
||||||
self:T3(self.lid..string.format("Known AI flight group %s closed in by %.1f NM", knownflight.groupname, UTILS.MetersToNM(closein)))
|
self:T3(self.lid..string.format("Known AI flight group %s closed in by %.1f NM", knownflight.groupname, UTILS.MetersToNM(closein)))
|
||||||
|
|
||||||
-- Send AI flight to marshal stack if group closes in more than 5 and has initial flag value.
|
-- Is this group the tanker?
|
||||||
if closein>UTILS.NMToMeters(5) and knownflight.flag==-100 and iscarriersquad then
|
local istanker=self.tanker and self.tanker.tanker:GetName()==groupname
|
||||||
|
|
||||||
-- Check that we do not add a recovery tanker for marshaling.
|
-- Is this group the AWACS?
|
||||||
if self.tanker and self.tanker.tanker:GetName()==groupname then
|
local isawacs=self.awacs and self.awacs.tanker:GetName()==groupname
|
||||||
|
|
||||||
|
-- Send tanker to marshal stack?
|
||||||
|
local tanker2marshal = istanker and self.tanker:IsReturning() and self.tanker.airbase:GetName()==self.airbase:GetName() and knownflight.flag==-100
|
||||||
|
|
||||||
|
-- Send AWACS to marhsal stack?
|
||||||
|
local awacs2marshal = isawacs and self.awacs:IsReturning() and self.awacs.airbase:GetName()==self.airbase:GetName() and knownflight.flag==-100
|
||||||
|
|
||||||
|
-- Put flight into Marshal.
|
||||||
|
local putintomarshal=closein>UTILS.NMToMeters(5) and knownflight.flag==-100 and iscarriersquad and istanker==false and isawacs==false
|
||||||
|
|
||||||
|
-- Send AI flight to marshal stack if group closes in more than 5 and has initial flag value.
|
||||||
|
if putintomarshal or tanker2marshal or awacs2marshal then
|
||||||
|
|
||||||
|
-- Get the next free stack for current recovery case.
|
||||||
|
local stack=self:_GetFreeStack(knownflight.ai)
|
||||||
|
|
||||||
|
-- Repawn.
|
||||||
|
local respawn=self.respawnAI --or tanker2marshal
|
||||||
|
|
||||||
-- Don't touch the recovery tanker!
|
if stack then
|
||||||
|
|
||||||
|
-- Send AI to marshal stack. We respawn the group to clean possible departure and destination airbases.
|
||||||
|
self:_MarshalAI(knownflight, stack, respawn)
|
||||||
|
|
||||||
else
|
else
|
||||||
|
|
||||||
-- Get the next free stack for current recovery case.
|
-- Send AI to orbit outside 10 NM zone and wait until the next Marshal stack is available.
|
||||||
local stack=self:_GetFreeStack(knownflight.ai)
|
if not self:_InQueue(self.Qwaiting, knownflight.group) then
|
||||||
|
self:_WaitAI(knownflight, respawn) -- Group is respawned to clear any attached airfields.
|
||||||
if stack then
|
|
||||||
|
|
||||||
-- Send AI to marshal stack. We respawn the group to clean possible departure and destination airbases.
|
|
||||||
self:_MarshalAI(knownflight, stack, self.respawnAI)
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
-- Send AI to orbit outside 10 NM zone and wait until the next Marshal stack is available.
|
|
||||||
if not self:_InQueue(self.Qwaiting, knownflight.group) then
|
|
||||||
self:_WaitAI(knownflight, self.respawnAI) -- Group is respawned to clear any attached airfields.
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Break the loop to not have all flights at once! Spams the message screen.
|
end
|
||||||
break
|
|
||||||
|
-- Break the loop to not have all flights at once! Spams the message screen.
|
||||||
end -- Tanker
|
break
|
||||||
end -- Closed in
|
|
||||||
|
end -- Closed in or tanker/AWACS
|
||||||
end -- AI
|
end -- AI
|
||||||
|
|
||||||
else
|
else
|
||||||
@ -14329,7 +14355,7 @@ end
|
|||||||
-- @param #number delay Delay in seconds, before the message is broadcasted.
|
-- @param #number delay Delay in seconds, before the message is broadcasted.
|
||||||
-- @param #number interval Interval in seconds after the last sound has been played.
|
-- @param #number interval Interval in seconds after the last sound has been played.
|
||||||
-- @param #boolean click If true, play radio click at the end.
|
-- @param #boolean click If true, play radio click at the end.
|
||||||
-- @param #booelan pilotcall If true, it's a pilot call.
|
-- @param #boolean pilotcall If true, it's a pilot call.
|
||||||
function AIRBOSS:RadioTransmission(radio, call, loud, delay, interval, click, pilotcall)
|
function AIRBOSS:RadioTransmission(radio, call, loud, delay, interval, click, pilotcall)
|
||||||
self:F2({radio=radio, call=call, loud=loud, delay=delay, interval=interval, click=click})
|
self:F2({radio=radio, call=call, loud=loud, delay=delay, interval=interval, click=click})
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,8 @@
|
|||||||
-- @field #number callsignname Number for the callsign name.
|
-- @field #number callsignname Number for the callsign name.
|
||||||
-- @field #number callsignnumber Number of the callsign name.
|
-- @field #number callsignnumber Number of the callsign name.
|
||||||
-- @field #string modex Tail number of the tanker.
|
-- @field #string modex Tail number of the tanker.
|
||||||
|
-- @field #boolean eplrs If true, enable data link, e.g. if used as AWACS.
|
||||||
|
-- @field #boolean recovery If true, tanker will recover using the AIRBOSS marshal pattern.
|
||||||
-- @extends Core.Fsm#FSM
|
-- @extends Core.Fsm#FSM
|
||||||
|
|
||||||
--- Recovery Tanker.
|
--- Recovery Tanker.
|
||||||
@ -295,15 +297,16 @@ RECOVERYTANKER = {
|
|||||||
callsignnumber = nil,
|
callsignnumber = nil,
|
||||||
modex = nil,
|
modex = nil,
|
||||||
eplrs = nil,
|
eplrs = nil,
|
||||||
|
recovery = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
--- Unique ID (global).
|
--- Unique ID (global).
|
||||||
-- @field #number UID Unique ID (global).
|
-- @field #number UID Unique ID (global).
|
||||||
RECOVERYTANKER.UID=0
|
_RECOVERYTANKERID=0
|
||||||
|
|
||||||
--- Class version.
|
--- Class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
RECOVERYTANKER.version="1.0.7"
|
RECOVERYTANKER.version="1.0.8"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@ -349,16 +352,16 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
|
|||||||
self.tankergroupname=tankergroupname
|
self.tankergroupname=tankergroupname
|
||||||
|
|
||||||
-- Increase unique ID.
|
-- Increase unique ID.
|
||||||
RECOVERYTANKER.UID=RECOVERYTANKER.UID+1
|
_RECOVERYTANKERID=_RECOVERYTANKERID+1
|
||||||
|
|
||||||
-- Unique ID of this tanker.
|
-- Unique ID of this tanker.
|
||||||
self.uid=RECOVERYTANKER.UID
|
self.uid=_RECOVERYTANKERID
|
||||||
|
|
||||||
-- Save self in static object. Easier to retrieve later.
|
-- Save self in static object. Easier to retrieve later.
|
||||||
self.carrier:SetState(self.carrier, string.format("RECOVERYTANKER_%d", self.uid) , self)
|
self.carrier:SetState(self.carrier, string.format("RECOVERYTANKER_%d", self.uid) , self)
|
||||||
|
|
||||||
-- Set unique spawn alias.
|
-- Set unique spawn alias.
|
||||||
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.tankergroupname, RECOVERYTANKER.UID)
|
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.tankergroupname, _RECOVERYTANKERID)
|
||||||
|
|
||||||
-- Log ID.
|
-- Log ID.
|
||||||
self.lid=string.format("RECOVERYTANKER %s | ", self.alias)
|
self.lid=string.format("RECOVERYTANKER %s | ", self.alias)
|
||||||
@ -377,6 +380,7 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
|
|||||||
self:SetPatternUpdateHeading()
|
self:SetPatternUpdateHeading()
|
||||||
self:SetPatternUpdateInterval()
|
self:SetPatternUpdateInterval()
|
||||||
self:SetAWACS(false)
|
self:SetAWACS(false)
|
||||||
|
self:SetRecoveryAirboss(false)
|
||||||
|
|
||||||
-- Debug trace.
|
-- Debug trace.
|
||||||
if false then
|
if false then
|
||||||
@ -399,6 +403,7 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
|
|||||||
self:AddTransition("*", "RefuelStop", "Running") -- Tanker starts to refuel.
|
self:AddTransition("*", "RefuelStop", "Running") -- Tanker starts to refuel.
|
||||||
self:AddTransition("*", "Run", "Running") -- Tanker starts normal operation again.
|
self:AddTransition("*", "Run", "Running") -- Tanker starts normal operation again.
|
||||||
self:AddTransition("Running", "RTB", "Returning") -- Tanker is returning to base (for fuel).
|
self:AddTransition("Running", "RTB", "Returning") -- Tanker is returning to base (for fuel).
|
||||||
|
self:AddTransition("Returning", "Returned", "Returned") -- Tanker has returned to its airbase (i.e. landed).
|
||||||
self:AddTransition("*", "Status", "*") -- Status update.
|
self:AddTransition("*", "Status", "*") -- Status update.
|
||||||
self:AddTransition("Running", "PatternUpdate", "*") -- Update pattern wrt to carrier.
|
self:AddTransition("Running", "PatternUpdate", "*") -- Update pattern wrt to carrier.
|
||||||
self:AddTransition("*", "Stop", "Stopped") -- Stop the FSM.
|
self:AddTransition("*", "Stop", "Stopped") -- Stop the FSM.
|
||||||
@ -472,6 +477,26 @@ function RECOVERYTANKER:New(carrierunit, tankergroupname)
|
|||||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase where the tanker should return to.
|
-- @param Wrapper.Airbase#AIRBASE airbase The airbase where the tanker should return to.
|
||||||
|
|
||||||
|
|
||||||
|
--- Triggers the FSM event "Returned" after the tanker has landed.
|
||||||
|
-- @function [parent=#RECOVERYTANKER] Returned
|
||||||
|
-- @param #RECOVERYTANKER self
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the tanker has landed.
|
||||||
|
|
||||||
|
--- Triggers the delayed FSM event "Returned" after the tanker has landed.
|
||||||
|
-- @function [parent=#RECOVERYTANKER] __Returned
|
||||||
|
-- @param #RECOVERYTANKER self
|
||||||
|
-- @param #number delay Delay in seconds.
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the tanker has landed.
|
||||||
|
|
||||||
|
--- On after "Returned" event user function. Called when a the the tanker has landed at an airbase.
|
||||||
|
-- @function [parent=#RECOVERYTANKER] OnAfterReturned
|
||||||
|
-- @param #RECOVERYTANKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE airbase The airbase the tanker has landed.
|
||||||
|
|
||||||
|
|
||||||
--- Triggers the FSM event "Status" that updates the tanker status.
|
--- Triggers the FSM event "Status" that updates the tanker status.
|
||||||
-- @function [parent=#RECOVERYTANKER] Status
|
-- @function [parent=#RECOVERYTANKER] Status
|
||||||
-- @param #RECOVERYTANKER self
|
-- @param #RECOVERYTANKER self
|
||||||
@ -596,6 +621,19 @@ function RECOVERYTANKER:SetHomeBase(airbase)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Activate recovery by the AIRBOSS class. Tanker will get a Marshal stack and perform a CASE I, II or III recovery when RTB.
|
||||||
|
-- @param #RECOVERYTANKER self
|
||||||
|
-- @param #boolean switch If true or nil, recovery is done by AIRBOSS.
|
||||||
|
-- @return #RECOVERYTANKER self
|
||||||
|
function RECOVERYTANKER:SetRecoveryAirboss(switch)
|
||||||
|
if switch==true or switch==nil then
|
||||||
|
self.recovery=true
|
||||||
|
else
|
||||||
|
self.recovery=false
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Set that the group takes the roll of an AWACS instead of a refueling tanker.
|
--- Set that the group takes the roll of an AWACS instead of a refueling tanker.
|
||||||
-- @param #RECOVERYTANKER self
|
-- @param #RECOVERYTANKER self
|
||||||
-- @param #boolean switch If true or nil, set roll AWACS.
|
-- @param #boolean switch If true or nil, set roll AWACS.
|
||||||
@ -830,6 +868,7 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
|||||||
|
|
||||||
-- Handle events.
|
-- Handle events.
|
||||||
self:HandleEvent(EVENTS.EngineShutdown)
|
self:HandleEvent(EVENTS.EngineShutdown)
|
||||||
|
self:HandleEvent(EVENTS.Land)
|
||||||
self:HandleEvent(EVENTS.Refueling, self._RefuelingStart) --Need explicit functions since OnEventRefueling and OnEventRefuelingStop did not hook!
|
self:HandleEvent(EVENTS.Refueling, self._RefuelingStart) --Need explicit functions since OnEventRefueling and OnEventRefuelingStop did not hook!
|
||||||
self:HandleEvent(EVENTS.RefuelingStop, self._RefuelingStop)
|
self:HandleEvent(EVENTS.RefuelingStop, self._RefuelingStop)
|
||||||
self:HandleEvent(EVENTS.Crash, self._OnEventCrashOrDead)
|
self:HandleEvent(EVENTS.Crash, self._OnEventCrashOrDead)
|
||||||
@ -865,7 +904,7 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
|||||||
else
|
else
|
||||||
|
|
||||||
-- Check if an uncontrolled tanker group was requested.
|
-- Check if an uncontrolled tanker group was requested.
|
||||||
if self.useuncontrolled then
|
if self.uncontrolledac then
|
||||||
|
|
||||||
-- Use an uncontrolled aircraft group.
|
-- Use an uncontrolled aircraft group.
|
||||||
self.tanker=GROUP:FindByName(self.tankergroupname)
|
self.tanker=GROUP:FindByName(self.tankergroupname)
|
||||||
@ -884,14 +923,14 @@ function RECOVERYTANKER:onafterStart(From, Event, To)
|
|||||||
else
|
else
|
||||||
|
|
||||||
-- Spawn tanker at airbase.
|
-- Spawn tanker at airbase.
|
||||||
self.tanker=Spawn:SpawnAtAirbase(self.airbase, self.takeoff)
|
self.tanker=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, AIRBASE.TerminalType.OpenMedOrBig)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Initialize route. self.distStern<0!
|
-- Initialize route. self.distStern<0!
|
||||||
SCHEDULER:New(nil, self._InitRoute, {self, -self.distStern+UTILS.NMToMeters(3)}, 1)
|
self:ScheduleOnce(1, self._InitRoute, self, -self.distStern+UTILS.NMToMeters(3))
|
||||||
|
|
||||||
-- Create tanker beacon.
|
-- Create tanker beacon.
|
||||||
if self.TACANon then
|
if self.TACANon then
|
||||||
@ -929,7 +968,7 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
|||||||
-- Get current time.
|
-- Get current time.
|
||||||
local time=timer.getTime()
|
local time=timer.getTime()
|
||||||
|
|
||||||
if self.tanker:IsAlive() then
|
if self.tanker and self.tanker:IsAlive() then
|
||||||
|
|
||||||
---------------------
|
---------------------
|
||||||
-- TANKER is ALIVE --
|
-- TANKER is ALIVE --
|
||||||
@ -937,8 +976,14 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
-- Get fuel of tanker.
|
-- Get fuel of tanker.
|
||||||
local fuel=self.tanker:GetFuel()*100
|
local fuel=self.tanker:GetFuel()*100
|
||||||
local text=string.format("Recovery tanker %s: state=%s fuel=%.1f", self.tanker:GetName(), self:GetState(), fuel)
|
local life=self.tanker:GetUnit(1):GetLife()
|
||||||
|
local life0=self.tanker:GetUnit(1):GetLife0()
|
||||||
|
local lifeR=self.tanker:GetUnit(1):GetLifeRelative()
|
||||||
|
|
||||||
|
-- Report fuel and life.
|
||||||
|
local text=string.format("Recovery tanker %s: state=%s fuel=%.1f, life=%.1f/%.1f=%d", self.tanker:GetName(), self:GetState(), fuel, life, life0, lifeR*100)
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
|
MESSAGE:New(text, 10):ToAllIf(self.Debug)
|
||||||
|
|
||||||
-- Check if tanker is running and not RTBing or refueling.
|
-- Check if tanker is running and not RTBing or refueling.
|
||||||
if self:IsRunning() then
|
if self:IsRunning() then
|
||||||
@ -947,7 +992,7 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
|||||||
if fuel<self.lowfuel then
|
if fuel<self.lowfuel then
|
||||||
|
|
||||||
-- Check if spawn in air is activated.
|
-- Check if spawn in air is activated.
|
||||||
if self.takeoff==SPAWN.Takeoff.Air or self.respawninair then
|
if (self.takeoff==SPAWN.Takeoff.Air or self.respawninair) and not self.recovery then
|
||||||
|
|
||||||
-- Check that respawn should happen.
|
-- Check that respawn should happen.
|
||||||
if self.respawn then
|
if self.respawn then
|
||||||
@ -1028,6 +1073,8 @@ function RECOVERYTANKER:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
if not self:IsStopped() then
|
if not self:IsStopped() then
|
||||||
|
|
||||||
|
self:E(self.lid.."Recovery tanker is NOT alive (and not stopped)!")
|
||||||
|
|
||||||
-- Stop FSM.
|
-- Stop FSM.
|
||||||
self:Stop()
|
self:Stop()
|
||||||
|
|
||||||
@ -1133,7 +1180,14 @@ function RECOVERYTANKER:onafterRTB(From, Event, To, airbase)
|
|||||||
|
|
||||||
-- Set landing waypoint.
|
-- Set landing waypoint.
|
||||||
wp[1]=self.tanker:GetCoordinate():WaypointAirTurningPoint(nil, speed, {}, "Current Position")
|
wp[1]=self.tanker:GetCoordinate():WaypointAirTurningPoint(nil, speed, {}, "Current Position")
|
||||||
wp[2]=airbase:GetCoordinate():SetAltitude(500):WaypointAirLanding(speed, airbase, nil, "Land at airbase")
|
|
||||||
|
|
||||||
|
if self.recovery then
|
||||||
|
-- Fly a bit until the airboss takes over.
|
||||||
|
wp[2]=self.tanker:GetCoordinate():Translate(UTILS.NMToMeters(10), self.tanker:GetHeading(), true):WaypointAirTurningPoint(nil, speed, {}, "WP")
|
||||||
|
else
|
||||||
|
wp[2]=airbase:GetCoordinate():SetAltitude(500):WaypointAirLanding(speed, airbase, nil, "Land at airbase")
|
||||||
|
end
|
||||||
|
|
||||||
-- Initialize WP and route tanker.
|
-- Initialize WP and route tanker.
|
||||||
self.tanker:WayPointInitialize(wp)
|
self.tanker:WayPointInitialize(wp)
|
||||||
@ -1142,6 +1196,25 @@ function RECOVERYTANKER:onafterRTB(From, Event, To, airbase)
|
|||||||
self.tanker:Route(wp, 1)
|
self.tanker:Route(wp, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- On after Returned event. The tanker has landed.
|
||||||
|
-- @param #RECOVERYTANKER self
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To To state.
|
||||||
|
-- @param Wrapper.Airbase#AIRBASE airbase The base at which the tanker landed.
|
||||||
|
function RECOVERYTANKER:onafterReturned(From, Event, To, airbase)
|
||||||
|
|
||||||
|
if airbase then
|
||||||
|
local airbasename=airbase:GetName()
|
||||||
|
self:I(self.lid..string.format("Tanker returned to airbase %s", tostring(airbasename)))
|
||||||
|
else
|
||||||
|
self:E(self.lid..string.format("WARNING: Tanker landed but airbase (EventData.Place) is nil!"))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- On after Stop event. Unhandle events and stop status updates.
|
--- On after Stop event. Unhandle events and stop status updates.
|
||||||
-- @param #RECOVERYTANKER self
|
-- @param #RECOVERYTANKER self
|
||||||
-- @param #string From From state.
|
-- @param #string From From state.
|
||||||
@ -1150,14 +1223,18 @@ end
|
|||||||
function RECOVERYTANKER:onafterStop(From, Event, To)
|
function RECOVERYTANKER:onafterStop(From, Event, To)
|
||||||
|
|
||||||
-- Unhandle events.
|
-- Unhandle events.
|
||||||
|
self:UnHandleEvent(EVENTS.Land)
|
||||||
self:UnHandleEvent(EVENTS.EngineShutdown)
|
self:UnHandleEvent(EVENTS.EngineShutdown)
|
||||||
self:UnHandleEvent(EVENTS.Refueling)
|
self:UnHandleEvent(EVENTS.Refueling)
|
||||||
self:UnHandleEvent(EVENTS.RefuelingStop)
|
self:UnHandleEvent(EVENTS.RefuelingStop)
|
||||||
self:UnHandleEvent(EVENTS.Dead)
|
self:UnHandleEvent(EVENTS.Dead)
|
||||||
self:UnHandleEvent(EVENTS.Crash)
|
self:UnHandleEvent(EVENTS.Crash)
|
||||||
|
|
||||||
|
-- Clear all pending FSM events.
|
||||||
|
self.CallScheduler:Clear()
|
||||||
|
|
||||||
-- If tanker is alive, despawn it.
|
-- If tanker is alive, despawn it.
|
||||||
if self.helo and self.helo:IsAlive() then
|
if self.tanker and self.tanker:IsAlive() then
|
||||||
self:I(self.lid.."Stopping FSM and despawning tanker.")
|
self:I(self.lid.."Stopping FSM and despawning tanker.")
|
||||||
self.tanker:Destroy()
|
self.tanker:Destroy()
|
||||||
else
|
else
|
||||||
@ -1170,6 +1247,42 @@ end
|
|||||||
-- EVENT functions
|
-- EVENT functions
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
--- Event handler for landing of recovery tanker.
|
||||||
|
-- @param #RECOVERYTANKER self
|
||||||
|
-- @param Core.Event#EVENTDATA EventData Event data.
|
||||||
|
function RECOVERYTANKER:OnEventLand(EventData)
|
||||||
|
|
||||||
|
-- Group that shut down the engine.
|
||||||
|
local group=EventData.IniGroup --Wrapper.Group#GROUP
|
||||||
|
|
||||||
|
-- Check if group is alive.
|
||||||
|
if group and group:IsAlive() then
|
||||||
|
|
||||||
|
-- Group name. When spawning it will have #001 attached.
|
||||||
|
local groupname=group:GetName()
|
||||||
|
|
||||||
|
-- Check that we have the right group and that it should be respawned.
|
||||||
|
if groupname==self.tanker:GetName() then
|
||||||
|
|
||||||
|
local airbase=nil --Wrapper.Airbase#AIRBASE
|
||||||
|
local airbasename="unknown"
|
||||||
|
if EventData.Place then
|
||||||
|
airbase=EventData.Plase
|
||||||
|
airbasename=airbase:GetName()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Debug info.
|
||||||
|
local text=string.format("Recovery tanker group %s landed at airbase %s.", group:GetName(), airbasename)
|
||||||
|
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||||
|
self:T(self.lid..text)
|
||||||
|
|
||||||
|
-- Trigger returned event.
|
||||||
|
self:__Returned(1, airbase)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
--- Event handler for engine shutdown of recovery tanker.
|
--- Event handler for engine shutdown of recovery tanker.
|
||||||
-- Respawn tanker group once it landed because it was out of fuel.
|
-- Respawn tanker group once it landed because it was out of fuel.
|
||||||
-- @param #RECOVERYTANKER self
|
-- @param #RECOVERYTANKER self
|
||||||
@ -1180,7 +1293,7 @@ function RECOVERYTANKER:OnEventEngineShutdown(EventData)
|
|||||||
local group=EventData.IniGroup --Wrapper.Group#GROUP
|
local group=EventData.IniGroup --Wrapper.Group#GROUP
|
||||||
|
|
||||||
-- Check if group is alive.
|
-- Check if group is alive.
|
||||||
if group:IsAlive() then
|
if group and group:IsAlive() then
|
||||||
|
|
||||||
-- Group name. When spawning it will have #001 attached.
|
-- Group name. When spawning it will have #001 attached.
|
||||||
local groupname=group:GetName()
|
local groupname=group:GetName()
|
||||||
@ -1219,8 +1332,7 @@ function RECOVERYTANKER:OnEventEngineShutdown(EventData)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Initial route.
|
-- Initial route.
|
||||||
SCHEDULER:New(nil, self._InitRoute, {self, -self.distStern+UTILS.NMToMeters(3)}, 2)
|
SCHEDULER:New(nil, self._InitRoute, {self, -self.distStern+UTILS.NMToMeters(3)}, 2)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
@ -1503,7 +1615,7 @@ function RECOVERYTANKER:_ActivateTACAN(delay)
|
|||||||
self.beacon:ActivateTACAN(self.TACANchannel, self.TACANmode, self.TACANmorse, true)
|
self.beacon:ActivateTACAN(self.TACANchannel, self.TACANmode, self.TACANmorse, true)
|
||||||
|
|
||||||
else
|
else
|
||||||
self:E("ERROR: Recovery tanker is not alive!")
|
self:E(self.lid.."ERROR: Recovery tanker is not alive!")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@ -231,11 +231,11 @@ RESCUEHELO = {
|
|||||||
|
|
||||||
--- Unique ID (global).
|
--- Unique ID (global).
|
||||||
-- @field #number uid Unique ID (global).
|
-- @field #number uid Unique ID (global).
|
||||||
RESCUEHELO.UID=0
|
_RESCUEHELOID=0
|
||||||
|
|
||||||
--- Class version.
|
--- Class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
RESCUEHELO.version="1.0.7"
|
RESCUEHELO.version="1.0.8"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@ -277,16 +277,16 @@ function RESCUEHELO:New(carrierunit, helogroupname)
|
|||||||
self.helogroupname=helogroupname
|
self.helogroupname=helogroupname
|
||||||
|
|
||||||
-- Increase ID.
|
-- Increase ID.
|
||||||
RESCUEHELO.UID=RESCUEHELO.UID+1
|
_RESCUEHELOID=_RESCUEHELOID+1
|
||||||
|
|
||||||
-- Unique ID of this helo.
|
-- Unique ID of this helo.
|
||||||
self.uid=RESCUEHELO.UID
|
self.uid=_RESCUEHELOID
|
||||||
|
|
||||||
-- Save self in static object. Easier to retrieve later.
|
-- Save self in static object. Easier to retrieve later.
|
||||||
self.carrier:SetState(self.carrier, string.format("RESCUEHELO_%d", self.uid) , self)
|
self.carrier:SetState(self.carrier, string.format("RESCUEHELO_%d", self.uid) , self)
|
||||||
|
|
||||||
-- Set unique spawn alias.
|
-- Set unique spawn alias.
|
||||||
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.helogroupname, RESCUEHELO.UID)
|
self.alias=string.format("%s_%s_%02d", self.carrier:GetName(), self.helogroupname, _RESCUEHELOID)
|
||||||
|
|
||||||
-- Log ID.
|
-- Log ID.
|
||||||
self.lid=string.format("RESCUEHELO %s | ", self.alias)
|
self.lid=string.format("RESCUEHELO %s | ", self.alias)
|
||||||
@ -386,6 +386,7 @@ function RESCUEHELO:New(carrierunit, helogroupname)
|
|||||||
-- @param #string To To state.
|
-- @param #string To To state.
|
||||||
-- @param Wrapper.Airbase#AIRBASE airbase The airbase to return to. Default is the home base.
|
-- @param Wrapper.Airbase#AIRBASE airbase The airbase to return to. Default is the home base.
|
||||||
|
|
||||||
|
|
||||||
--- Triggers the FSM event "Returned" after the helo has landed.
|
--- Triggers the FSM event "Returned" after the helo has landed.
|
||||||
-- @function [parent=#RESCUEHELO] Returned
|
-- @function [parent=#RESCUEHELO] Returned
|
||||||
-- @param #RESCUEHELO self
|
-- @param #RESCUEHELO self
|
||||||
@ -719,7 +720,7 @@ end
|
|||||||
function RESCUEHELO:OnEventLand(EventData)
|
function RESCUEHELO:OnEventLand(EventData)
|
||||||
local group=EventData.IniGroup --Wrapper.Group#GROUP
|
local group=EventData.IniGroup --Wrapper.Group#GROUP
|
||||||
|
|
||||||
if group:IsAlive() then
|
if group and group:IsAlive() then
|
||||||
|
|
||||||
-- Group name that landed.
|
-- Group name that landed.
|
||||||
local groupname=group:GetName()
|
local groupname=group:GetName()
|
||||||
@ -727,8 +728,15 @@ function RESCUEHELO:OnEventLand(EventData)
|
|||||||
-- Check that it was our helo that landed.
|
-- Check that it was our helo that landed.
|
||||||
if groupname==self.helo:GetName() then
|
if groupname==self.helo:GetName() then
|
||||||
|
|
||||||
|
local airbase=nil --Wrapper.Airbase#AIRBASE
|
||||||
|
local airbasename="unknown"
|
||||||
|
if EventData.Place then
|
||||||
|
airbase=EventData.Place
|
||||||
|
airbasename=airbase:GetName()
|
||||||
|
end
|
||||||
|
|
||||||
-- Respawn the Helo.
|
-- Respawn the Helo.
|
||||||
local text=string.format("Respawning rescue helo group %s at home base.", groupname)
|
local text=string.format("Rescue helo group %s landed at airbase %s.", groupname, airbasename)
|
||||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
@ -749,7 +757,7 @@ function RESCUEHELO:OnEventLand(EventData)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Trigger returned event. Respawn at current airbase.
|
-- Trigger returned event. Respawn at current airbase.
|
||||||
self:__Returned(3, EventData.Place)
|
self:__Returned(3, airbase)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -839,7 +847,6 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
|||||||
self:I(self.lid..text)
|
self:I(self.lid..text)
|
||||||
|
|
||||||
-- Handle events.
|
-- Handle events.
|
||||||
--self:HandleEvent(EVENTS.Birth)
|
|
||||||
self:HandleEvent(EVENTS.Land)
|
self:HandleEvent(EVENTS.Land)
|
||||||
self:HandleEvent(EVENTS.Crash, self._OnEventCrashOrEject)
|
self:HandleEvent(EVENTS.Crash, self._OnEventCrashOrEject)
|
||||||
self:HandleEvent(EVENTS.Ejection, self._OnEventCrashOrEject)
|
self:HandleEvent(EVENTS.Ejection, self._OnEventCrashOrEject)
|
||||||
@ -899,7 +906,7 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
|||||||
else
|
else
|
||||||
|
|
||||||
-- Spawn at airbase.
|
-- Spawn at airbase.
|
||||||
self.helo=Spawn:SpawnAtAirbase(self.airbase, self.takeoff)
|
self.helo=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, AIRBASE.TerminalType.HelicopterUsable)
|
||||||
|
|
||||||
-- Delay before formation is started.
|
-- Delay before formation is started.
|
||||||
if self.takeoff==SPAWN.Takeoff.Runway then
|
if self.takeoff==SPAWN.Takeoff.Runway then
|
||||||
@ -948,7 +955,7 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
|||||||
local time=timer.getTime()
|
local time=timer.getTime()
|
||||||
|
|
||||||
-- Check if helo is running and not RTBing already or rescuing.
|
-- Check if helo is running and not RTBing already or rescuing.
|
||||||
if self.helo:IsAlive() then
|
if self.helo and self.helo:IsAlive() then
|
||||||
|
|
||||||
-------------------
|
-------------------
|
||||||
-- HELO is ALIVE --
|
-- HELO is ALIVE --
|
||||||
@ -959,9 +966,10 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
|||||||
local fuelrel=fuel/self.HeloFuel0
|
local fuelrel=fuel/self.HeloFuel0
|
||||||
local life=self.helo:GetUnit(1):GetLife()
|
local life=self.helo:GetUnit(1):GetLife()
|
||||||
local life0=self.helo:GetUnit(1):GetLife0()
|
local life0=self.helo:GetUnit(1):GetLife0()
|
||||||
|
local lifeR=self.helo:GetUnit(1):GetLifeRelative()
|
||||||
|
|
||||||
-- Report current fuel.
|
-- Report current fuel.
|
||||||
local text=string.format("Rescue Helo %s: state=%s fuel=%.1f, rel.fuel=%.1f, life=%.1f/%.1f", self.helo:GetName(), self:GetState(), fuel, fuelrel, life, life0)
|
local text=string.format("Rescue Helo %s: state=%s fuel=%.1f, rel.fuel=%.1f, life=%.1f/%.1f=%d", self.helo:GetName(), self:GetState(), fuel, fuelrel, life, life0, lifeR*100)
|
||||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
@ -982,7 +990,7 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
|||||||
-- Respawn helo in air.
|
-- Respawn helo in air.
|
||||||
self.helo=self.helo:Respawn(nil, true)
|
self.helo=self.helo:Respawn(nil, true)
|
||||||
|
|
||||||
-- XXX: ATTENTION: if helo automatically RTBs on low fuel, it goes a bit cazy. The formation is not stopped and he partially dives into the water.
|
-- XXX: ATTENTION: if helo automatically RTBs on low fuel, it goes a bit crazy. The formation is not stopped and he partially dives into the water.
|
||||||
-- Also trying to find a ship to land on he flies right through it.
|
-- Also trying to find a ship to land on he flies right through it.
|
||||||
--self.helo:OptionRTBBingoFuel(false)
|
--self.helo:OptionRTBBingoFuel(false)
|
||||||
|
|
||||||
@ -1016,6 +1024,8 @@ function RESCUEHELO:onafterStatus(From, Event, To)
|
|||||||
|
|
||||||
if not self:IsStopped() then
|
if not self:IsStopped() then
|
||||||
|
|
||||||
|
self:E(self.lid.."Rescue helo is NOT alive (and not stopped)!")
|
||||||
|
|
||||||
-- Stop FSM.
|
-- Stop FSM.
|
||||||
self:Stop()
|
self:Stop()
|
||||||
|
|
||||||
@ -1047,18 +1057,6 @@ function RESCUEHELO:onafterRun(From, Event, To)
|
|||||||
self.formation:Start()
|
self.formation:Start()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Restart route of carrier if it was stopped.
|
|
||||||
if self.carrierstop then
|
|
||||||
-- Debug info.
|
|
||||||
local text="Carrier resuming route after rescue operation."
|
|
||||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
|
||||||
self:T(self.lid..text)
|
|
||||||
|
|
||||||
-- Resume route of carrier.
|
|
||||||
self.carrier:RouteResume()
|
|
||||||
self.carrierstop=false
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -1143,15 +1141,6 @@ function RESCUEHELO:onafterRescue(From, Event, To, RescueCoord)
|
|||||||
-- Stop formation.
|
-- Stop formation.
|
||||||
self.formation:Stop()
|
self.formation:Stop()
|
||||||
|
|
||||||
-- Stop carrier.
|
|
||||||
if self.rescuestopboat then
|
|
||||||
local text="Stopping carrier for rescue operation."
|
|
||||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
|
||||||
self:T(self.lid..text)
|
|
||||||
|
|
||||||
self.carrier:RouteStop()
|
|
||||||
self.carrierstop=true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- On after RTB event. Send helo back to carrier.
|
--- On after RTB event. Send helo back to carrier.
|
||||||
@ -1170,21 +1159,6 @@ function RESCUEHELO:onafterRTB(From, Event, To, airbase)
|
|||||||
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
MESSAGE:New(text, 10, "DEBUG"):ToAllIf(self.Debug)
|
||||||
self:T(self.lid..text)
|
self:T(self.lid..text)
|
||||||
|
|
||||||
--[[
|
|
||||||
-- Waypoint array.
|
|
||||||
local wp={}
|
|
||||||
|
|
||||||
-- Set landing waypoint at home base.
|
|
||||||
wp[1]=self.helo:GetCoordinate():WaypointAirTurningPoint(nil, 300, {}, "Current Position")
|
|
||||||
wp[2]=self.airbase:GetCoordinate():SetAltitude(70):WaypointAirLanding(300, self.airbase, {}, "Landing at Home Base")
|
|
||||||
|
|
||||||
-- Initialize WP and route helo.
|
|
||||||
self.helo:WayPointInitialize(wp)
|
|
||||||
|
|
||||||
-- Set task.
|
|
||||||
self.helo:Route(wp, 1)
|
|
||||||
]]
|
|
||||||
|
|
||||||
-- Stop formation.
|
-- Stop formation.
|
||||||
if From=="Running" then
|
if From=="Running" then
|
||||||
self.formation:Stop()
|
self.formation:Stop()
|
||||||
@ -1238,6 +1212,9 @@ function RESCUEHELO:onafterStop(From, Event, To)
|
|||||||
self:UnHandleEvent(EVENTS.Land)
|
self:UnHandleEvent(EVENTS.Land)
|
||||||
self:UnHandleEvent(EVENTS.Crash)
|
self:UnHandleEvent(EVENTS.Crash)
|
||||||
self:UnHandleEvent(EVENTS.Ejection)
|
self:UnHandleEvent(EVENTS.Ejection)
|
||||||
|
|
||||||
|
-- Clear all pending FSM events.
|
||||||
|
self.CallScheduler:Clear()
|
||||||
|
|
||||||
-- If helo is alive, despawn it.
|
-- If helo is alive, despawn it.
|
||||||
if self.helo and self.helo:IsAlive() then
|
if self.helo and self.helo:IsAlive() then
|
||||||
@ -1245,7 +1222,8 @@ function RESCUEHELO:onafterStop(From, Event, To)
|
|||||||
self.helo:Destroy()
|
self.helo:Destroy()
|
||||||
else
|
else
|
||||||
self:I(self.lid.."Stopping FSM. Helo was not alive.")
|
self:I(self.lid.."Stopping FSM. Helo was not alive.")
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ -1260,13 +1238,13 @@ function RESCUEHELO:RouteRTB(RTBAirbase, Speed)
|
|||||||
|
|
||||||
-- Curent (from) waypoint.
|
-- Curent (from) waypoint.
|
||||||
local coord=self.helo:GetCoordinate()
|
local coord=self.helo:GetCoordinate()
|
||||||
local PointFrom=coord:WaypointAirTurningPoint(nil, Speed)
|
local PointFrom=coord:WaypointAirTurningPoint(nil, Speed, {}, "Current")
|
||||||
|
|
||||||
-- Airbase coordinate.
|
-- Airbase coordinate.
|
||||||
local PointAirbase=RTBAirbase:GetCoordinate():SetAltitude(100):WaypointAirTurningPoint(nil ,Speed)
|
--local PointAirbase=RTBAirbase:GetCoordinate():SetAltitude(100):WaypointAirTurningPoint(nil ,Speed)
|
||||||
|
|
||||||
-- Landing waypoint. More general than prev version since it should also work with FAPRS and ships.
|
-- Landing waypoint. More general than prev version since it should also work with FAPRS and ships.
|
||||||
local PointLanding=RTBAirbase:GetCoordinate():SetAltitude(20):WaypointAirLanding(Speed, RTBAirbase)
|
local PointLanding=RTBAirbase:GetCoordinate():SetAltitude(20):WaypointAirLanding(Speed, RTBAirbase, {}, "Landing")
|
||||||
|
|
||||||
-- Waypoint table.
|
-- Waypoint table.
|
||||||
local Points={PointFrom, PointLanding}
|
local Points={PointFrom, PointLanding}
|
||||||
@ -1283,6 +1261,9 @@ function RESCUEHELO:RouteRTB(RTBAirbase, Speed)
|
|||||||
-- Respawn the group.
|
-- Respawn the group.
|
||||||
self.helo=self.helo:Respawn(Template, true)
|
self.helo=self.helo:Respawn(Template, true)
|
||||||
|
|
||||||
|
-- Route the group or this will not work.
|
||||||
|
self.helo:Route(Points, 1)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,11 @@ routines.build = 22
|
|||||||
-- Utils- conversion, Lua utils, etc.
|
-- Utils- conversion, Lua utils, etc.
|
||||||
routines.utils = {}
|
routines.utils = {}
|
||||||
|
|
||||||
|
routines.utils.round = function(number, decimals)
|
||||||
|
local power = 10^decimals
|
||||||
|
return math.floor(number * power) / power
|
||||||
|
end
|
||||||
|
|
||||||
--from http://lua-users.org/wiki/CopyTable
|
--from http://lua-users.org/wiki/CopyTable
|
||||||
routines.utils.deepCopy = function(object)
|
routines.utils.deepCopy = function(object)
|
||||||
local lookup_table = {}
|
local lookup_table = {}
|
||||||
|
|||||||
@ -311,7 +311,7 @@ AIRBASE.PersianGulf = {
|
|||||||
-- @field #number OpenMed 72: Open/Shelter air airplane only.
|
-- @field #number OpenMed 72: Open/Shelter air airplane only.
|
||||||
-- @field #number OpenBig 104: Open air spawn points. Generally larger but does not guarantee large aircraft are capable of spawning there.
|
-- @field #number OpenBig 104: Open air spawn points. Generally larger but does not guarantee large aircraft are capable of spawning there.
|
||||||
-- @field #number OpenMedOrBig 176: Combines OpenMed and OpenBig spots.
|
-- @field #number OpenMedOrBig 176: Combines OpenMed and OpenBig spots.
|
||||||
-- @field #number HelicopterUnsable 216: Combines HelicopterOnly, OpenMed and OpenBig.
|
-- @field #number HelicopterUsable 216: Combines HelicopterOnly, OpenMed and OpenBig.
|
||||||
-- @field #number FighterAircraft 244: Combines Shelter. OpenMed and OpenBig spots. So effectively all spots usable by fixed wing aircraft.
|
-- @field #number FighterAircraft 244: Combines Shelter. OpenMed and OpenBig spots. So effectively all spots usable by fixed wing aircraft.
|
||||||
AIRBASE.TerminalType = {
|
AIRBASE.TerminalType = {
|
||||||
Runway=16,
|
Runway=16,
|
||||||
@ -578,7 +578,7 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC)
|
|||||||
-- Put coordinates of free spots into table.
|
-- Put coordinates of free spots into table.
|
||||||
local freespots={}
|
local freespots={}
|
||||||
for _,_spot in pairs(parkingfree) do
|
for _,_spot in pairs(parkingfree) do
|
||||||
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) then
|
if AIRBASE._CheckTerminalType(_spot.Term_Type, termtype) and _spot.Term_Index>0 then
|
||||||
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
|
if (allowTOAC and allowTOAC==true) or _spot.TO_AC==false then
|
||||||
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
|
local _coord=COORDINATE:NewFromVec3(_spot.vTerminalPos)
|
||||||
table.insert(freespots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=true, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
|
table.insert(freespots, {Coordinate=_coord, TerminalID=_spot.Term_Index, TerminalType=_spot.Term_Type, TOAC=_spot.TO_AC, Free=true, TerminalID0=_spot.Term_Index_0, DistToRwy=_spot.fDistToRW})
|
||||||
@ -589,6 +589,31 @@ function AIRBASE:GetFreeParkingSpotsTable(termtype, allowTOAC)
|
|||||||
return freespots
|
return freespots
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Get a table containing the coordinates, terminal index and terminal type of free parking spots at an airbase.
|
||||||
|
-- @param #AIRBASE self
|
||||||
|
-- @param #number TerminalID The terminal ID of the parking spot.
|
||||||
|
-- @return #AIRBASE.ParkingSpot Table free parking spots. Table has the elements ".Coordinate, ".TerminalID", ".TerminalType", ".TOAC", ".Free", ".TerminalID0", ".DistToRwy".
|
||||||
|
function AIRBASE:GetParkingSpotData(TerminalID)
|
||||||
|
self:F({TerminalID=TerminalID})
|
||||||
|
|
||||||
|
-- Get parking data.
|
||||||
|
local parkingdata=self:GetParkingSpotsTable()
|
||||||
|
|
||||||
|
-- Debug output.
|
||||||
|
self:T2({parkingdata=parkingdata})
|
||||||
|
|
||||||
|
for _,_spot in pairs(parkingdata) do
|
||||||
|
local spot=_spot --#AIRBASE.ParkingSpot
|
||||||
|
self:E({TerminalID=spot.TerminalID,TerminalType=spot.TerminalType})
|
||||||
|
if TerminalID==spot.TerminalID then
|
||||||
|
return spot
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:E("ERROR: Could not find spot with Terminal ID="..tostring(TerminalID))
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Place markers of parking spots on the F10 map.
|
--- Place markers of parking spots on the F10 map.
|
||||||
-- @param #AIRBASE self
|
-- @param #AIRBASE self
|
||||||
-- @param #AIRBASE.TerminalType termtype Terminal type for which marks should be placed.
|
-- @param #AIRBASE.TerminalType termtype Terminal type for which marks should be placed.
|
||||||
@ -893,7 +918,7 @@ function AIRBASE:CheckOnRunWay(group, radius, despawn)
|
|||||||
end
|
end
|
||||||
|
|
||||||
--- Get category of airbase.
|
--- Get category of airbase.
|
||||||
-- @param #WAREHOUSE self
|
-- @param #AIRBASE self
|
||||||
-- @return #number Category of airbase from GetDesc().category.
|
-- @return #number Category of airbase from GetDesc().category.
|
||||||
function AIRBASE:GetAirbaseCategory()
|
function AIRBASE:GetAirbaseCategory()
|
||||||
return self:GetDesc().category
|
return self:GetDesc().category
|
||||||
|
|||||||
@ -612,8 +612,7 @@ end
|
|||||||
|
|
||||||
--- Returns the unit's health. Dead units has health <= 1.0.
|
--- Returns the unit's health. Dead units has health <= 1.0.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number The Unit's health value.
|
-- @return #number The Unit's health value or -1 if unit does not exist any more.
|
||||||
-- @return #nil The DCS Unit is not existing or alive.
|
|
||||||
function UNIT:GetLife()
|
function UNIT:GetLife()
|
||||||
self:F2( self.UnitName )
|
self:F2( self.UnitName )
|
||||||
|
|
||||||
@ -629,8 +628,7 @@ end
|
|||||||
|
|
||||||
--- Returns the Unit's initial health.
|
--- Returns the Unit's initial health.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #number The Unit's initial health value.
|
-- @return #number The Unit's initial health value or 0 if unit does not exist any more.
|
||||||
-- @return #nil The DCS Unit is not existing or alive.
|
|
||||||
function UNIT:GetLife0()
|
function UNIT:GetLife0()
|
||||||
self:F2( self.UnitName )
|
self:F2( self.UnitName )
|
||||||
|
|
||||||
@ -644,6 +642,34 @@ function UNIT:GetLife0()
|
|||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Returns the unit's relative health.
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @return #number The Unit's relative health value, i.e. a number in [0,1] or -1 if unit does not exist any more.
|
||||||
|
function UNIT:GetLifeRelative()
|
||||||
|
self:F2(self.UnitName)
|
||||||
|
|
||||||
|
if self and self:IsAlive() then
|
||||||
|
local life0=self:GetLife0()
|
||||||
|
local lifeN=self:GetLife()
|
||||||
|
return lifeN/life0
|
||||||
|
end
|
||||||
|
|
||||||
|
return -1
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Returns the unit's relative damage, i.e. 1-life.
|
||||||
|
-- @param #UNIT self
|
||||||
|
-- @return #number The Unit's relative health value, i.e. a number in [0,1] or 1 if unit does not exist any more.
|
||||||
|
function UNIT:GetDamageRelative()
|
||||||
|
self:F2(self.UnitName)
|
||||||
|
|
||||||
|
if self and self:IsAlive() then
|
||||||
|
return 1-self:GetLifeRelative()
|
||||||
|
end
|
||||||
|
|
||||||
|
return 1
|
||||||
|
end
|
||||||
|
|
||||||
--- Returns the category name of the #UNIT.
|
--- Returns the category name of the #UNIT.
|
||||||
-- @param #UNIT self
|
-- @param #UNIT self
|
||||||
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship
|
-- @return #string Category name = Helicopter, Airplane, Ground Unit, Ship
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user