mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-07-21 06:04:49 +00:00
Updates Base, Event, Point, Contollable, FG
This commit is contained in:
@@ -626,6 +626,55 @@ do -- Event Handling
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
|
||||
--- Unknown precisely what creates this event, likely tied into newer damage model. Will update this page when new information become available.
|
||||
--
|
||||
-- * initiator: The unit that had the failure.
|
||||
--
|
||||
-- @function [parent=#BASE] OnEventDetailedFailure
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any modification to the "Score" as seen on the debrief menu would occur.
|
||||
-- There is no information on what values the score was changed to. Event is likely similar to player_comment in this regard.
|
||||
-- @function [parent=#BASE] OnEventScore
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs on the death of a unit. Contains more and different information. Similar to unit_lost it will occur for aircraft before the aircraft crash event occurs.
|
||||
--
|
||||
-- * initiator: The unit that killed the target
|
||||
-- * target: Target Object
|
||||
-- * weapon: Weapon Object
|
||||
--
|
||||
-- @function [parent=#BASE] OnEventKill
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when any modification to the "Score" as seen on the debrief menu would occur.
|
||||
-- There is no information on what values the score was changed to. Event is likely similar to player_comment in this regard.
|
||||
-- @function [parent=#BASE] OnEventScore
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs when the game thinks an object is destroyed.
|
||||
--
|
||||
-- * initiator: The unit that is was destroyed.
|
||||
--
|
||||
-- @function [parent=#BASE] OnEventUnitLost
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
--- Occurs shortly after the landing animation of an ejected pilot touching the ground and standing up. Event does not occur if the pilot lands in the water and sub combs to Davey Jones Locker.
|
||||
--
|
||||
-- * initiator: Static object representing the ejected pilot. Place : Aircraft that the pilot ejected from.
|
||||
-- * place: may not return as a valid object if the aircraft has crashed into the ground and no longer exists.
|
||||
-- * subplace: is always 0 for unknown reasons.
|
||||
--
|
||||
-- @function [parent=#BASE] OnEventLandingAfterEjection
|
||||
-- @param #BASE self
|
||||
-- @param Core.Event#EVENTDATA EventData The EventData structure.
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
@@ -221,9 +221,11 @@ EVENTS = {
|
||||
PlayerComment = world.event.S_EVENT_PLAYER_COMMENT,
|
||||
ShootingStart = world.event.S_EVENT_SHOOTING_START,
|
||||
ShootingEnd = world.event.S_EVENT_SHOOTING_END,
|
||||
-- Added with DCS 2.5.1
|
||||
MarkAdded = world.event.S_EVENT_MARK_ADDED,
|
||||
MarkChange = world.event.S_EVENT_MARK_CHANGE,
|
||||
MarkRemoved = world.event.S_EVENT_MARK_REMOVED,
|
||||
-- Moose Events
|
||||
NewCargo = world.event.S_EVENT_NEW_CARGO,
|
||||
DeleteCargo = world.event.S_EVENT_DELETE_CARGO,
|
||||
NewZone = world.event.S_EVENT_NEW_ZONE,
|
||||
@@ -231,6 +233,12 @@ EVENTS = {
|
||||
NewZoneGoal = world.event.S_EVENT_NEW_ZONE_GOAL,
|
||||
DeleteZoneGoal = world.event.S_EVENT_DELETE_ZONE_GOAL,
|
||||
RemoveUnit = world.event.S_EVENT_REMOVE_UNIT,
|
||||
-- Added with DCS 2.5.6
|
||||
DetailedFailure = world.event.S_EVENT_DETAILED_FAILURE or -1, --We set this to -1 for backward compatibility to DCS 2.5.5 and earlier
|
||||
Kill = world.event.S_EVENT_KILL or -1,
|
||||
Score = world.event.S_EVENT_SCORE or -1,
|
||||
UnitLost = world.event.S_EVENT_UNIT_LOST or -1,
|
||||
LandingAfterEjection = world.event.S_EVENT_LANDING_AFTER_EJECTION or -1,
|
||||
}
|
||||
|
||||
--- The Event structure
|
||||
@@ -481,6 +489,32 @@ local _EVENTMETA = {
|
||||
Event = "OnEventRemoveUnit",
|
||||
Text = "S_EVENT_REMOVE_UNIT"
|
||||
},
|
||||
-- Added with DCS 2.5.6
|
||||
[EVENTS.DetailedFailure] = {
|
||||
Order = 1,
|
||||
Event = "OnEventDetailedFailure",
|
||||
Text = "S_EVENT_DETAILED_FAILURE"
|
||||
},
|
||||
[EVENTS.Kill] = {
|
||||
Order = 1,
|
||||
Event = "OnEventKill",
|
||||
Text = "S_EVENT_KILL"
|
||||
},
|
||||
[EVENTS.Score] = {
|
||||
Order = 1,
|
||||
Event = "OnEventScore",
|
||||
Text = "S_EVENT_SCORE"
|
||||
},
|
||||
[EVENTS.UnitLost] = {
|
||||
Order = 1,
|
||||
Event = "OnEventUnitLost",
|
||||
Text = "S_EVENT_UNIT_LOST"
|
||||
},
|
||||
[EVENTS.LandingAfterEjection] = {
|
||||
Order = 1,
|
||||
Event = "OnEventLandingAfterEjection",
|
||||
Text = "S_EVENT_LANDING_AFTER_EJECTION"
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -881,258 +915,213 @@ function EVENT:onEvent( Event )
|
||||
end
|
||||
|
||||
|
||||
-- Get event meta data.
|
||||
local EventMeta = _EVENTMETA[Event.id]
|
||||
|
||||
--self:E( { EventMeta.Text, Event } ) -- Activate the see all incoming events ...
|
||||
|
||||
if self and
|
||||
self.Events and
|
||||
self.Events[Event.id] and
|
||||
self.MissionEnd == false and
|
||||
( Event.initiator ~= nil or ( Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit ) ) then
|
||||
|
||||
if Event.id and Event.id == EVENTS.MissionEnd then
|
||||
self.MissionEnd = true
|
||||
end
|
||||
|
||||
if Event.initiator then
|
||||
|
||||
Event.IniObjectCategory = Event.initiator:getCategory()
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.UNIT then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniDCSGroup = Event.IniDCSUnit:getGroup()
|
||||
Event.IniUnit = UNIT:FindByName( Event.IniDCSUnitName )
|
||||
if not Event.IniUnit then
|
||||
-- Unit can be a CLIENT. Most likely this will be the case ...
|
||||
Event.IniUnit = CLIENT:FindByName( Event.IniDCSUnitName, '', true )
|
||||
end
|
||||
Event.IniDCSGroupName = ""
|
||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||
--if Event.IniGroup then
|
||||
Event.IniGroupName = Event.IniDCSGroupName
|
||||
--end
|
||||
end
|
||||
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.STATIC then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = STATIC:FindByName( Event.IniDCSUnitName, false )
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.CARGO then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName )
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.SCENERY then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY" -- TODO: Bug fix for 2.1!
|
||||
end
|
||||
end
|
||||
|
||||
if Event.target then
|
||||
|
||||
Event.TgtObjectCategory = Event.target:getCategory()
|
||||
|
||||
if Event.TgtObjectCategory == Object.Category.UNIT then
|
||||
Event.TgtDCSUnit = Event.target
|
||||
Event.TgtDCSGroup = Event.TgtDCSUnit:getGroup()
|
||||
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||
Event.TgtUnit = UNIT:FindByName( Event.TgtDCSUnitName )
|
||||
Event.TgtDCSGroupName = ""
|
||||
if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then
|
||||
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
|
||||
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
||||
--if Event.TgtGroup then
|
||||
Event.TgtGroupName = Event.TgtDCSGroupName
|
||||
--end
|
||||
end
|
||||
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
|
||||
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.TgtObjectCategory == Object.Category.STATIC then
|
||||
Event.TgtDCSUnit = Event.target
|
||||
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||
Event.TgtUnit = STATIC:FindByName( Event.TgtDCSUnitName, false )
|
||||
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.TgtObjectCategory == Object.Category.SCENERY then
|
||||
Event.TgtDCSUnit = Event.target
|
||||
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
|
||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||
end
|
||||
end
|
||||
|
||||
if Event.weapon then
|
||||
Event.Weapon = Event.weapon
|
||||
Event.WeaponName = Event.Weapon:getTypeName()
|
||||
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
|
||||
Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon:getPlayerName()
|
||||
Event.WeaponCoalition = Event.WeaponUNIT and Event.Weapon:getCoalition()
|
||||
Event.WeaponCategory = Event.WeaponUNIT and Event.Weapon:getDesc().category
|
||||
Event.WeaponTypeName = Event.WeaponUNIT and Event.Weapon:getTypeName()
|
||||
--Event.WeaponTgtDCSUnit = Event.Weapon:getTarget()
|
||||
end
|
||||
|
||||
-- Place should be given for takeoff and landing events as well as base captured. It should be a DCS airbase.
|
||||
if Event.place then
|
||||
Event.Place=AIRBASE:Find(Event.place)
|
||||
Event.PlaceName=Event.Place:GetName()
|
||||
end
|
||||
|
||||
-- Mark points.
|
||||
if Event.idx then
|
||||
Event.MarkID=Event.idx
|
||||
Event.MarkVec3=Event.pos
|
||||
Event.MarkCoordinate=COORDINATE:NewFromVec3(Event.pos)
|
||||
Event.MarkText=Event.text
|
||||
Event.MarkCoalition=Event.coalition
|
||||
Event.MarkGroupID = Event.groupID
|
||||
end
|
||||
|
||||
if Event.cargo then
|
||||
Event.Cargo = Event.cargo
|
||||
Event.CargoName = Event.cargo.Name
|
||||
end
|
||||
|
||||
if Event.zone then
|
||||
Event.Zone = Event.zone
|
||||
Event.ZoneName = Event.zone.ZoneName
|
||||
end
|
||||
|
||||
local PriorityOrder = EventMeta.Order
|
||||
local PriorityBegin = PriorityOrder == -1 and 5 or 1
|
||||
local PriorityEnd = PriorityOrder == -1 and 1 or 5
|
||||
|
||||
if Event.IniObjectCategory ~= Object.Category.STATIC then
|
||||
self:F( { EventMeta.Text, Event, Event.IniDCSUnitName, Event.TgtDCSUnitName, PriorityOrder } )
|
||||
end
|
||||
|
||||
for EventPriority = PriorityBegin, PriorityEnd, PriorityOrder do
|
||||
|
||||
if self.Events[Event.id][EventPriority] then
|
||||
|
||||
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
||||
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
|
||||
|
||||
--if Event.IniObjectCategory ~= Object.Category.STATIC then
|
||||
-- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
|
||||
--end
|
||||
|
||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
||||
|
||||
-- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT.
|
||||
if EventData.EventUnit then
|
||||
|
||||
-- So now the EventClass must be a UNIT class!!! We check if it is still "Alive".
|
||||
if EventClass:IsAlive() or
|
||||
Event.id == EVENTS.PlayerEnterUnit or
|
||||
Event.id == EVENTS.Crash or
|
||||
Event.id == EVENTS.Dead or
|
||||
Event.id == EVENTS.RemoveUnit then
|
||||
|
||||
local UnitName = EventClass:GetName()
|
||||
|
||||
if ( EventMeta.Side == "I" and UnitName == Event.IniDCSUnitName ) or
|
||||
( EventMeta.Side == "T" and UnitName == Event.TgtDCSUnitName ) then
|
||||
|
||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||
if EventData.EventFunction then
|
||||
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||
end
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventData.EventFunction( EventClass, Event )
|
||||
end, ErrorHandler )
|
||||
|
||||
else
|
||||
|
||||
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||
local EventFunction = EventClass[ EventMeta.Event ]
|
||||
if EventFunction and type( EventFunction ) == "function" then
|
||||
|
||||
-- Now call the default event function.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
end
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventFunction( EventClass, Event )
|
||||
end, ErrorHandler )
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- The EventClass is not alive anymore, we remove it from the EventHandlers...
|
||||
self:RemoveEvent( EventClass, Event.id )
|
||||
end
|
||||
else
|
||||
|
||||
-- If the EventData is for a GROUP, the call directly the EventClass EventFunction for the UNIT in that GROUP.
|
||||
if EventData.EventGroup then
|
||||
|
||||
-- So now the EventClass must be a GROUP class!!! We check if it is still "Alive".
|
||||
if EventClass:IsAlive() or
|
||||
Event.id == EVENTS.PlayerEnterUnit or
|
||||
Event.id == EVENTS.Crash or
|
||||
Event.id == EVENTS.Dead or
|
||||
Event.id == EVENTS.RemoveUnit then
|
||||
|
||||
-- We can get the name of the EventClass, which is now always a GROUP object.
|
||||
local GroupName = EventClass:GetName()
|
||||
|
||||
if ( EventMeta.Side == "I" and GroupName == Event.IniDCSGroupName ) or
|
||||
( EventMeta.Side == "T" and GroupName == Event.TgtDCSGroupName ) then
|
||||
|
||||
-- Check if this is a known event?
|
||||
if EventMeta then
|
||||
|
||||
if self and
|
||||
self.Events and
|
||||
self.Events[Event.id] and
|
||||
self.MissionEnd == false and
|
||||
( Event.initiator ~= nil or ( Event.initiator == nil and Event.id ~= EVENTS.PlayerLeaveUnit ) ) then
|
||||
|
||||
if Event.id and Event.id == EVENTS.MissionEnd then
|
||||
self.MissionEnd = true
|
||||
end
|
||||
|
||||
if Event.initiator then
|
||||
|
||||
Event.IniObjectCategory = Event.initiator:getCategory()
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.UNIT then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniDCSGroup = Event.IniDCSUnit:getGroup()
|
||||
Event.IniUnit = UNIT:FindByName( Event.IniDCSUnitName )
|
||||
if not Event.IniUnit then
|
||||
-- Unit can be a CLIENT. Most likely this will be the case ...
|
||||
Event.IniUnit = CLIENT:FindByName( Event.IniDCSUnitName, '', true )
|
||||
end
|
||||
Event.IniDCSGroupName = ""
|
||||
if Event.IniDCSGroup and Event.IniDCSGroup:isExist() then
|
||||
Event.IniDCSGroupName = Event.IniDCSGroup:getName()
|
||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||
--if Event.IniGroup then
|
||||
Event.IniGroupName = Event.IniDCSGroupName
|
||||
--end
|
||||
end
|
||||
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.STATIC then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = STATIC:FindByName( Event.IniDCSUnitName, false )
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.CARGO then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName )
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.SCENERY then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.initiator:isExist() and Event.IniDCSUnit:getTypeName() or "SCENERY" -- TODO: Bug fix for 2.1!
|
||||
end
|
||||
end
|
||||
|
||||
if Event.target then
|
||||
|
||||
Event.TgtObjectCategory = Event.target:getCategory()
|
||||
|
||||
if Event.TgtObjectCategory == Object.Category.UNIT then
|
||||
Event.TgtDCSUnit = Event.target
|
||||
Event.TgtDCSGroup = Event.TgtDCSUnit:getGroup()
|
||||
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||
Event.TgtUnit = UNIT:FindByName( Event.TgtDCSUnitName )
|
||||
Event.TgtDCSGroupName = ""
|
||||
if Event.TgtDCSGroup and Event.TgtDCSGroup:isExist() then
|
||||
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
|
||||
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
||||
--if Event.TgtGroup then
|
||||
Event.TgtGroupName = Event.TgtDCSGroupName
|
||||
--end
|
||||
end
|
||||
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
|
||||
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.TgtObjectCategory == Object.Category.STATIC then
|
||||
Event.TgtDCSUnit = Event.target
|
||||
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||
Event.TgtUnit = STATIC:FindByName( Event.TgtDCSUnitName, false )
|
||||
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
|
||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.TgtObjectCategory == Object.Category.SCENERY then
|
||||
Event.TgtDCSUnit = Event.target
|
||||
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
|
||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
|
||||
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
|
||||
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
|
||||
end
|
||||
end
|
||||
|
||||
if Event.weapon then
|
||||
Event.Weapon = Event.weapon
|
||||
Event.WeaponName = Event.Weapon:getTypeName()
|
||||
Event.WeaponUNIT = CLIENT:Find( Event.Weapon, '', true ) -- Sometimes, the weapon is a player unit!
|
||||
Event.WeaponPlayerName = Event.WeaponUNIT and Event.Weapon:getPlayerName()
|
||||
Event.WeaponCoalition = Event.WeaponUNIT and Event.Weapon:getCoalition()
|
||||
Event.WeaponCategory = Event.WeaponUNIT and Event.Weapon:getDesc().category
|
||||
Event.WeaponTypeName = Event.WeaponUNIT and Event.Weapon:getTypeName()
|
||||
--Event.WeaponTgtDCSUnit = Event.Weapon:getTarget()
|
||||
end
|
||||
|
||||
-- Place should be given for takeoff and landing events as well as base captured. It should be a DCS airbase.
|
||||
if Event.place then
|
||||
if Event.id==EVENTS.LandingAfterEjection then
|
||||
-- Place is here the UNIT of which the pilot ejected.
|
||||
Event.Place=UNIT:Find(Event.place)
|
||||
else
|
||||
Event.Place=AIRBASE:Find(Event.place)
|
||||
Event.PlaceName=Event.Place:GetName()
|
||||
end
|
||||
end
|
||||
|
||||
-- Mark points.
|
||||
if Event.idx then
|
||||
Event.MarkID=Event.idx
|
||||
Event.MarkVec3=Event.pos
|
||||
Event.MarkCoordinate=COORDINATE:NewFromVec3(Event.pos)
|
||||
Event.MarkText=Event.text
|
||||
Event.MarkCoalition=Event.coalition
|
||||
Event.MarkGroupID = Event.groupID
|
||||
end
|
||||
|
||||
if Event.cargo then
|
||||
Event.Cargo = Event.cargo
|
||||
Event.CargoName = Event.cargo.Name
|
||||
end
|
||||
|
||||
if Event.zone then
|
||||
Event.Zone = Event.zone
|
||||
Event.ZoneName = Event.zone.ZoneName
|
||||
end
|
||||
|
||||
local PriorityOrder = EventMeta.Order
|
||||
local PriorityBegin = PriorityOrder == -1 and 5 or 1
|
||||
local PriorityEnd = PriorityOrder == -1 and 1 or 5
|
||||
|
||||
if Event.IniObjectCategory ~= Object.Category.STATIC then
|
||||
self:F( { EventMeta.Text, Event, Event.IniDCSUnitName, Event.TgtDCSUnitName, PriorityOrder } )
|
||||
end
|
||||
|
||||
for EventPriority = PriorityBegin, PriorityEnd, PriorityOrder do
|
||||
|
||||
if self.Events[Event.id][EventPriority] then
|
||||
|
||||
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
||||
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
|
||||
|
||||
--if Event.IniObjectCategory ~= Object.Category.STATIC then
|
||||
-- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
|
||||
--end
|
||||
|
||||
Event.IniGroup = GROUP:FindByName( Event.IniDCSGroupName )
|
||||
Event.TgtGroup = GROUP:FindByName( Event.TgtDCSGroupName )
|
||||
|
||||
-- If the EventData is for a UNIT, the call directly the EventClass EventFunction for that UNIT.
|
||||
if EventData.EventUnit then
|
||||
|
||||
-- So now the EventClass must be a UNIT class!!! We check if it is still "Alive".
|
||||
if EventClass:IsAlive() or
|
||||
Event.id == EVENTS.PlayerEnterUnit or
|
||||
Event.id == EVENTS.Crash or
|
||||
Event.id == EVENTS.Dead or
|
||||
Event.id == EVENTS.RemoveUnit then
|
||||
|
||||
local UnitName = EventClass:GetName()
|
||||
|
||||
if ( EventMeta.Side == "I" and UnitName == Event.IniDCSUnitName ) or
|
||||
( EventMeta.Side == "T" and UnitName == Event.TgtDCSUnitName ) then
|
||||
|
||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||
if EventData.EventFunction then
|
||||
|
||||
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||
self:F( { "Calling EventFunction for UNIT ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||
end
|
||||
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) )
|
||||
return EventData.EventFunction( EventClass, Event )
|
||||
end, ErrorHandler )
|
||||
|
||||
else
|
||||
@@ -1143,74 +1132,129 @@ function EVENT:onEvent( Event )
|
||||
|
||||
-- Now call the default event function.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
self:F( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
end
|
||||
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventFunction( EventClass, Event, unpack( EventData.Params ) )
|
||||
return EventFunction( EventClass, Event )
|
||||
end, ErrorHandler )
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- The EventClass is not alive anymore, we remove it from the EventHandlers...
|
||||
--self:RemoveEvent( EventClass, Event.id )
|
||||
end
|
||||
self:RemoveEvent( EventClass, Event.id )
|
||||
end
|
||||
else
|
||||
|
||||
-- If the EventData is not bound to a specific unit, then call the EventClass EventFunction.
|
||||
-- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon.
|
||||
if not EventData.EventUnit then
|
||||
|
||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||
if EventData.EventFunction then
|
||||
|
||||
-- There is an EventFunction defined, so call the EventFunction.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
end
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventData.EventFunction( EventClass, Event )
|
||||
end, ErrorHandler )
|
||||
else
|
||||
|
||||
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||
local EventFunction = EventClass[ EventMeta.Event ]
|
||||
if EventFunction and type( EventFunction ) == "function" then
|
||||
|
||||
-- Now call the default event function.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
|
||||
-- If the EventData is for a GROUP, the call directly the EventClass EventFunction for the UNIT in that GROUP.
|
||||
if EventData.EventGroup then
|
||||
|
||||
-- So now the EventClass must be a GROUP class!!! We check if it is still "Alive".
|
||||
if EventClass:IsAlive() or
|
||||
Event.id == EVENTS.PlayerEnterUnit or
|
||||
Event.id == EVENTS.Crash or
|
||||
Event.id == EVENTS.Dead or
|
||||
Event.id == EVENTS.RemoveUnit then
|
||||
|
||||
-- We can get the name of the EventClass, which is now always a GROUP object.
|
||||
local GroupName = EventClass:GetName()
|
||||
|
||||
if ( EventMeta.Side == "I" and GroupName == Event.IniDCSGroupName ) or
|
||||
( EventMeta.Side == "T" and GroupName == Event.TgtDCSGroupName ) then
|
||||
|
||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||
if EventData.EventFunction then
|
||||
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F( { "Calling EventFunction for GROUP ", EventClass:GetClassNameAndID(), ", Unit ", Event.IniUnitName, EventPriority } )
|
||||
end
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) )
|
||||
end, ErrorHandler )
|
||||
|
||||
else
|
||||
|
||||
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||
local EventFunction = EventClass[ EventMeta.Event ]
|
||||
if EventFunction and type( EventFunction ) == "function" then
|
||||
|
||||
-- Now call the default event function.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F( { "Calling " .. EventMeta.Event .. " for GROUP ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
end
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
return EventFunction( EventClass, Event, unpack( EventData.Params ) )
|
||||
end, ErrorHandler )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
else
|
||||
-- The EventClass is not alive anymore, we remove it from the EventHandlers...
|
||||
--self:RemoveEvent( EventClass, Event.id )
|
||||
end
|
||||
else
|
||||
|
||||
-- If the EventData is not bound to a specific unit, then call the EventClass EventFunction.
|
||||
-- Note that here the EventFunction will need to implement and determine the logic for the relevant source- or target unit, or weapon.
|
||||
if not EventData.EventUnit then
|
||||
|
||||
-- First test if a EventFunction is Set, otherwise search for the default function
|
||||
if EventData.EventFunction then
|
||||
|
||||
-- There is an EventFunction defined, so call the EventFunction.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F2( { "Calling EventFunction for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
end
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
local Result, Value = EventFunction( EventClass, Event )
|
||||
return Result, Value
|
||||
return EventData.EventFunction( EventClass, Event )
|
||||
end, ErrorHandler )
|
||||
else
|
||||
|
||||
-- There is no EventFunction defined, so try to find if a default OnEvent function is defined on the object.
|
||||
local EventFunction = EventClass[ EventMeta.Event ]
|
||||
if EventFunction and type( EventFunction ) == "function" then
|
||||
|
||||
-- Now call the default event function.
|
||||
if Event.IniObjectCategory ~= 3 then
|
||||
self:F2( { "Calling " .. EventMeta.Event .. " for Class ", EventClass:GetClassNameAndID(), EventPriority } )
|
||||
end
|
||||
|
||||
local Result, Value = xpcall(
|
||||
function()
|
||||
local Result, Value = EventFunction( EventClass, Event )
|
||||
return Result, Value
|
||||
end, ErrorHandler )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- When cargo was deleted, it may probably be because of an S_EVENT_DEAD.
|
||||
-- However, in the loading logic, an S_EVENT_DEAD is also generated after a Destroy() call.
|
||||
-- And this is a problem because it will remove all entries from the SET_CARGOs.
|
||||
-- To prevent this from happening, the Cargo object has a flag NoDestroy.
|
||||
-- When true, the SET_CARGO won't Remove the Cargo object from the set.
|
||||
-- But we need to switch that flag off after the event handlers have been called.
|
||||
if Event.id == EVENTS.DeleteCargo then
|
||||
Event.Cargo.NoDestroy = nil
|
||||
|
||||
-- When cargo was deleted, it may probably be because of an S_EVENT_DEAD.
|
||||
-- However, in the loading logic, an S_EVENT_DEAD is also generated after a Destroy() call.
|
||||
-- And this is a problem because it will remove all entries from the SET_CARGOs.
|
||||
-- To prevent this from happening, the Cargo object has a flag NoDestroy.
|
||||
-- When true, the SET_CARGO won't Remove the Cargo object from the set.
|
||||
-- But we need to switch that flag off after the event handlers have been called.
|
||||
if Event.id == EVENTS.DeleteCargo then
|
||||
Event.Cargo.NoDestroy = nil
|
||||
end
|
||||
else
|
||||
self:T( { EventMeta.Text, Event } )
|
||||
end
|
||||
else
|
||||
self:T( { EventMeta.Text, Event } )
|
||||
self:E(string.format("WARNING: Could not get EVENTMETA data for event ID=%d! Is this an unknown/new DCS event?", tostring(Event.id)))
|
||||
end
|
||||
|
||||
Event = nil
|
||||
|
||||
@@ -1215,34 +1215,64 @@ do -- COORDINATE
|
||||
|
||||
--- Build an ground type route point.
|
||||
-- @param #COORDINATE self
|
||||
-- @param #number Speed (optional) Speed in km/h. The default speed is 20 km/h.
|
||||
-- @param #string Formation (optional) The route point Formation, which is a text string that specifies exactly the Text in the Type of the route point, like "Vee", "Echelon Right".
|
||||
-- @param #table DCSTasks A table of DCS tasks that are executed at the waypoints. Mind the curly brackets {}!
|
||||
-- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h.
|
||||
-- @param #string Formation (Optional) The route point Formation, which is a text string that specifies exactly the Text in the Type of the route point, like "Vee", "Echelon Right".
|
||||
-- @param #table DCSTasks (Optional) A table of DCS tasks that are executed at the waypoints. Mind the curly brackets {}!
|
||||
-- @return #table The route point.
|
||||
function COORDINATE:WaypointGround( Speed, Formation, DCSTasks )
|
||||
self:F2( { Formation, Speed } )
|
||||
self:F2( { Speed, Formation, DCSTasks } )
|
||||
|
||||
local RoutePoint = {}
|
||||
RoutePoint.x = self.x
|
||||
RoutePoint.y = self.z
|
||||
|
||||
RoutePoint.action = Formation or ""
|
||||
--RoutePoint.formation_template = Formation and "" or nil
|
||||
|
||||
|
||||
RoutePoint.x = self.x
|
||||
RoutePoint.y = self.z
|
||||
|
||||
RoutePoint.alt = self:GetLandHeight()+1 -- self.y
|
||||
RoutePoint.alt_type = COORDINATE.WaypointAltType.BARO
|
||||
|
||||
RoutePoint.action = Formation or "Off Road"
|
||||
RoutePoint.formation_template=""
|
||||
|
||||
RoutePoint.ETA=0
|
||||
RoutePoint.ETA_locked=true
|
||||
|
||||
RoutePoint.speed = ( Speed or 20 ) / 3.6
|
||||
RoutePoint.speed_locked = true
|
||||
|
||||
-- ["task"] =
|
||||
-- {
|
||||
-- ["id"] = "ComboTask",
|
||||
-- ["params"] =
|
||||
-- {
|
||||
-- ["tasks"] =
|
||||
-- {
|
||||
-- }, -- end of ["tasks"]
|
||||
-- }, -- end of ["params"]
|
||||
-- }, -- end of ["task"]
|
||||
RoutePoint.task = {}
|
||||
RoutePoint.task.id = "ComboTask"
|
||||
RoutePoint.task.params = {}
|
||||
RoutePoint.task.params.tasks = DCSTasks or {}
|
||||
|
||||
return RoutePoint
|
||||
end
|
||||
|
||||
--- Build route waypoint point for Naval units.
|
||||
-- @param #COORDINATE self
|
||||
-- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h.
|
||||
-- @param #string Depth (Optional) Dive depth in meters. Only for submarines. Default is COORDINATE.y component.
|
||||
-- @param #table DCSTasks (Optional) A table of DCS tasks that are executed at the waypoints. Mind the curly brackets {}!
|
||||
-- @return #table The route point.
|
||||
function COORDINATE:WaypointNaval( Speed, Depth, DCSTasks )
|
||||
self:F2( { Speed, Depth, DCSTasks } )
|
||||
|
||||
local RoutePoint = {}
|
||||
|
||||
RoutePoint.x = self.x
|
||||
RoutePoint.y = self.z
|
||||
|
||||
RoutePoint.alt = Depth or self.y -- Depth is for submarines only. Ships should have alt=0.
|
||||
RoutePoint.alt_type = "BARO"
|
||||
|
||||
RoutePoint.type = "Turning Point"
|
||||
RoutePoint.action = "Turning Point"
|
||||
RoutePoint.formation_template = ""
|
||||
|
||||
RoutePoint.ETA=0
|
||||
RoutePoint.ETA_locked=true
|
||||
|
||||
RoutePoint.speed = ( Speed or 20 ) / 3.6
|
||||
RoutePoint.speed_locked = true
|
||||
|
||||
RoutePoint.task = {}
|
||||
RoutePoint.task.id = "ComboTask"
|
||||
|
||||
@@ -1100,13 +1100,19 @@ function FLIGHTGROUP:Route(waypoints)
|
||||
|
||||
-- Route (Mission) task.
|
||||
local TaskRoute=self.group:TaskRoute(waypoints)
|
||||
env.info("FF waypoints in route:")
|
||||
self:I({waypoints=waypoints})
|
||||
table.insert(Tasks, TaskRoute)
|
||||
|
||||
-- TaskCombo of enroute and mission tasks.
|
||||
local TaskCombo=self.group:TaskCombo(Tasks)
|
||||
|
||||
-- Set tasks.
|
||||
self:SetTask(TaskCombo)
|
||||
if #Tasks>1 then
|
||||
self:SetTask(TaskCombo)
|
||||
else
|
||||
self:SetTask(TaskRoute)
|
||||
end
|
||||
|
||||
else
|
||||
self:I(self.lid.."FF ERROR!")
|
||||
@@ -1223,18 +1229,20 @@ function FLIGHTGROUP:onafterStart(From, Event, To)
|
||||
-- Short info.
|
||||
local text=string.format("Starting flight group v%s", FLIGHTGROUP.version)
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Set current waypoint. Counting starts a one.
|
||||
self.currentwp=1
|
||||
|
||||
-- Check if the group is already alive and if so, add its elements.
|
||||
local group=GROUP:FindByName(self.groupname)
|
||||
|
||||
|
||||
if group then
|
||||
|
||||
-- Set group object.
|
||||
self.group=group
|
||||
|
||||
-- Get units of group.
|
||||
local units=group:GetUnits()
|
||||
local units=group:GetUnits() or {}
|
||||
|
||||
-- Add elemets.
|
||||
for _,unit in pairs(units) do
|
||||
@@ -1987,47 +1995,51 @@ function FLIGHTGROUP:_InitGroup()
|
||||
|
||||
local unit=self.group:GetUnit(1)
|
||||
|
||||
--local nunits=self.group:GetUnits()
|
||||
if unit then
|
||||
|
||||
self.descriptors=unit:GetDesc()
|
||||
--local nunits=self.group:GetUnits()
|
||||
|
||||
self.descriptors=unit:GetDesc()
|
||||
|
||||
self.actype=unit:GetTypeName()
|
||||
|
||||
self.ceiling=self.descriptors.Hmax
|
||||
|
||||
self.ai=not self:_IsHuman(self.group)
|
||||
|
||||
for _,_element in pairs(self.elements) do
|
||||
local element=_element --#FLIGHTGROUP.Element
|
||||
element.ai=not self:_IsHumanUnit(element.unit)
|
||||
end
|
||||
|
||||
self.actype=unit:GetTypeName()
|
||||
|
||||
self.ceiling=self.descriptors.Hmax
|
||||
|
||||
self.ai=not self:_IsHuman(self.group)
|
||||
|
||||
for _,_element in pairs(self.elements) do
|
||||
local element=_element --#FLIGHTGROUP.Element
|
||||
element.ai=not self:_IsHumanUnit(element.unit)
|
||||
-- Init waypoints.
|
||||
if not self.waypoints then
|
||||
self:InitWaypoints()
|
||||
end
|
||||
|
||||
-- Debug info.
|
||||
local text=string.format("Initialized Flight Group %s:\n", self.groupname)
|
||||
text=text..string.format("AC type = %s\n", self.actype)
|
||||
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedmax))
|
||||
text=text..string.format("Ceiling = %.1f feet\n", UTILS.MetersToFeet(self.ceiling))
|
||||
text=text..string.format("AI = %s\n", tostring(self.ai))
|
||||
text=text..string.format("Helicopter = %s\n", tostring(self.group:IsHelicopter()))
|
||||
text=text..string.format("Elements = %d\n", #self.elements)
|
||||
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
||||
text=text..string.format("FSM state = %s\n", self:GetState())
|
||||
text=text..string.format("Is alive = %s\n", tostring(self.group:IsAlive()))
|
||||
text=text..string.format("Late activat = %s\n", tostring(self:IsLateActivated()))
|
||||
text=text..string.format("Uncontrolled = %s\n", tostring(self:IsUncontrolled()))
|
||||
text=text..string.format("Start Air = %s\n", tostring(self:IsTakeoffAir()))
|
||||
text=text..string.format("Start Cold = %s\n", tostring(self:IsTakeoffCold()))
|
||||
text=text..string.format("Start Hot = %s\n", tostring(self:IsTakeoffHot()))
|
||||
text=text..string.format("Start Rwy = %s\n", tostring(self:IsTakeoffRunway()))
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Init done.
|
||||
self.groupinitialized=true
|
||||
|
||||
end
|
||||
|
||||
-- Init waypoints.
|
||||
if not self.waypoints then
|
||||
self:InitWaypoints()
|
||||
end
|
||||
|
||||
-- Debug info.
|
||||
local text=string.format("Initialized Flight Group %s:\n", self.groupname)
|
||||
text=text..string.format("AC type = %s\n", self.actype)
|
||||
text=text..string.format("Speed max = %.1f Knots\n", UTILS.KmphToKnots(self.speedmax))
|
||||
text=text..string.format("Ceiling = %.1f feet\n", UTILS.MetersToFeet(self.ceiling))
|
||||
text=text..string.format("AI = %s\n", tostring(self.ai))
|
||||
text=text..string.format("Helicopter = %s\n", tostring(self.group:IsHelicopter()))
|
||||
text=text..string.format("Elements = %d\n", #self.elements)
|
||||
text=text..string.format("Waypoints = %d\n", #self.waypoints)
|
||||
text=text..string.format("FSM state = %s\n", self:GetState())
|
||||
text=text..string.format("Is alive = %s\n", tostring(self.group:IsAlive()))
|
||||
text=text..string.format("Late activat = %s\n", tostring(self:IsLateActivated()))
|
||||
text=text..string.format("Uncontrolled = %s\n", tostring(self:IsUncontrolled()))
|
||||
text=text..string.format("Start Air = %s\n", tostring(self:IsTakeoffAir()))
|
||||
text=text..string.format("Start Cold = %s\n", tostring(self:IsTakeoffCold()))
|
||||
text=text..string.format("Start Hot = %s\n", tostring(self:IsTakeoffHot()))
|
||||
text=text..string.format("Start Rwy = %s\n", tostring(self:IsTakeoffRunway()))
|
||||
self:I(self.lid..text)
|
||||
|
||||
-- Init done.
|
||||
self.groupinitialized=true
|
||||
|
||||
return self
|
||||
end
|
||||
@@ -2312,6 +2324,10 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
|
||||
-- TODO: This, however, leads to the flight to go right over this point when it is on an airport ==> Need to test Waypoint takeoff
|
||||
local current=self.group:GetCoordinate():WaypointAir(nil, COORDINATE.WaypointType.TurningPoint, COORDINATE.WaypointAction.TurningPoint, 350, true, nil, {}, "Current")
|
||||
table.insert(wp, current)
|
||||
|
||||
for i=n, #self.waypoints do
|
||||
table.insert(wp, self.waypoints[i])
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
@@ -2334,13 +2350,14 @@ function FLIGHTGROUP:onafterUpdateRoute(From, Event, To, n)
|
||||
end
|
||||
]]
|
||||
|
||||
|
||||
-- Debug info.
|
||||
local hb=self.homebase and self.homebase:GetName() or "unknown"
|
||||
local db=self.destbase and self.destbase:GetName() or "unknown"
|
||||
self:I(self.lid..string.format("Updating route for WP>=%d/%d (%d) homebase=%s destination=%s", n, #wp, #self.waypoints, hb, db))
|
||||
|
||||
|
||||
if #wp>0 then
|
||||
if #wp>1 then
|
||||
|
||||
-- Route group to all defined waypoints remaining.
|
||||
self:Route(wp, 1)
|
||||
@@ -3763,9 +3780,6 @@ function FLIGHTGROUP:InitWaypoints(waypoints)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Set current waypoint. Counting starts a one.
|
||||
self.currentwp=1
|
||||
|
||||
-- Get home and destination airbases from waypoints.
|
||||
self.homebase=self:GetHomebaseFromWaypoints()
|
||||
|
||||
@@ -861,34 +861,18 @@ function CONTROLLABLE:TaskAttackGroup( AttackGroup, WeaponType, WeaponExpend, At
|
||||
-- }
|
||||
-- }
|
||||
|
||||
local DirectionEnabled = nil
|
||||
if Direction then
|
||||
DirectionEnabled = true
|
||||
else
|
||||
DirectionEnabled = false
|
||||
Direction=0
|
||||
end
|
||||
|
||||
local AltitudeEnabled = nil
|
||||
if Altitude then
|
||||
AltitudeEnabled = true
|
||||
else
|
||||
AltitudeEnabled = false
|
||||
Altitude=0
|
||||
end
|
||||
|
||||
local DCSTask
|
||||
DCSTask = { id = 'AttackGroup',
|
||||
local DCSTask = { id = 'AttackGroup',
|
||||
params = {
|
||||
groupId = AttackGroup:GetID(),
|
||||
weaponType = WeaponType,
|
||||
expend = WeaponExpend,
|
||||
weaponType = WeaponType or 1073741822,
|
||||
expend = WeaponExpend or "Auto",
|
||||
attackQtyLimit = AttackQty and true or false,
|
||||
attackQty = AttackQty,
|
||||
directionEnabled = DirectionEnabled,
|
||||
direction = Direction,
|
||||
altitudeEnabled = AltitudeEnabled,
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = Direction and math.rad(Direction) or nil,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude,
|
||||
attackQtyLimit = AttackQtyLimit,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -914,15 +898,15 @@ function CONTROLLABLE:TaskAttackUnit(AttackUnit, GroupAttack, WeaponExpend, Atta
|
||||
id = 'AttackUnit',
|
||||
params = {
|
||||
unitId = AttackUnit:GetID(),
|
||||
groupAttack = GroupAttack or false,
|
||||
groupAttack = GroupAttack and GroupAttack or false,
|
||||
expend = WeaponExpend or "Auto",
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = math.rad(Direction or 0),
|
||||
direction = Direction and math.rad(Direction) or nil,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude or math.max(1000, AttackUnit:GetAltitude()),
|
||||
altitude = Altitude,
|
||||
attackQtyLimit = AttackQty and true or false,
|
||||
attackQty = AttackQty,
|
||||
weaponType = WeaponType
|
||||
weaponType = WeaponType or 1073741822,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -946,25 +930,6 @@ end
|
||||
function CONTROLLABLE:TaskBombing( Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, Divebomb )
|
||||
self:F( { self.ControllableName, Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, Divebomb } )
|
||||
|
||||
local _groupattack=false
|
||||
if GroupAttack then
|
||||
_groupattack=GroupAttack
|
||||
end
|
||||
|
||||
local _direction=0
|
||||
local _directionenabled=false
|
||||
if Direction then
|
||||
_direction=math.rad(Direction)
|
||||
_directionenabled=true
|
||||
end
|
||||
|
||||
local _altitude=5000
|
||||
local _altitudeenabled=false
|
||||
if Altitude then
|
||||
_altitude=Altitude
|
||||
_altitudeenabled=true
|
||||
end
|
||||
|
||||
local _attacktype=nil
|
||||
if Divebomb then
|
||||
_attacktype="Dive"
|
||||
@@ -975,17 +940,18 @@ function CONTROLLABLE:TaskBombing( Vec2, GroupAttack, WeaponExpend, AttackQty, D
|
||||
DCSTask = {
|
||||
id = 'Bombing',
|
||||
params = {
|
||||
point = Vec2,
|
||||
x = Vec2.x,
|
||||
y = Vec2.y,
|
||||
groupAttack = _groupattack,
|
||||
groupAttack = GroupAttack and GroupAttack or false,
|
||||
expend = WeaponExpend or "Auto",
|
||||
attackQtyLimit = false,
|
||||
attackQty = AttackQty or 1,
|
||||
directionEnabled = _directionenabled,
|
||||
direction = _direction,
|
||||
altitudeEnabled = _altitudeenabled,
|
||||
altitude = _altitude,
|
||||
weaponType = WeaponType,
|
||||
attackQtyLimit = AttackQty and true or false,
|
||||
attackQty = AttackQty,
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = Direction and math.rad(Direction) or nil,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude,
|
||||
weaponType = WeaponType or 1073741822,
|
||||
attackType = _attacktype,
|
||||
},
|
||||
}
|
||||
@@ -998,7 +964,7 @@ end
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param DCS#Vec2 Vec2 2D-coordinates of the point to deliver weapon at.
|
||||
-- @param #boolean GroupAttack (Optional) If true, all units in the group will attack the Unit when found.
|
||||
-- @param DCS#AI.Task.WeaponExpend WeaponExpend (Optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.
|
||||
-- @param DCS#AI.Task.WeaponExpend WeaponExpend (Optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit will choose expend on its own discretion.
|
||||
-- @param #number AttackQty (Optional) This parameter limits maximal quantity of attack. The aicraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aicraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo.
|
||||
-- @param DCS#Azimuth Direction (Optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction.
|
||||
-- @param #number Altitude (Optional) The altitude [meters] from where to attack. Default 30 m.
|
||||
@@ -1021,7 +987,7 @@ function CONTROLLABLE:TaskAttackMapObject( Vec2, GroupAttack, WeaponExpend, Atta
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = Direction,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude or 30,
|
||||
altitude = Altitude,
|
||||
weaponType = WeaponType or 1073741822,
|
||||
},
|
||||
},
|
||||
@@ -1035,7 +1001,7 @@ end
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param DCS#Vec2 Vec2 2D-coordinates of the point to deliver weapon at.
|
||||
-- @param #boolean GroupAttack (optional) If true, all units in the group will attack the Unit when found.
|
||||
-- @param DCS#AI.Task.WeaponExpend WeaponExpend (optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit / controllable will choose expend on its own discretion.
|
||||
-- @param DCS#AI.Task.WeaponExpend WeaponExpend (optional) Determines how much weapon will be released at each attack. If parameter is not defined the unit will choose expend on its own discretion.
|
||||
-- @param #number AttackQty (optional) This parameter limits maximal quantity of attack. The aicraft/controllable will not make more attack than allowed even if the target controllable not destroyed and the aicraft/controllable still have ammo. If not defined the aircraft/controllable will attack target until it will be destroyed or until the aircraft/controllable will run out of ammo.
|
||||
-- @param DCS#Azimuth Direction (optional) Desired ingress direction from the target to the attacking aircraft. Controllable/aircraft will make its attacks from the direction. Of course if there is no way to attack from the direction due the terrain controllable/aircraft will choose another direction.
|
||||
-- @param #number Altitude (optional) The altitude from where to attack.
|
||||
@@ -1045,55 +1011,24 @@ end
|
||||
function CONTROLLABLE:TaskCarpetBombing(Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, CarpetLength)
|
||||
self:F2( { self.ControllableName, Vec2, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, WeaponType, CarpetLength } )
|
||||
|
||||
local _groupattack=false
|
||||
if GroupAttack then
|
||||
_groupattack=GroupAttack
|
||||
end
|
||||
|
||||
local _direction=0
|
||||
local _directionenabled=false
|
||||
if Direction then
|
||||
_direction=math.rad(Direction)
|
||||
_directionenabled=true
|
||||
end
|
||||
|
||||
local _altitude=0
|
||||
local _altitudeenabled=false
|
||||
if Altitude then
|
||||
_altitude=Altitude
|
||||
_altitudeenabled=true
|
||||
end
|
||||
|
||||
-- default to 500m
|
||||
local _carpetLength = 500
|
||||
if CarpetLength then
|
||||
_carpetLength = CarpetLength
|
||||
end
|
||||
|
||||
local _weaponexpend = "Auto"
|
||||
if WeaponExpend then
|
||||
_weaponexpend = WeaponExpend
|
||||
end
|
||||
|
||||
-- Build Task Structure
|
||||
local DCSTask
|
||||
DCSTask = {
|
||||
local DCSTask = {
|
||||
id = 'CarpetBombing',
|
||||
params = {
|
||||
attackType = "Carpet",
|
||||
point = Vec2,
|
||||
x = Vec2.x,
|
||||
y = Vec2.y,
|
||||
groupAttack = _groupattack,
|
||||
carpetLength = _carpetLength,
|
||||
weaponType = WeaponType,
|
||||
expend = "All",
|
||||
attackQtyLimit = false, --AttackQty and true or false,
|
||||
attackQty = AttackQty or 1,
|
||||
directionEnabled = _directionenabled,
|
||||
direction = _direction,
|
||||
altitudeEnabled = _altitudeenabled,
|
||||
altitude = _altitude
|
||||
groupAttack = GroupAttack and GroupAttack or false,
|
||||
carpetLength = CarpetLength or 500,
|
||||
weaponType = WeaponType or ENUMS.WeaponFlag.AnyBomb,
|
||||
expend = WeaponExpend or "All",
|
||||
attackQtyLimit = AttackQty and true or false,
|
||||
attackQty = AttackQty,
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = Direction and math.rad(Direction) or nil,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1148,7 +1083,15 @@ function CONTROLLABLE:TaskEmbarking(Vec2, GroupSetForEmbarking, Duration, Distri
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Table of group IDs for embarking.
|
||||
local Distribution={}
|
||||
|
||||
if DistributionGroupSet then
|
||||
for _,_group in pairs(DistributionGroupSet:GetSet()) do
|
||||
local group=_group --Wrapper.Group#GROUP
|
||||
table.insert(Distribution, group:GetID())
|
||||
end
|
||||
end
|
||||
|
||||
local DCSTask = {
|
||||
id = 'Embarking',
|
||||
@@ -1169,68 +1112,22 @@ function CONTROLLABLE:TaskEmbarking(Vec2, GroupSetForEmbarking, Duration, Distri
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- (AIR) Move the controllable to a Vec2 Point, wait for a defined duration and embark a controllable.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param DCS#Vec2 Vec2 The point where to wait.
|
||||
-- @param #number Duration The duration in seconds to wait.
|
||||
-- @param #CONTROLLABLE EmbarkingControllable The controllable to be embarked.
|
||||
-- @return DCS#Task The DCS task structure
|
||||
function CONTROLLABLE:TaskDisembarking(Vec2, Duration, EmbarkingControllable)
|
||||
|
||||
-- Table of group IDs for embarking.
|
||||
local g4e={}
|
||||
|
||||
if GroupSetForEmbarking then
|
||||
for _,_group in pairs(GroupSetForEmbarking:GetSet()) do
|
||||
local group=_group --Wrapper.Group#GROUP
|
||||
table.insert(g4e, group:GetID())
|
||||
end
|
||||
else
|
||||
self:E("ERROR: No groups for embarking specified!")
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
local DCSTask = {
|
||||
id = 'Disembarking',
|
||||
params = {
|
||||
point = Vec2,
|
||||
x = Vec2.x,
|
||||
y = Vec2.y,
|
||||
duration = Duration,
|
||||
groupsForEmbarking = { EmbarkingControllable:GetID() },
|
||||
durationFlag = durationflag,
|
||||
distributionFlag = false,
|
||||
distribution = {},
|
||||
}
|
||||
}
|
||||
|
||||
return DCSTask
|
||||
end
|
||||
|
||||
----
|
||||
|
||||
--- (AIR) Orbit at a specified position at a specified alititude during a specified duration with a specified speed.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param DCS#Vec2 Point The point to hold the position.
|
||||
-- @param #number Altitude The altitude [m] to hold the position.
|
||||
-- @param #number Altitude The altitude AGL in meters to hold the position.
|
||||
-- @param #number Speed The speed [m/s] flying when holding the position.
|
||||
-- @return #CONTROLLABLE self
|
||||
function CONTROLLABLE:TaskOrbitCircleAtVec2( Point, Altitude, Speed )
|
||||
self:F2( { self.ControllableName, Point, Altitude, Speed } )
|
||||
|
||||
local LandHeight = land.getHeight( Point )
|
||||
|
||||
self:T3( { LandHeight } )
|
||||
|
||||
local DCSTask = {
|
||||
id = 'Orbit',
|
||||
params = {
|
||||
pattern = AI.Task.OrbitPattern.CIRCLE,
|
||||
point = Point,
|
||||
speed = Speed,
|
||||
altitude = Altitude + LandHeight
|
||||
altitude = Altitude + land.getHeight( Point )
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1331,7 +1228,7 @@ function CONTROLLABLE:TaskBombingRunway(Airbase, WeaponType, WeaponExpend, Attac
|
||||
expend = WeaponExpend or AI.Task.WeaponExpend.ALL,
|
||||
attackQty = AttackQty or 1,
|
||||
direction = Direction and math.rad(Direction) or nil,
|
||||
groupAttack = GroupAttack,
|
||||
groupAttack = GroupAttack and GroupAttack or false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1419,14 +1316,13 @@ function CONTROLLABLE:TaskFollow( FollowControllable, Vec3, LastWaypointIndex )
|
||||
lastWptIndexFlagChangedManually = true
|
||||
end
|
||||
|
||||
local DCSTask
|
||||
DCSTask = {
|
||||
local DCSTask = {
|
||||
id = 'Follow',
|
||||
params = {
|
||||
groupId = FollowControllable:GetID(),
|
||||
pos = Vec3,
|
||||
lastWptIndexFlag = LastWaypointIndexFlag,
|
||||
lastWptIndex = LastWaypointIndex,
|
||||
groupId = FollowControllable:GetID(),
|
||||
pos = Vec3,
|
||||
lastWptIndexFlag = LastWaypointIndexFlag,
|
||||
lastWptIndex = LastWaypointIndex,
|
||||
lastWptIndexFlagChangedManually = lastWptIndexFlagChangedManually,
|
||||
}
|
||||
}
|
||||
@@ -1444,7 +1340,7 @@ end
|
||||
-- @param DCS#Vec3 Vec3 Position of the unit / lead unit of the controllable relative lead unit of another controllable in frame reference oriented by course of lead unit of another controllable. If another controllable is on land the unit / controllable will orbit around.
|
||||
-- @param #number LastWaypointIndex Detach waypoint of another controllable. Once reached the unit / controllable Follow task is finished.
|
||||
-- @param #number EngagementDistance Maximal distance from escorted controllable to threat. If the threat is already engaged by escort escort will disengage if the distance becomes greater than 1.5 * engagementDistMax.
|
||||
-- @param DCS#AttributeNameArray TargetTypes Array of AttributeName that is contains threat categories allowed to engage.
|
||||
-- @param DCS#AttributeNameArray TargetTypes Array of AttributeName that is contains threat categories allowed to engage. Default {"Air"}.
|
||||
-- @return DCS#Task The DCS task structure.
|
||||
function CONTROLLABLE:TaskEscort( FollowControllable, Vec3, LastWaypointIndex, EngagementDistance, TargetTypes )
|
||||
self:F2( { self.ControllableName, FollowControllable, Vec3, LastWaypointIndex, EngagementDistance, TargetTypes } )
|
||||
@@ -1461,22 +1357,16 @@ function CONTROLLABLE:TaskEscort( FollowControllable, Vec3, LastWaypointIndex, E
|
||||
-- }
|
||||
-- }
|
||||
|
||||
local LastWaypointIndexFlag = false
|
||||
if LastWaypointIndex then
|
||||
LastWaypointIndexFlag = true
|
||||
end
|
||||
|
||||
TargetTypes=TargetTypes or {}
|
||||
|
||||
local DCSTask
|
||||
DCSTask = { id = 'Escort',
|
||||
DCSTask = {
|
||||
id = 'Escort',
|
||||
params = {
|
||||
groupId = FollowControllable:GetID(),
|
||||
pos = Vec3,
|
||||
lastWptIndexFlag = LastWaypointIndexFlag,
|
||||
lastWptIndex = LastWaypointIndex,
|
||||
groupId = FollowControllable:GetID(),
|
||||
pos = Vec3,
|
||||
lastWptIndexFlag = LastWaypointIndex and true or false,
|
||||
lastWptIndex = LastWaypointIndex,
|
||||
engagementDistMax = EngagementDistance,
|
||||
targetTypes = TargetTypes,
|
||||
targetTypes = TargetTypes or {"Air"},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1650,29 +1540,19 @@ function CONTROLLABLE:EnRouteTaskEngageGroup( AttackGroup, Priority, WeaponType,
|
||||
-- }
|
||||
-- }
|
||||
|
||||
local DirectionEnabled = nil
|
||||
if Direction then
|
||||
DirectionEnabled = true
|
||||
end
|
||||
|
||||
local AltitudeEnabled = nil
|
||||
if Altitude then
|
||||
AltitudeEnabled = true
|
||||
end
|
||||
|
||||
local DCSTask
|
||||
DCSTask = { id = 'EngageControllable',
|
||||
local DCSTask = {
|
||||
id = 'EngageControllable',
|
||||
params = {
|
||||
groupId = AttackGroup:GetID(),
|
||||
weaponType = WeaponType,
|
||||
expend = WeaponExpend,
|
||||
attackQty = AttackQty,
|
||||
directionEnabled = DirectionEnabled,
|
||||
direction = Direction,
|
||||
altitudeEnabled = AltitudeEnabled,
|
||||
altitude = Altitude,
|
||||
attackQtyLimit = AttackQtyLimit,
|
||||
priority = Priority,
|
||||
groupId = AttackGroup:GetID(),
|
||||
weaponType = WeaponType,
|
||||
expend = WeaponExpend or "Auto",
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = Direction,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude,
|
||||
attackQtyLimit = AttackQty and true or false,
|
||||
attackQty = AttackQty,
|
||||
priority = Priority or 1,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1694,36 +1574,22 @@ end
|
||||
-- @param #boolean ControllableAttack (optional) Flag indicates that the target must be engaged by all aircrafts of the controllable. Has effect only if the task is assigned to a controllable, not to a single aircraft.
|
||||
-- @return DCS#Task The DCS task structure.
|
||||
function CONTROLLABLE:EnRouteTaskEngageUnit( EngageUnit, Priority, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, Visible, ControllableAttack )
|
||||
self:F2( { self.ControllableName, EngageUnit, Priority, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, Visible, ControllableAttack } )
|
||||
self:F2( { self.ControllableName, EngageUnit, Priority, GroupAttack, WeaponExpend, AttackQty, Direction, Altitude, Visible, ControllableAttack } )
|
||||
|
||||
-- EngageUnit = {
|
||||
-- id = 'EngageUnit',
|
||||
-- params = {
|
||||
-- unitId = Unit.ID,
|
||||
-- weaponType = number,
|
||||
-- expend = enum AI.Task.WeaponExpend
|
||||
-- attackQty = number,
|
||||
-- direction = Azimuth,
|
||||
-- attackQtyLimit = boolean,
|
||||
-- controllableAttack = boolean,
|
||||
-- priority = number,
|
||||
-- }
|
||||
-- }
|
||||
|
||||
local DCSTask
|
||||
DCSTask = { id = 'EngageUnit',
|
||||
local DCSTask = {
|
||||
id = 'EngageUnit',
|
||||
params = {
|
||||
unitId = EngageUnit:GetID(),
|
||||
priority = Priority or 1,
|
||||
groupAttack = GroupAttack or false,
|
||||
visible = Visible or false,
|
||||
expend = WeaponExpend or "Auto",
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = Direction,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude,
|
||||
attackQtyLimit = AttackQty and true or false,
|
||||
attackQty = AttackQty,
|
||||
unitId = EngageUnit:GetID(),
|
||||
priority = Priority or 1,
|
||||
groupAttack = GroupAttack and GroupAttack or false,
|
||||
visible = Visible and Visible or false,
|
||||
expend = WeaponExpend or "Auto",
|
||||
directionEnabled = Direction and true or false,
|
||||
direction = Direction and math.rad(Direction) or nil,
|
||||
altitudeEnabled = Altitude and true or false,
|
||||
altitude = Altitude,
|
||||
attackQtyLimit = AttackQty and true or false,
|
||||
attackQty = AttackQty,
|
||||
controllableAttack = ControllableAttack,
|
||||
},
|
||||
},
|
||||
@@ -1782,33 +1648,22 @@ end
|
||||
-- If the task is assigned to the controllable lead unit will be a FAC.
|
||||
-- @param #CONTROLLABLE self
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE AttackGroup Target CONTROLLABLE.
|
||||
-- @param #number Priority All en-route tasks have the priority parameter. This is a number (less value - higher priority) that determines actions related to what task will be performed first.
|
||||
-- @param #number WeaponType Bitmask of weapon types those allowed to use. If parameter is not defined that means no limits on weapon usage.
|
||||
-- @param DCS#AI.Task.Designation Designation (optional) Designation type.
|
||||
-- @param #number Priority (Optional) All en-route tasks have the priority parameter. This is a number (less value - higher priority) that determines actions related to what task will be performed first. Default is 0.
|
||||
-- @param #number WeaponType (Optional) Bitmask of weapon types those allowed to use. Default is "Auto".
|
||||
-- @param DCS#AI.Task.Designation Designation (Optional) Designation type.
|
||||
-- @param #boolean Datalink (optional) Allows to use datalink to send the target information to attack aircraft. Enabled by default.
|
||||
-- @return DCS#Task The DCS task structure.
|
||||
function CONTROLLABLE:EnRouteTaskFAC_EngageGroup( AttackGroup, Priority, WeaponType, Designation, Datalink )
|
||||
self:F2( { self.ControllableName, AttackGroup, WeaponType, Priority, Designation, Datalink } )
|
||||
|
||||
-- FAC_EngageControllable = {
|
||||
-- id = 'FAC_EngageControllable',
|
||||
-- params = {
|
||||
-- groupId = Group.ID,
|
||||
-- weaponType = number,
|
||||
-- designation = enum AI.Task.Designation,
|
||||
-- datalink = boolean,
|
||||
-- priority = number,
|
||||
-- }
|
||||
-- }
|
||||
|
||||
local DCSTask
|
||||
DCSTask = { id = 'FAC_EngageControllable',
|
||||
local DCSTask = {
|
||||
id = 'FAC_EngageControllable',
|
||||
params = {
|
||||
groupId = AttackGroup:GetID(),
|
||||
weaponType = WeaponType,
|
||||
groupId = AttackGroup:GetID(),
|
||||
weaponType = WeaponType or "Auto",
|
||||
designation = Designation,
|
||||
datalink = Datalink,
|
||||
priority = Priority,
|
||||
datalink = Datalink and Datalink or false,
|
||||
priority = Priority or 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1979,9 +1834,12 @@ function CONTROLLABLE:TaskEmbarkToTransport( Point, Radius )
|
||||
self:F2( { self.ControllableName, Point, Radius } )
|
||||
|
||||
local DCSTask --DCS#Task
|
||||
DCSTask = { id = 'EmbarkToTransport',
|
||||
params = { x = Point.x,
|
||||
y = Point.y,
|
||||
DCSTask = {
|
||||
id = 'EmbarkToTransport',
|
||||
params = {
|
||||
point = Point,
|
||||
x = Point.x,
|
||||
y = Point.y,
|
||||
zoneRadius = Radius,
|
||||
}
|
||||
}
|
||||
@@ -2236,7 +2094,8 @@ function CONTROLLABLE:TaskRoute( Points )
|
||||
local DCSTask = {
|
||||
id = 'Mission',
|
||||
params = {
|
||||
route = { points = Points, },
|
||||
airborne = self:IsAir(),
|
||||
route = {points = Points},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user