mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2026-08-21 11:53:30 +00:00
Merge branch 'FF/Ops' into FF/OpsDev
This commit is contained in:
@@ -1475,7 +1475,7 @@ function EVENT:onEvent( Event )
|
|||||||
-- SCENERY
|
-- SCENERY
|
||||||
---
|
---
|
||||||
Event.TgtDCSUnit = Event.target
|
Event.TgtDCSUnit = Event.target
|
||||||
Event.TgtDCSUnitName = Event.TgtDCSUnit.getName and Event.TgtDCSUnit.getName() or nil
|
Event.TgtDCSUnitName = Event.TgtDCSUnit.getName and Event.TgtDCSUnit:getName() or nil
|
||||||
if Event.TgtDCSUnitName~=nil then
|
if Event.TgtDCSUnitName~=nil then
|
||||||
Event.TgtUnitName = Event.TgtDCSUnitName
|
Event.TgtUnitName = Event.TgtDCSUnitName
|
||||||
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
|
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
|
||||||
|
|||||||
@@ -3,8 +3,6 @@
|
|||||||
-- ## Features:
|
-- ## Features:
|
||||||
--
|
--
|
||||||
-- * Provides a COORDINATE class, which allows to manage points in 3D space and perform various operations on it.
|
-- * Provides a COORDINATE class, which allows to manage points in 3D space and perform various operations on it.
|
||||||
-- * Provides a POINT\_VEC2 class, which is derived from COORDINATE, and allows to manage points in 3D space, but from a Lat/Lon and Altitude perspective.
|
|
||||||
-- * Provides a POINT\_VEC3 class, which is derived from COORDINATE, and allows to manage points in 3D space, but from a X, Z and Y vector perspective.
|
|
||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
@@ -3892,171 +3890,3 @@ do -- COORDINATE
|
|||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
do
|
|
||||||
|
|
||||||
--- The POINT_VEC3 class
|
|
||||||
-- @type POINT_VEC3
|
|
||||||
-- @field #number x The x coordinate in 3D space.
|
|
||||||
-- @field #number y The y coordinate in 3D space.
|
|
||||||
-- @field #number z The z COORDINATE in 3D space.
|
|
||||||
-- @field Utilities.Utils#SMOKECOLOR SmokeColor
|
|
||||||
-- @field Utilities.Utils#FLARECOLOR FlareColor
|
|
||||||
-- @field #POINT_VEC3.RoutePointAltType RoutePointAltType
|
|
||||||
-- @field #POINT_VEC3.RoutePointType RoutePointType
|
|
||||||
-- @field #POINT_VEC3.RoutePointAction RoutePointAction
|
|
||||||
-- @extends #COORDINATE
|
|
||||||
|
|
||||||
|
|
||||||
--- Defines a 3D point in the simulator and with its methods, you can use or manipulate the point in 3D space.
|
|
||||||
--
|
|
||||||
-- **DEPRECATED - PLEASE USE COORDINATE!**
|
|
||||||
--
|
|
||||||
-- **Important Note:** Most of the functions in this section were taken from MIST, and reworked to OO concepts.
|
|
||||||
-- In order to keep the credibility of the the author,
|
|
||||||
-- I want to emphasize that the formulas embedded in the MIST framework were created by Grimes or previous authors,
|
|
||||||
-- who you can find on the Eagle Dynamics Forums.
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- ## POINT_VEC3 constructor
|
|
||||||
--
|
|
||||||
-- A new POINT_VEC3 object can be created with:
|
|
||||||
--
|
|
||||||
-- * @{#POINT_VEC3.New}(): a 3D point.
|
|
||||||
-- * @{#POINT_VEC3.NewFromVec3}(): a 3D point created from a @{DCS#Vec3}.
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- ## Manupulate the X, Y, Z coordinates of the POINT_VEC3
|
|
||||||
--
|
|
||||||
-- A POINT_VEC3 class works in 3D space. It contains internally an X, Y, Z coordinate.
|
|
||||||
-- Methods exist to manupulate these coordinates.
|
|
||||||
--
|
|
||||||
-- The current X, Y, Z axis can be retrieved with the methods @{#POINT_VEC3.GetX}(), @{#POINT_VEC3.GetY}(), @{#POINT_VEC3.GetZ}() respectively.
|
|
||||||
-- The methods @{#POINT_VEC3.SetX}(), @{#POINT_VEC3.SetY}(), @{#POINT_VEC3.SetZ}() change the respective axis with a new value.
|
|
||||||
-- The current axis values can be changed by using the methods @{#POINT_VEC3.AddX}(), @{#POINT_VEC3.AddY}(), @{#POINT_VEC3.AddZ}()
|
|
||||||
-- to add or substract a value from the current respective axis value.
|
|
||||||
-- Note that the Set and Add methods return the current POINT_VEC3 object, so these manipulation methods can be chained... For example:
|
|
||||||
--
|
|
||||||
-- local Vec3 = PointVec3:AddX( 100 ):AddZ( 150 ):GetVec3()
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- ## 3D calculation methods
|
|
||||||
--
|
|
||||||
-- Various calculation methods exist to use or manipulate 3D space. Find below a short description of each method:
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- ## Point Randomization
|
|
||||||
--
|
|
||||||
-- Various methods exist to calculate random locations around a given 3D point.
|
|
||||||
--
|
|
||||||
-- * @{#POINT_VEC3.GetRandomPointVec3InRadius}(): Provides a random 3D point around the current 3D point, in the given inner to outer band.
|
|
||||||
--
|
|
||||||
--
|
|
||||||
-- @field #POINT_VEC3
|
|
||||||
POINT_VEC3 = {
|
|
||||||
ClassName = "POINT_VEC3",
|
|
||||||
Metric = true,
|
|
||||||
RoutePointAltType = {
|
|
||||||
BARO = "BARO",
|
|
||||||
},
|
|
||||||
RoutePointType = {
|
|
||||||
TakeOffParking = "TakeOffParking",
|
|
||||||
TurningPoint = "Turning Point",
|
|
||||||
},
|
|
||||||
RoutePointAction = {
|
|
||||||
FromParkingArea = "From Parking Area",
|
|
||||||
TurningPoint = "Turning Point",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
--- RoutePoint AltTypes
|
|
||||||
-- @type POINT_VEC3.RoutePointAltType
|
|
||||||
-- @field BARO "BARO"
|
|
||||||
|
|
||||||
--- RoutePoint Types
|
|
||||||
-- @type POINT_VEC3.RoutePointType
|
|
||||||
-- @field TakeOffParking "TakeOffParking"
|
|
||||||
-- @field TurningPoint "Turning Point"
|
|
||||||
|
|
||||||
--- RoutePoint Actions
|
|
||||||
-- @type POINT_VEC3.RoutePointAction
|
|
||||||
-- @field FromParkingArea "From Parking Area"
|
|
||||||
-- @field TurningPoint "Turning Point"
|
|
||||||
|
|
||||||
-- Constructor.
|
|
||||||
|
|
||||||
--- Create a new POINT_VEC3 object.
|
|
||||||
-- @param #POINT_VEC3 self
|
|
||||||
-- @param DCS#Distance x The x coordinate of the Vec3 point, pointing to the North.
|
|
||||||
-- @param DCS#Distance y The y coordinate of the Vec3 point, pointing Upwards.
|
|
||||||
-- @param DCS#Distance z The z coordinate of the Vec3 point, pointing to the Right.
|
|
||||||
-- @return Core.Point#POINT_VEC3
|
|
||||||
function POINT_VEC3:New( x, y, z )
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, COORDINATE:New( x, y, z ) ) -- Core.Point#POINT_VEC3
|
|
||||||
self:F2( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
do
|
|
||||||
|
|
||||||
--- @type POINT_VEC2
|
|
||||||
-- @field DCS#Distance x The x coordinate in meters.
|
|
||||||
-- @field DCS#Distance y the y coordinate in meters.
|
|
||||||
-- @extends Core.Point#COORDINATE
|
|
||||||
|
|
||||||
--- Defines a 2D point in the simulator. The height coordinate (if needed) will be the land height + an optional added height specified.
|
|
||||||
--
|
|
||||||
-- **DEPRECATED - PLEASE USE COORDINATE!**
|
|
||||||
--
|
|
||||||
-- ## POINT_VEC2 constructor
|
|
||||||
--
|
|
||||||
-- A new POINT_VEC2 instance can be created with:
|
|
||||||
--
|
|
||||||
-- * @{Core.Point#POINT_VEC2.New}(): a 2D point, taking an additional height parameter.
|
|
||||||
-- * @{Core.Point#POINT_VEC2.NewFromVec2}(): a 2D point created from a @{DCS#Vec2}.
|
|
||||||
--
|
|
||||||
-- ## Manupulate the X, Altitude, Y coordinates of the 2D point
|
|
||||||
--
|
|
||||||
-- A POINT_VEC2 class works in 2D space, with an altitude setting. It contains internally an X, Altitude, Y coordinate.
|
|
||||||
-- Methods exist to manupulate these coordinates.
|
|
||||||
--
|
|
||||||
-- The current X, Altitude, Y axis can be retrieved with the methods @{#POINT_VEC2.GetX}(), @{#POINT_VEC2.GetAlt}(), @{#POINT_VEC2.GetY}() respectively.
|
|
||||||
-- The methods @{#POINT_VEC2.SetX}(), @{#POINT_VEC2.SetAlt}(), @{#POINT_VEC2.SetY}() change the respective axis with a new value.
|
|
||||||
-- The current Lat(itude), Alt(itude), Lon(gitude) values can also be retrieved with the methods @{#POINT_VEC2.GetLat}(), @{#POINT_VEC2.GetAlt}(), @{#POINT_VEC2.GetLon}() respectively.
|
|
||||||
-- The current axis values can be changed by using the methods @{#POINT_VEC2.AddX}(), @{#POINT_VEC2.AddAlt}(), @{#POINT_VEC2.AddY}()
|
|
||||||
-- to add or substract a value from the current respective axis value.
|
|
||||||
-- Note that the Set and Add methods return the current POINT_VEC2 object, so these manipulation methods can be chained... For example:
|
|
||||||
--
|
|
||||||
-- local Vec2 = PointVec2:AddX( 100 ):AddY( 2000 ):GetVec2()
|
|
||||||
--
|
|
||||||
-- @field #POINT_VEC2
|
|
||||||
POINT_VEC2 = {
|
|
||||||
ClassName = "POINT_VEC2",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- POINT_VEC2 constructor.
|
|
||||||
-- @param #POINT_VEC2 self
|
|
||||||
-- @param DCS#Distance x The x coordinate of the Vec3 point, pointing to the North.
|
|
||||||
-- @param DCS#Distance y The y coordinate of the Vec3 point, pointing to the Right.
|
|
||||||
-- @param DCS#Distance LandHeightAdd (optional) The default height if required to be evaluated will be the land height of the x, y coordinate. You can specify an extra height to be added to the land height.
|
|
||||||
-- @return Core.Point#POINT_VEC2
|
|
||||||
function POINT_VEC2:New( x, y, LandHeightAdd )
|
|
||||||
|
|
||||||
local LandHeight = land.getHeight( { ["x"] = x, ["y"] = y } )
|
|
||||||
|
|
||||||
LandHeightAdd = LandHeightAdd or 0
|
|
||||||
LandHeight = LandHeight + LandHeightAdd
|
|
||||||
|
|
||||||
local self = BASE:Inherit( self, COORDINATE:New( x, LandHeight, y ) ) -- Core.Point#POINT_VEC2
|
|
||||||
self:F2( self )
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|||||||
@@ -945,7 +945,8 @@ do -- SET_BASE
|
|||||||
function SET_BASE:IsInSet(Object)
|
function SET_BASE:IsInSet(Object)
|
||||||
--self:F3(Object)
|
--self:F3(Object)
|
||||||
local outcome = false
|
local outcome = false
|
||||||
local name = Object:GetName()
|
if Object == nil then return false end
|
||||||
|
local name = (Object ~= nil and Object.GetName) and Object:GetName() or "none"
|
||||||
--self:I("SET_BASE: Objectname = "..name)
|
--self:I("SET_BASE: Objectname = "..name)
|
||||||
self:ForEach(
|
self:ForEach(
|
||||||
function(object)
|
function(object)
|
||||||
|
|||||||
@@ -1179,7 +1179,7 @@ function ZONE_RADIUS:Scan( ObjectCategories, UnitCategories )
|
|||||||
self.ScanData.SceneryTable = {}
|
self.ScanData.SceneryTable = {}
|
||||||
self.ScanData.Units = {}
|
self.ScanData.Units = {}
|
||||||
|
|
||||||
local ZoneCoord = self:GetCoordinate()
|
local ZoneCoord = self:GetCoordinate():SetAlt()
|
||||||
local ZoneRadius = self:GetRadius()
|
local ZoneRadius = self:GetRadius()
|
||||||
|
|
||||||
--self:F({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
|
--self:F({ZoneCoord = ZoneCoord, ZoneRadius = ZoneRadius, ZoneCoordLL = ZoneCoord:ToStringLLDMS()})
|
||||||
|
|||||||
@@ -0,0 +1,999 @@
|
|||||||
|
--- **Functional** - Build large airborne formations of aircraft.
|
||||||
|
--
|
||||||
|
-- **Features:**
|
||||||
|
--
|
||||||
|
-- * Build in-air formations consisting of more than 40 aircraft as one group.
|
||||||
|
-- * Build different formation types.
|
||||||
|
-- * Assign a group leader that will guide the large formation path.
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ## Additional Material:
|
||||||
|
--
|
||||||
|
-- * **Demo Missions:** [GitHub](https://github.com/FlightControl-Master/MOOSE_MISSIONS/tree/master/AI/FORMATION)
|
||||||
|
-- * **Guides:** None
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- ### Author: **FlightControl**
|
||||||
|
-- ### Contributions: **Applevangelist** (refactor)
|
||||||
|
--
|
||||||
|
-- ===
|
||||||
|
--
|
||||||
|
-- @module Functional.FORMATION
|
||||||
|
-- @image AI_Large_Formations.JPG
|
||||||
|
|
||||||
|
--- FORMATION class
|
||||||
|
-- @type FORMATION
|
||||||
|
-- @extends Core.Fsm#FSM_SET
|
||||||
|
-- @field Wrapper.Unit#UNIT FollowUnit
|
||||||
|
-- @field Core.Set#SET_GROUP FollowGroupSet
|
||||||
|
-- @field #string FollowName
|
||||||
|
-- @field Core.Scheduler#SCHEDULER FollowScheduler The instance of the SCHEDULER class.
|
||||||
|
-- @field #number FollowDistance The current follow distance.
|
||||||
|
-- @field DCS#AI.Option.Air.val.ROE OptionROE Which ROE is set to the FollowGroup.
|
||||||
|
-- @field DCS#AI.Option.Air.val.REACTION_ON_THREAT OptionReactionOnThreat Which REACTION_ON_THREAT is set to the FollowGroup.
|
||||||
|
-- @field #number dtFollow Time step between position updates.
|
||||||
|
|
||||||
|
|
||||||
|
--- Build (large) formations, make AI follow a @{Wrapper.Client#CLIENT} (player) leader or a @{Wrapper.Unit#UNIT} (AI) leader.
|
||||||
|
--
|
||||||
|
-- FORMATION makes AI @{Wrapper.Group#GROUP}s fly in formation of various compositions.
|
||||||
|
-- The FORMATION class models formations in a different manner than the internal DCS formation logic!!!
|
||||||
|
-- The purpose of the class is to:
|
||||||
|
--
|
||||||
|
-- * Make formation building a process that can be managed while in flight, rather than a task.
|
||||||
|
-- * Human players can guide formations, consisting of larget planes.
|
||||||
|
-- * Build large formations (like a large bomber field).
|
||||||
|
-- * Form formations that DCS does not support off-the-shelve.
|
||||||
|
--
|
||||||
|
-- A few remarks:
|
||||||
|
--
|
||||||
|
-- * Depending on the type of plane, the change in direction by the leader may result in the formation getting disentangled while in flight and needs to be rebuild.
|
||||||
|
-- * Formations are vulnerable to collissions, but is depending on the type of plane, the distance between the planes and the speed and angle executed by the leader.
|
||||||
|
-- * Formations may take a while to build up.
|
||||||
|
--
|
||||||
|
-- As a result, the FORMATION is not perfect, but is very useful to:
|
||||||
|
--
|
||||||
|
-- * Model large formations when flying straight line. You can build close formations when doing this.
|
||||||
|
-- * Make humans guide a large formation, when the planes are wide from each other.
|
||||||
|
--
|
||||||
|
-- ## FORMATION construction
|
||||||
|
--
|
||||||
|
-- Create a new SPAWN object with the @{#FORMATION.New} method:
|
||||||
|
--
|
||||||
|
-- * @{#FORMATION.New}(): Creates a new FORMATION object from a @{Wrapper.Group#GROUP} for a @{Wrapper.Client#CLIENT} or a @{Wrapper.Unit#UNIT}, with an optional briefing text.
|
||||||
|
--
|
||||||
|
-- ## Formation methods
|
||||||
|
--
|
||||||
|
-- The following methods can be used to set or change the formation:
|
||||||
|
--
|
||||||
|
-- * @{#FORMATION.FormationLine}(): Form a line formation (core formation function).
|
||||||
|
-- * @{#FORMATION.FormationTrail}(): Form a trail formation.
|
||||||
|
-- * @{#FORMATION.FormationLeftLine}(): Form a left line formation.
|
||||||
|
-- * @{#FORMATION.FormationRightLine}(): Form a right line formation.
|
||||||
|
-- * @{#FORMATION.FormationRightWing}(): Form a right wing formation.
|
||||||
|
-- * @{#FORMATION.FormationLeftWing}(): Form a left wing formation.
|
||||||
|
-- * @{#FORMATION.FormationCenterWing}(): Form a center wing formation.
|
||||||
|
-- * @{#FORMATION.FormationCenterVic}(): Form a Vic formation (same as CenterWing).
|
||||||
|
-- * @{#FORMATION.FormationCenterBoxed}(): Form a center boxed formation.
|
||||||
|
--
|
||||||
|
-- ## Randomization
|
||||||
|
--
|
||||||
|
-- Use the method @{FORMATION#FORMATION.SetFlightRandomization}() to simulate the formation flying errors that pilots make while in formation. Is a range set in meters.
|
||||||
|
--
|
||||||
|
-- @usage
|
||||||
|
-- local FollowGroupSet = SET_GROUP:New():FilterCategories("plane"):FilterCoalitions("blue"):FilterPrefixes("Follow"):FilterStart()
|
||||||
|
-- local LeaderUnit = UNIT:FindByName( "Leader" )
|
||||||
|
-- local LargeFormation = FORMATION:New( LeaderUnit, FollowGroupSet, "Center Wing Formation", "Briefing" )
|
||||||
|
-- LargeFormation:FormationCenterWing( 500, 50, 0, 250, 250 )
|
||||||
|
-- LargeFormation:__Start( 1 )
|
||||||
|
--
|
||||||
|
-- @field #FORMATION
|
||||||
|
FORMATION = {
|
||||||
|
ClassName = "FORMATION",
|
||||||
|
FollowName = nil, -- The Follow Name
|
||||||
|
FollowUnit = nil,
|
||||||
|
FollowGroupSet = nil,
|
||||||
|
FollowScheduler = nil,
|
||||||
|
OptionROE = AI.Option.Air.val.ROE.OPEN_FIRE,
|
||||||
|
OptionReactionOnThreat = AI.Option.Air.val.REACTION_ON_THREAT.ALLOW_ABORT_MISSION,
|
||||||
|
dtFollow = 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- @type FORMATION.Formation
|
||||||
|
-- @field #number None
|
||||||
|
-- @field #number Line
|
||||||
|
-- @field #number Trail
|
||||||
|
-- @field #number Stack
|
||||||
|
-- @field #number LeftLine
|
||||||
|
-- @field #number RightLine
|
||||||
|
-- @field #number LeftWing
|
||||||
|
-- @field #number RightWing
|
||||||
|
-- @field #number Vic
|
||||||
|
-- @field #number Box
|
||||||
|
FORMATION.Formation = {
|
||||||
|
None = 1,
|
||||||
|
Line = 2,
|
||||||
|
Trail = 3,
|
||||||
|
Stack = 4,
|
||||||
|
LeftLine = 5,
|
||||||
|
RightLine = 6,
|
||||||
|
LeftWing = 7,
|
||||||
|
RightWing = 8,
|
||||||
|
Vic = 9,
|
||||||
|
Box = 10,
|
||||||
|
}
|
||||||
|
|
||||||
|
--- FORMATION class constructor for an AI group
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Wrapper.Unit#UNIT FollowUnit The UNIT leading the FolllowGroupSet.
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string FollowName Name of the escort.
|
||||||
|
-- @return #FORMATION self
|
||||||
|
function FORMATION:New( FollowUnit, FollowGroupSet, FollowName )
|
||||||
|
local self = BASE:Inherit( self, FSM_SET:New( FollowGroupSet ) )
|
||||||
|
self:F( { FollowUnit, FollowGroupSet, FollowName } )
|
||||||
|
|
||||||
|
self.FollowUnit = FollowUnit -- Wrapper.Unit#UNIT
|
||||||
|
self.FollowGroupSet = FollowGroupSet -- Core.Set#SET_GROUP
|
||||||
|
|
||||||
|
self:SetFlightRandomization( 2 )
|
||||||
|
|
||||||
|
self:SetStartState( "None" )
|
||||||
|
|
||||||
|
self:AddTransition( "*", "Stop", "Stopped" )
|
||||||
|
|
||||||
|
self:AddTransition( {"None", "Stopped"}, "Start", "Following" )
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationLine", "*" )
|
||||||
|
|
||||||
|
--- Start Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] Start
|
||||||
|
-- @param #FORMATION self
|
||||||
|
|
||||||
|
--- Start Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __Start
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
--- Stop Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] Stop
|
||||||
|
-- @param #FORMATION self
|
||||||
|
|
||||||
|
--- Stop Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __Stop
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
|
||||||
|
--- FormationLine Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationLine Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationLine Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationTrail", "*" )
|
||||||
|
|
||||||
|
--- FormationTrail Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationTrail
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
|
||||||
|
--- FormationTrail Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationTrail
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
|
||||||
|
--- FormationTrail Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationTrail
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationStack", "*" )
|
||||||
|
|
||||||
|
--- FormationStack Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationStack
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationStack Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationStack
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationStack Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationStack
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationLeftLine", "*" )
|
||||||
|
|
||||||
|
--- FormationLeftLine Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationLeftLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationLeftLine Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationLeftLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationLeftLine Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationLeftLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationRightLine", "*" )
|
||||||
|
|
||||||
|
--- FormationRightLine Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationRightLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationRightLine Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationRightLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationRightLine Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationRightLine
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationLeftWing", "*" )
|
||||||
|
|
||||||
|
--- FormationLeftWing Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationLeftWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationLeftWing Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationLeftWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationLeftWing Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationLeftWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationRightWing", "*" )
|
||||||
|
|
||||||
|
--- FormationRightWing Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationRightWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationRightWing Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationRightWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationRightWing Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationRightWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationCenterWing", "*" )
|
||||||
|
|
||||||
|
--- FormationCenterWing Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationCenterWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationCenterWing Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationCenterWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationCenterWing Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationCenterWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationVic", "*" )
|
||||||
|
|
||||||
|
--- FormationVic Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationVic
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationVic Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationVic
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
--- FormationVic Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationVic
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "FormationBox", "*" )
|
||||||
|
|
||||||
|
--- FormationBox Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationBox
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
|
|
||||||
|
--- FormationBox Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] FormationBox
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
|
|
||||||
|
--- FormationBox Asynchronous Trigger for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] __FormationBox
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number Delay
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
|
|
||||||
|
self:AddTransition( "*", "Follow", "Following" )
|
||||||
|
|
||||||
|
self:FormationLeftLine( 500, 0, 250, 250 )
|
||||||
|
|
||||||
|
self.FollowName = FollowName
|
||||||
|
|
||||||
|
self.CT1 = 0
|
||||||
|
self.GT1 = 0
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- Set time interval between updates of the formation.
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number dt Time step in seconds between formation updates. Default is every 0.5 seconds.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:SetFollowTimeInterval(dt)
|
||||||
|
self.dtFollow=dt or 0.5
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- This function is for test, it will put on the frequency of the FollowScheduler a red smoke at the direction vector calculated for the escort to fly to.
|
||||||
|
-- This allows to visualize where the escort is flying to.
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #boolean SmokeDirection If true, then the direction vector will be smoked.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:TestSmokeDirectionVector( SmokeDirection )
|
||||||
|
self.SmokeDirectionVector = ( SmokeDirection == true ) and true or false
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationLine Handler OnAfter for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:onafterFormationLine( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, Formation )
|
||||||
|
self:F( { FollowGroupSet, From , Event ,To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, Formation } )
|
||||||
|
|
||||||
|
XStart = XStart or self.XStart
|
||||||
|
XSpace = XSpace or self.XSpace
|
||||||
|
YStart = YStart or self.YStart
|
||||||
|
YSpace = YSpace or self.YSpace
|
||||||
|
ZStart = ZStart or self.ZStart
|
||||||
|
ZSpace = ZSpace or self.ZSpace
|
||||||
|
|
||||||
|
local FollowSet = FollowGroupSet:GetSet()
|
||||||
|
|
||||||
|
local i = 1 --FF i=0 caused first unit to have no XSpace! Probably needs further adjustments. This is just a quick work around.
|
||||||
|
|
||||||
|
for FollowID, FollowGroup in pairs( FollowSet ) do
|
||||||
|
|
||||||
|
local PointVec3 = COORDINATE:New()
|
||||||
|
PointVec3:SetX( XStart + i * XSpace )
|
||||||
|
PointVec3:SetY( YStart + i * YSpace )
|
||||||
|
PointVec3:SetZ( ZStart + i * ZSpace )
|
||||||
|
|
||||||
|
local Vec3 = PointVec3:GetVec3()
|
||||||
|
FollowGroup:SetState( self, "FormationVec3", Vec3 )
|
||||||
|
i = i + 1
|
||||||
|
|
||||||
|
FollowGroup:SetState( FollowGroup, "Formation", Formation )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationTrail Handler OnAfter for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:onafterFormationTrail( FollowGroupSet, From , Event , To, XStart, XSpace, YStart )
|
||||||
|
|
||||||
|
self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,0,0,0, self.Formation.Trail )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- FormationStack Handler OnAfter for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:onafterFormationStack( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace )
|
||||||
|
|
||||||
|
self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,YSpace,0,0, self.Formation.Stack )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationLeftLine Handler OnAfter for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:onafterFormationLeftLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace )
|
||||||
|
|
||||||
|
self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,0,YStart,0,-ZStart,-ZSpace, self.Formation.LeftLine )
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationRightLine Handler OnAfter for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:onafterFormationRightLine( FollowGroupSet, From , Event , To, XStart, YStart, ZStart, ZSpace )
|
||||||
|
|
||||||
|
self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,0,YStart,0,ZStart,ZSpace,self.Formation.RightLine)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationLeftWing Handler OnAfter for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
function FORMATION:onafterFormationLeftWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace )
|
||||||
|
|
||||||
|
self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,0,-ZStart,-ZSpace,self.Formation.LeftWing)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationRightWing Handler OnAfter for FORMATION
|
||||||
|
-- @function [parent=#FORMATION] OnAfterFormationRightWing
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
function FORMATION:onafterFormationRightWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, ZStart, ZSpace )
|
||||||
|
|
||||||
|
self:onafterFormationLine(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,0,ZStart,ZSpace,self.Formation.RightWing)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationCenterWing Handler OnAfter for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The group AI escorting the FollowUnit.
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
function FORMATION:onafterFormationCenterWing( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace )
|
||||||
|
|
||||||
|
local FollowSet = FollowGroupSet:GetSet()
|
||||||
|
|
||||||
|
local i = 0
|
||||||
|
|
||||||
|
for FollowID, FollowGroup in pairs( FollowSet ) do
|
||||||
|
|
||||||
|
local PointVec3 = COORDINATE:New()
|
||||||
|
|
||||||
|
local Side = ( i % 2 == 0 ) and 1 or -1
|
||||||
|
local Row = i / 2 + 1
|
||||||
|
|
||||||
|
PointVec3:SetX( XStart + Row * XSpace )
|
||||||
|
PointVec3:SetY( YStart )
|
||||||
|
PointVec3:SetZ( Side * ( ZStart + i * ZSpace ) )
|
||||||
|
|
||||||
|
local Vec3 = PointVec3:GetVec3()
|
||||||
|
FollowGroup:SetState( self, "FormationVec3", Vec3 )
|
||||||
|
i = i + 1
|
||||||
|
FollowGroup:SetState( FollowGroup, "Formation", self.Formation.Vic )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationVic Handle for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:onafterFormationVic( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace )
|
||||||
|
|
||||||
|
self:onafterFormationCenterWing(FollowGroupSet,From,Event,To,XStart,XSpace,YStart,YSpace,ZStart,ZSpace)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- FormationBox Handler OnAfter for FORMATION
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #string From
|
||||||
|
-- @param #string Event
|
||||||
|
-- @param #string To
|
||||||
|
-- @param #number XStart The start position on the X-axis in meters for the first group.
|
||||||
|
-- @param #number XSpace The space between groups on the X-axis in meters for each sequent group.
|
||||||
|
-- @param #number YStart The start position on the Y-axis in meters for the first group.
|
||||||
|
-- @param #number YSpace The space between groups on the Y-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZStart The start position on the Z-axis in meters for the first group.
|
||||||
|
-- @param #number ZSpace The space between groups on the Z-axis in meters for each sequent group.
|
||||||
|
-- @param #number ZLevels The amount of levels on the Z-axis.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:onafterFormationBox( FollowGroupSet, From , Event , To, XStart, XSpace, YStart, YSpace, ZStart, ZSpace, ZLevels )
|
||||||
|
|
||||||
|
local FollowSet = FollowGroupSet:GetSet()
|
||||||
|
|
||||||
|
local i = 0
|
||||||
|
|
||||||
|
for FollowID, FollowGroup in pairs( FollowSet ) do
|
||||||
|
|
||||||
|
local PointVec3 = COORDINATE:New()
|
||||||
|
|
||||||
|
local ZIndex = i % ZLevels
|
||||||
|
local XIndex = math.floor( i / ZLevels )
|
||||||
|
local YIndex = math.floor( i / ZLevels )
|
||||||
|
|
||||||
|
PointVec3:SetX( XStart + XIndex * XSpace )
|
||||||
|
PointVec3:SetY( YStart + YIndex * YSpace )
|
||||||
|
PointVec3:SetZ( -ZStart - (ZSpace * ZLevels / 2 ) + ZSpace * ZIndex )
|
||||||
|
|
||||||
|
local Vec3 = PointVec3:GetVec3()
|
||||||
|
FollowGroup:SetState( self, "FormationVec3", Vec3 )
|
||||||
|
i = i + 1
|
||||||
|
FollowGroup:SetState( FollowGroup, "Formation", self.Formation.Box )
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Use the method @{FORMATION#FORMATION.SetFlightRandomization}() to make the air units in your formation randomize their flight a bit while in formation.
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param #number FlightRandomization The formation flying errors that pilots can make while in formation. Is a range set in meters.
|
||||||
|
-- @return #FORMATION
|
||||||
|
function FORMATION:SetFlightRandomization( FlightRandomization )
|
||||||
|
self.FlightRandomization = FlightRandomization
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Stop function. Formation will not be updated any more.
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To The to state.
|
||||||
|
function FORMATION:onafterStop(FollowGroupSet, From, Event, To)
|
||||||
|
self:E("Stopping formation.")
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Follow event fuction. Check if coming from state "stopped". If so the transition is rejected.
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To The to state.
|
||||||
|
function FORMATION:onbeforeFollow( FollowGroupSet, From, Event, To )
|
||||||
|
if From=="Stopped" then
|
||||||
|
return false -- Deny transition.
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Enter following state.
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Core.Set#SET_GROUP FollowGroupSet The following set of groups.
|
||||||
|
-- @param #string From From state.
|
||||||
|
-- @param #string Event Event.
|
||||||
|
-- @param #string To The to state.
|
||||||
|
function FORMATION:onenterFollowing( FollowGroupSet )
|
||||||
|
|
||||||
|
if self.FollowUnit:IsAlive() then
|
||||||
|
|
||||||
|
local ClientUnit = self.FollowUnit
|
||||||
|
|
||||||
|
local CT1, CT2, CV1, CV2
|
||||||
|
CT1 = ClientUnit:GetState( self, "CT1" )
|
||||||
|
|
||||||
|
local CuVec3=ClientUnit:GetVec3()
|
||||||
|
|
||||||
|
if CT1 == nil or CT1 == 0 then
|
||||||
|
ClientUnit:SetState( self, "CV1", CuVec3)
|
||||||
|
ClientUnit:SetState( self, "CT1", timer.getTime() )
|
||||||
|
else
|
||||||
|
CT1 = ClientUnit:GetState( self, "CT1" )
|
||||||
|
CT2 = timer.getTime()
|
||||||
|
CV1 = ClientUnit:GetState( self, "CV1" )
|
||||||
|
CV2 = CuVec3
|
||||||
|
|
||||||
|
ClientUnit:SetState( self, "CT1", CT2 )
|
||||||
|
ClientUnit:SetState( self, "CV1", CV2 )
|
||||||
|
end
|
||||||
|
|
||||||
|
--FollowGroupSet:ForEachGroupAlive( bla, self, ClientUnit, CT1, CV1, CT2, CV2)
|
||||||
|
|
||||||
|
for _,_group in pairs(FollowGroupSet:GetSet()) do
|
||||||
|
local group=_group --Wrapper.Group#GROUP
|
||||||
|
if group and group:IsAlive() then
|
||||||
|
self:FollowMe(group, ClientUnit, CT1, CV1, CT2, CV2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self:__Follow( -self.dtFollow )
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Follow me.
|
||||||
|
-- @param #FORMATION self
|
||||||
|
-- @param Wrapper.Group#GROUP FollowGroup Follow group.
|
||||||
|
-- @param Wrapper.Unit#UNIT ClientUnit Client Unit.
|
||||||
|
-- @param DCS#Time CT1 Time
|
||||||
|
-- @param DCS#Vec3 CV1 Vec3
|
||||||
|
-- @param DCS#Time CT2 Time
|
||||||
|
-- @param DCS#Vec3 CV2 Vec3
|
||||||
|
function FORMATION:FollowMe(FollowGroup, ClientUnit, CT1, CV1, CT2, CV2)
|
||||||
|
|
||||||
|
if not self:Is("Stopped") then
|
||||||
|
|
||||||
|
self:T({Mode=FollowGroup:GetState( FollowGroup, "Mode" )})
|
||||||
|
|
||||||
|
FollowGroup:OptionROTEvadeFire()
|
||||||
|
FollowGroup:OptionROEReturnFire()
|
||||||
|
|
||||||
|
local GroupUnit = FollowGroup:GetUnit( 1 )
|
||||||
|
|
||||||
|
local GuVec3=GroupUnit:GetVec3()
|
||||||
|
|
||||||
|
local FollowFormation = FollowGroup:GetState( self, "FormationVec3" )
|
||||||
|
|
||||||
|
if FollowFormation then
|
||||||
|
local FollowDistance = FollowFormation.x
|
||||||
|
|
||||||
|
local GT1 = GroupUnit:GetState( self, "GT1" )
|
||||||
|
|
||||||
|
if CT1 == nil or CT1 == 0 or GT1 == nil or GT1 == 0 then
|
||||||
|
GroupUnit:SetState( self, "GV1", GuVec3)
|
||||||
|
GroupUnit:SetState( self, "GT1", timer.getTime() )
|
||||||
|
else
|
||||||
|
local CD = ( ( CV2.x - CV1.x )^2 + ( CV2.y - CV1.y )^2 + ( CV2.z - CV1.z )^2 ) ^ 0.5
|
||||||
|
local CT = CT2 - CT1
|
||||||
|
|
||||||
|
local CS = ( 3600 / CT ) * ( CD / 1000 ) / 3.6
|
||||||
|
|
||||||
|
local CDv = { x = CV2.x - CV1.x, y = CV2.y - CV1.y, z = CV2.z - CV1.z }
|
||||||
|
local Ca = math.atan2( CDv.x, CDv.z )
|
||||||
|
|
||||||
|
local GT1 = GroupUnit:GetState( self, "GT1" )
|
||||||
|
local GT2 = timer.getTime()
|
||||||
|
|
||||||
|
local GV1 = GroupUnit:GetState( self, "GV1" )
|
||||||
|
local GV2 = GuVec3
|
||||||
|
|
||||||
|
GV2.x=GV2.x+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 )
|
||||||
|
GV2.y=GV2.y+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 )
|
||||||
|
GV2.z=GV2.z+math.random( -self.FlightRandomization / 2, self.FlightRandomization / 2 )
|
||||||
|
|
||||||
|
GroupUnit:SetState( self, "GT1", GT2 )
|
||||||
|
GroupUnit:SetState( self, "GV1", GV2 )
|
||||||
|
|
||||||
|
local GD = ( ( GV2.x - GV1.x )^2 + ( GV2.y - GV1.y )^2 + ( GV2.z - GV1.z )^2 ) ^ 0.5
|
||||||
|
local GT = GT2 - GT1
|
||||||
|
|
||||||
|
-- Calculate the distance
|
||||||
|
local GDv = { x = GV2.x - CV1.x, y = GV2.y - CV1.y, z = GV2.z - CV1.z }
|
||||||
|
local Alpha_T = math.atan2( GDv.x, GDv.z ) - math.atan2( CDv.x, CDv.z )
|
||||||
|
local Alpha_R = ( Alpha_T < 0 ) and Alpha_T + 2 * math.pi or Alpha_T
|
||||||
|
local Position = math.cos( Alpha_R )
|
||||||
|
local GD = ( ( GDv.x )^2 + ( GDv.z )^2 ) ^ 0.5
|
||||||
|
local Distance = GD * Position + - CS * 0.5
|
||||||
|
|
||||||
|
-- Calculate the group direction vector
|
||||||
|
local GV = { x = GV2.x - CV2.x, y = GV2.y - CV2.y, z = GV2.z - CV2.z }
|
||||||
|
|
||||||
|
-- Calculate GH2, GH2 with the same height as CV2.
|
||||||
|
local GH2 = { x = GV2.x, y = CV2.y + FollowFormation.y, z = GV2.z }
|
||||||
|
|
||||||
|
-- Calculate the angle of GV to the orthonormal plane
|
||||||
|
local alpha = math.atan2( GV.x, GV.z )
|
||||||
|
|
||||||
|
local GVx = FollowFormation.z * math.cos( Ca ) + FollowFormation.x * math.sin( Ca )
|
||||||
|
local GVz = FollowFormation.x * math.cos( Ca ) - FollowFormation.z * math.sin( Ca )
|
||||||
|
|
||||||
|
-- Now we calculate the intersecting vector between the circle around CV2 with radius FollowDistance and GH2.
|
||||||
|
-- From the GeoGebra model: CVI = (x(CV2) + FollowDistance cos(alpha), y(GH2) + FollowDistance sin(alpha), z(CV2))
|
||||||
|
local Inclination = ( Distance + FollowFormation.x ) / 10
|
||||||
|
if Inclination < -30 then
|
||||||
|
Inclination = - 30
|
||||||
|
end
|
||||||
|
|
||||||
|
local CVI = {
|
||||||
|
x = CV2.x + CS * 10 * math.sin(Ca),
|
||||||
|
y = GH2.y + Inclination, -- + FollowFormation.y,
|
||||||
|
z = CV2.z + CS * 10 * math.cos(Ca),
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Calculate the direction vector DV of the escort group. We use CVI as the base and CV2 as the direction.
|
||||||
|
local DV = { x = CV2.x - CVI.x, y = CV2.y - CVI.y, z = CV2.z - CVI.z }
|
||||||
|
|
||||||
|
-- We now calculate the unary direction vector DVu, so that we can multiply DVu with the speed, which is expressed in meters / s.
|
||||||
|
-- We need to calculate this vector to predict the point the escort group needs to fly to according its speed.
|
||||||
|
-- The distance of the destination point should be far enough not to have the aircraft starting to swipe left to right...
|
||||||
|
local DVu = { x = DV.x / FollowDistance, y = DV.y, z = DV.z / FollowDistance }
|
||||||
|
|
||||||
|
-- Now we can calculate the group destination vector GDV.
|
||||||
|
local GDV = { x = CVI.x, y = CVI.y, z = CVI.z }
|
||||||
|
|
||||||
|
local ADDx = FollowFormation.x * math.cos(alpha) - FollowFormation.z * math.sin(alpha)
|
||||||
|
local ADDz = FollowFormation.z * math.cos(alpha) + FollowFormation.x * math.sin(alpha)
|
||||||
|
|
||||||
|
local GDV_Formation = {
|
||||||
|
x = GDV.x - GVx,
|
||||||
|
y = GDV.y,
|
||||||
|
z = GDV.z - GVz
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Debug smoke.
|
||||||
|
if self.SmokeDirectionVector == true then
|
||||||
|
trigger.action.smoke( GDV, trigger.smokeColor.Green )
|
||||||
|
trigger.action.smoke( GDV_Formation, trigger.smokeColor.White )
|
||||||
|
end
|
||||||
|
|
||||||
|
local Time = 120
|
||||||
|
|
||||||
|
local Speed = - ( Distance + FollowFormation.x ) / Time
|
||||||
|
|
||||||
|
if Distance > -10000 then
|
||||||
|
Speed = - ( Distance + FollowFormation.x ) / 60
|
||||||
|
end
|
||||||
|
|
||||||
|
if Distance > -2500 then
|
||||||
|
Speed = - ( Distance + FollowFormation.x ) / 20
|
||||||
|
end
|
||||||
|
|
||||||
|
local GS = Speed + CS
|
||||||
|
|
||||||
|
--self:F( { Distance = Distance, Speed = Speed, CS = CS, GS = GS } )
|
||||||
|
|
||||||
|
-- Now route the escort to the desired point with the desired speed.
|
||||||
|
FollowGroup:RouteToVec3( GDV_Formation, GS ) -- DCS models speed in Mps (Miles per second)
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -90,7 +90,8 @@
|
|||||||
-- @image Scoring.JPG
|
-- @image Scoring.JPG
|
||||||
|
|
||||||
--- @type SCORING
|
--- @type SCORING
|
||||||
-- @field Players A collection of the current players that have joined the game.
|
-- @field #table Players A collection of the current players that have joined the game.
|
||||||
|
-- @field Core.Set#SET_SCENERY ScoringScenery
|
||||||
-- @extends Core.Base#BASE
|
-- @extends Core.Base#BASE
|
||||||
|
|
||||||
--- SCORING class
|
--- SCORING class
|
||||||
@@ -229,7 +230,8 @@ SCORING = {
|
|||||||
ClassID = 0,
|
ClassID = 0,
|
||||||
Players = {},
|
Players = {},
|
||||||
AutoSave = true,
|
AutoSave = true,
|
||||||
version = "1.18.4"
|
version = "1.18.4",
|
||||||
|
ScoringScenery = nil, -- Core.Set#SET_SCENERY
|
||||||
}
|
}
|
||||||
|
|
||||||
local _SCORINGCoalition = {
|
local _SCORINGCoalition = {
|
||||||
@@ -325,6 +327,8 @@ function SCORING:New( GameName, SavePath, AutoSave )
|
|||||||
self:OpenCSV( GameName )
|
self:OpenCSV( GameName )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self:I("SCORING "..tostring(GameName).." started! v"..self.version)
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
end
|
end
|
||||||
@@ -377,7 +381,7 @@ function SCORING:AddUnitScore( ScoreUnit, Score )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Removes a @{Wrapper.Unit} for additional scoring when the @{Wrapper.Unit} is destroyed.
|
--- Removes a @{Wrapper.Unit} for scoring when the @{Wrapper.Unit} is destroyed.
|
||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
-- @param Wrapper.Unit#UNIT ScoreUnit The @{Wrapper.Unit} for which the Score needs to be given.
|
-- @param Wrapper.Unit#UNIT ScoreUnit The @{Wrapper.Unit} for which the Score needs to be given.
|
||||||
-- @return #SCORING
|
-- @return #SCORING
|
||||||
@@ -394,10 +398,26 @@ end
|
|||||||
-- Note that if there was already a @{Wrapper.Static} declared within the scoring with the same name,
|
-- Note that if there was already a @{Wrapper.Static} declared within the scoring with the same name,
|
||||||
-- then the old @{Wrapper.Static} will be replaced with the new @{Wrapper.Static}.
|
-- then the old @{Wrapper.Static} will be replaced with the new @{Wrapper.Static}.
|
||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
-- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
|
-- @param Wrapper.Static#STATIC ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
|
||||||
-- @param #number Score The Score value.
|
-- @param #number Score The Score value.
|
||||||
-- @return #SCORING
|
-- @return #SCORING
|
||||||
function SCORING:AddStaticScore( ScoreStatic, Score )
|
function SCORING:AddStaticScore( ScoreStatic, Score )
|
||||||
|
return self:AddScoreStatic( ScoreStatic, Score )
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Add a @{Wrapper.Static} for additional scoring when the @{Wrapper.Static} is destroyed.
|
||||||
|
-- Note that if there was already a @{Wrapper.Static} declared within the scoring with the same name,
|
||||||
|
-- then the old @{Wrapper.Static} will be replaced with the new @{Wrapper.Static}.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Wrapper.Static#STATIC ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
|
||||||
|
-- @param #number Score The Score value.
|
||||||
|
-- @return #SCORING
|
||||||
|
function SCORING:AddScoreStatic( ScoreStatic, Score )
|
||||||
|
|
||||||
|
if ScoreStatic == nil then
|
||||||
|
BASE:E("SCORING.AddStaticScore: Parameter ScoreStatic is nil!")
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
local StaticName = ScoreStatic:GetName()
|
local StaticName = ScoreStatic:GetName()
|
||||||
|
|
||||||
@@ -406,7 +426,61 @@ function SCORING:AddStaticScore( ScoreStatic, Score )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Removes a @{Wrapper.Static} for additional scoring when the @{Wrapper.Static} is destroyed.
|
--- Add a @{Wrapper.Scenery} for additional scoring when the @{Wrapper.Scenery} is destroyed.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Wrapper.Scenery#SCENERY ScoreScenery The @{Wrapper.Scenery} for which the Score needs to be given.
|
||||||
|
-- @param #number Score The Score value.
|
||||||
|
-- @return #SCORING
|
||||||
|
function SCORING:AddScoreScenery( ScoreScenery, Score )
|
||||||
|
|
||||||
|
if ScoreScenery == nil then
|
||||||
|
self:E("SCORING.ScoreScenery: Parameter ScoreScenery is nil!")
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
if not self.ScoringScenery then
|
||||||
|
self.ScoringScenery = SET_SCENERY:New() -- Core.Set#SET_SCENERY
|
||||||
|
end
|
||||||
|
|
||||||
|
local StaticName = ScoreScenery:GetName()
|
||||||
|
self:T("Scenery name = ".. StaticName)
|
||||||
|
|
||||||
|
self.ScoringScenery:AddScenery(ScoreScenery)
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Removes a @{Wrapper.Scenery} for scoring when the @{Wrapper.Scenery} is destroyed.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Wrapper.Scenery#SCENERY ScoreStatic The @{Wrapper.Scenery} for which the Score needs to be given.
|
||||||
|
-- @return #SCORING
|
||||||
|
function SCORING:RemoveSceneryScore( ScoreScenery )
|
||||||
|
|
||||||
|
local StaticName = ScoreScenery:GetName()
|
||||||
|
|
||||||
|
self.ScoringObjects[StaticName] = nil
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Specify a special additional score for a @{Core.Set#SET_SCENERY}.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Core.Set#SET_SCENERY Set The @{Core.Set#SET_SCENERY} for which each @{Wrapper.Scenery} in the SET a Score is given.
|
||||||
|
-- @param #number Score The Score value.
|
||||||
|
-- @return #SCORING
|
||||||
|
function SCORING:AddScoreSetScenery(Set, Score)
|
||||||
|
local set = Set.Set
|
||||||
|
|
||||||
|
for _,_static in pairs (set) do
|
||||||
|
if _static ~= nil then
|
||||||
|
self:AddScoreScenery(_static,Score)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Removes a @{Wrapper.Static} for scoring when the @{Wrapper.Static} is destroyed.
|
||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
-- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
|
-- @param Wrapper.Static#UNIT ScoreStatic The @{Wrapper.Static} for which the Score needs to be given.
|
||||||
-- @return #SCORING
|
-- @return #SCORING
|
||||||
@@ -461,6 +535,31 @@ function SCORING:AddScoreSetGroup(Set, Score)
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Specify a special additional score for a @{Core.Set#SET_STATIC}.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Core.Set#SET_STATIC Set The @{Core.Set#SET_STATIC} for which each @{Wrapper.Static} in the SET a Score is given.
|
||||||
|
-- @param #number Score The Score value.
|
||||||
|
-- @return #SCORING
|
||||||
|
function SCORING:AddScoreSetStatic(Set, Score)
|
||||||
|
local set = Set:GetSetObjects()
|
||||||
|
|
||||||
|
for _,_static in pairs (set) do
|
||||||
|
if _static and _static:IsAlive() then
|
||||||
|
self:AddStaticScore(_static,Score)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function AddScore(static)
|
||||||
|
self:AddStaticScore(static,Score)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Set:OnAfterAdded(From,Event,To,ObjectName,Object)
|
||||||
|
AddScore(Object)
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
--- Add a @{Core.Zone} to define additional scoring when any object is destroyed in that zone.
|
--- Add a @{Core.Zone} to define additional scoring when any object is destroyed in that zone.
|
||||||
-- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced!
|
-- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced!
|
||||||
-- This allows for a dynamic destruction zone evolution within your mission.
|
-- This allows for a dynamic destruction zone evolution within your mission.
|
||||||
@@ -480,7 +579,24 @@ function SCORING:AddZoneScore( ScoreZone, Score )
|
|||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Remove a @{Core.Zone} for additional scoring.
|
--- Add a @{Core.Set#SET_ZONE} to define additional scoring when any object is destroyed in that zone.
|
||||||
|
-- Note that if a @{Core.Zone} with the same name is already within the scoring added, the @{Core.Zone} (type) and Score will be replaced!
|
||||||
|
-- This allows for a dynamic destruction zone evolution within your mission.
|
||||||
|
-- @param #SCORING self
|
||||||
|
-- @param Core.Set#SET_ZONE ScoreZoneSet The @{Core.Set#SET_ZONE} which defines the destruction score perimeters.
|
||||||
|
-- Note that a zone can be a polygon or a moving zone.
|
||||||
|
-- @param #number Score The Score value.
|
||||||
|
-- @return #SCORING
|
||||||
|
function SCORING:AddZoneScoreSet( ScoreZoneSet, Score )
|
||||||
|
|
||||||
|
for _,_zone in pairs(ScoreZoneSet.Set or {}) do
|
||||||
|
self:AddZoneScore(_zone,Score)
|
||||||
|
end
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Remove a @{Core.Zone} for scoring.
|
||||||
-- The scoring will search if any @{Core.Zone} is added with the given name, and will remove that zone from the scoring.
|
-- The scoring will search if any @{Core.Zone} is added with the given name, and will remove that zone from the scoring.
|
||||||
-- This allows for a dynamic destruction zone evolution within your mission.
|
-- This allows for a dynamic destruction zone evolution within your mission.
|
||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
@@ -958,7 +1074,7 @@ end
|
|||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
-- @param Core.Event#EVENTDATA Event
|
-- @param Core.Event#EVENTDATA Event
|
||||||
function SCORING:_EventOnHit( Event )
|
function SCORING:_EventOnHit( Event )
|
||||||
self:F( { Event } )
|
--self:F( { Event } )
|
||||||
|
|
||||||
local InitUnit = nil
|
local InitUnit = nil
|
||||||
local InitUNIT = nil
|
local InitUNIT = nil
|
||||||
@@ -988,6 +1104,7 @@ function SCORING:_EventOnHit( Event )
|
|||||||
local TargetUnitCategory = nil
|
local TargetUnitCategory = nil
|
||||||
local TargetUnitType = nil
|
local TargetUnitType = nil
|
||||||
local TargetIsScenery = false
|
local TargetIsScenery = false
|
||||||
|
local TargetSceneryObject = nil
|
||||||
|
|
||||||
if Event.IniDCSUnit then
|
if Event.IniDCSUnit then
|
||||||
|
|
||||||
@@ -1009,7 +1126,7 @@ function SCORING:_EventOnHit( Event )
|
|||||||
InitUnitCategory = _SCORINGCategory[InitCategory]
|
InitUnitCategory = _SCORINGCategory[InitCategory]
|
||||||
InitUnitType = InitType
|
InitUnitType = InitType
|
||||||
|
|
||||||
self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType, InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
--self:T( { InitUnitName, InitGroupName, InitPlayerName, InitCoalition, InitCategory, InitType, InitUnitCoalition, InitUnitCategory, InitUnitType } )
|
||||||
end
|
end
|
||||||
|
|
||||||
if Event.TgtDCSUnit then
|
if Event.TgtDCSUnit then
|
||||||
@@ -1028,17 +1145,22 @@ function SCORING:_EventOnHit( Event )
|
|||||||
TargetCategory = Event.TgtCategory
|
TargetCategory = Event.TgtCategory
|
||||||
TargetType = Event.TgtTypeName
|
TargetType = Event.TgtTypeName
|
||||||
|
|
||||||
|
|
||||||
-- Scenery hit
|
-- Scenery hit
|
||||||
if (not TargetCategory) and TargetUNIT ~= nil and TargetUnit:IsInstanceOf("SCENERY") then
|
if TargetUNIT ~= nil and TargetUNIT:IsInstanceOf("SCENERY") then
|
||||||
TargetCategory = Unit.Category.STRUCTURE
|
TargetCategory = Unit.Category.STRUCTURE
|
||||||
TargetIsScenery = true
|
TargetIsScenery = true
|
||||||
|
TargetType = "Scenery"
|
||||||
|
TargetSceneryObject = TargetUNIT
|
||||||
|
self:T("***** Target is Scenery and TargetUNIT is SCENERY object!")
|
||||||
|
UTILS.PrintTableToLog(TargetSceneryObject)
|
||||||
end
|
end
|
||||||
|
|
||||||
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
|
||||||
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
TargetUnitCategory = _SCORINGCategory[TargetCategory]
|
||||||
TargetUnitType = TargetType
|
TargetUnitType = TargetType
|
||||||
|
|
||||||
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType, TargetUnitCoalition, TargetUnitCategory, TargetUnitType } )
|
--self:T( { TargetUnitName=TargetUnitName, TargetGroupName=TargetGroupName, TargetPlayerName=TargetPlayerName, TargetCoalition=TargetCoalition, TargetCategory=TargetCategory, TargetType=TargetType, TargetUnitCoalition=TargetUnitCoalition, TargetUnitCategory=TargetUnitCategory, TargetUnitType=TargetUnitType } )
|
||||||
end
|
end
|
||||||
|
|
||||||
if InitPlayerName ~= nil then -- It is a player that is hitting something
|
if InitPlayerName ~= nil then -- It is a player that is hitting something
|
||||||
@@ -1051,7 +1173,7 @@ function SCORING:_EventOnHit( Event )
|
|||||||
self:T( "Hitting Something" )
|
self:T( "Hitting Something" )
|
||||||
|
|
||||||
-- What is he hitting?
|
-- What is he hitting?
|
||||||
if TargetCategory then
|
if (TargetCategory ~=nil) and (TargetIsScenery == false) then
|
||||||
|
|
||||||
-- A target got hit, score it.
|
-- A target got hit, score it.
|
||||||
-- Player contains the score data from self.Players[InitPlayerName]
|
-- Player contains the score data from self.Players[InitPlayerName]
|
||||||
@@ -1071,7 +1193,7 @@ function SCORING:_EventOnHit( Event )
|
|||||||
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
|
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
|
||||||
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
|
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
|
||||||
-- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth
|
-- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth
|
||||||
if PlayerHit.UNIT.ThreatType == nil then
|
if PlayerHit.UNIT and PlayerHit.UNIT.ThreatType == nil then
|
||||||
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
|
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
|
||||||
-- if this fails for some reason, set a good default value
|
-- if this fails for some reason, set a good default value
|
||||||
if PlayerHit.ThreatType == nil or PlayerHit.ThreatType == "" then
|
if PlayerHit.ThreatType == nil or PlayerHit.ThreatType == "" then
|
||||||
@@ -1157,21 +1279,21 @@ function SCORING:_EventOnHit( Event )
|
|||||||
|
|
||||||
-- It is a weapon initiated by a player, that is hitting something
|
-- It is a weapon initiated by a player, that is hitting something
|
||||||
-- This seems to occur only with scenery and static objects.
|
-- This seems to occur only with scenery and static objects.
|
||||||
if Event.WeaponPlayerName ~= nil then
|
if Event.WeaponPlayerName ~= nil or TargetIsScenery == true then
|
||||||
self:_AddPlayerFromUnit( Event.WeaponUNIT )
|
|
||||||
if self.Players[Event.WeaponPlayerName] then -- This should normally not happen, but i'll test it anyway.
|
|
||||||
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
|
|
||||||
self:_AddPlayerFromUnit( TargetUNIT )
|
|
||||||
end
|
|
||||||
|
|
||||||
self:T( "Hitting Scenery" )
|
local playername = Event.WeaponPlayerName or Event.IniPlayerName or "Ghost"
|
||||||
|
|
||||||
|
--self:_AddPlayerFromUnit( Event.WeaponUNIT )
|
||||||
|
if self.Players[playername] then -- This should normally not happen, but i'll test it anyway.
|
||||||
|
|
||||||
|
self:T( "Hitting Scenery or Static" )
|
||||||
|
|
||||||
-- What is he hitting?
|
-- What is he hitting?
|
||||||
if TargetCategory then
|
if Event.TgtObjectCategory then
|
||||||
|
|
||||||
-- A scenery or static got hit, score it.
|
-- A scenery or static got hit, score it.
|
||||||
-- Player contains the score data from self.Players[WeaponPlayerName]
|
-- Player contains the score data from self.Players[WeaponPlayerName]
|
||||||
local Player = self.Players[Event.WeaponPlayerName]
|
local Player = self.Players[playername]
|
||||||
|
|
||||||
-- Ensure there is a hit table per TargetCategory and TargetUnitName.
|
-- Ensure there is a hit table per TargetCategory and TargetUnitName.
|
||||||
Player.Hit[TargetCategory] = Player.Hit[TargetCategory] or {}
|
Player.Hit[TargetCategory] = Player.Hit[TargetCategory] or {}
|
||||||
@@ -1180,14 +1302,16 @@ function SCORING:_EventOnHit( Event )
|
|||||||
-- PlayerHit contains the score counters and data per unit that was hit.
|
-- PlayerHit contains the score counters and data per unit that was hit.
|
||||||
local PlayerHit = Player.Hit[TargetCategory][TargetUnitName]
|
local PlayerHit = Player.Hit[TargetCategory][TargetUnitName]
|
||||||
|
|
||||||
|
-- Init player scores
|
||||||
PlayerHit.Score = PlayerHit.Score or 0
|
PlayerHit.Score = PlayerHit.Score or 0
|
||||||
PlayerHit.Penalty = PlayerHit.Penalty or 0
|
PlayerHit.Penalty = PlayerHit.Penalty or 0
|
||||||
PlayerHit.ScoreHit = PlayerHit.ScoreHit or 0
|
PlayerHit.ScoreHit = PlayerHit.ScoreHit or 0
|
||||||
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
|
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit or 0
|
||||||
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
|
PlayerHit.TimeStamp = PlayerHit.TimeStamp or 0
|
||||||
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
|
PlayerHit.UNIT = PlayerHit.UNIT or TargetUNIT
|
||||||
|
|
||||||
-- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth
|
-- After an instant kill we can't compute the threat level anymore. To fix this we compute at OnEventBirth
|
||||||
if PlayerHit.UNIT.ThreatType == nil then
|
if PlayerHit.UNIT and PlayerHit.UNIT.ThreatType == nil then
|
||||||
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
|
PlayerHit.ThreatLevel, PlayerHit.ThreatType = PlayerHit.UNIT:GetThreatLevel()
|
||||||
-- if this fails for some reason, set a good default value
|
-- if this fails for some reason, set a good default value
|
||||||
if PlayerHit.ThreatType == nil then
|
if PlayerHit.ThreatType == nil then
|
||||||
@@ -1195,8 +1319,8 @@ function SCORING:_EventOnHit( Event )
|
|||||||
PlayerHit.ThreatType = "Unknown"
|
PlayerHit.ThreatType = "Unknown"
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
PlayerHit.ThreatLevel = PlayerHit.UNIT.ThreatLevel
|
PlayerHit.ThreatLevel = PlayerHit.UNIT and PlayerHit.UNIT.ThreatLevel or 1
|
||||||
PlayerHit.ThreatType = PlayerHit.UNIT.ThreatType
|
PlayerHit.ThreatType = PlayerHit.UNIT and PlayerHit.UNIT.ThreatType or "Unknown"
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Only grant hit scores if there was more than one second between the last hit.
|
-- Only grant hit scores if there was more than one second between the last hit.
|
||||||
@@ -1205,48 +1329,66 @@ function SCORING:_EventOnHit( Event )
|
|||||||
|
|
||||||
local Score = 0
|
local Score = 0
|
||||||
|
|
||||||
if InitCoalition then -- A coalition object was hit, probably a static.
|
local TgtName = Event.TgtDCSUnit and Event.TgtDCSUnit.getName and Event.TgtDCSUnit:getName() or "Unknown"
|
||||||
if InitCoalition == TargetCoalition then
|
|
||||||
-- TODO: Penalty according scale
|
|
||||||
local Penalty = 10
|
|
||||||
Player.Penalty = Player.Penalty + Penalty --* self.ScaleDestroyPenalty
|
|
||||||
PlayerHit.Penalty = PlayerHit.Penalty + Penalty --* self.ScaleDestroyPenalty
|
|
||||||
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1 * self.ScaleDestroyPenalty
|
|
||||||
|
|
||||||
MESSAGE
|
--if InitCoalition then -- A coalition object was hit, probably a static.
|
||||||
:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " ..
|
if TargetIsScenery == true and self.ScoringScenery:IsInSet(TargetSceneryObject) then
|
||||||
TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
|
||||||
"Penalty: -" .. Penalty .. " = " .. Player.Score - Player.Penalty,
|
|
||||||
MESSAGE.Type.Update
|
|
||||||
)
|
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
|
||||||
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
|
||||||
self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_PENALTY", 1, -10, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
|
||||||
else
|
|
||||||
Player.Score = Player.Score + self.ScoreIncrementOnHit
|
Player.Score = Player.Score + self.ScoreIncrementOnHit
|
||||||
PlayerHit.Score = PlayerHit.Score + self.ScoreIncrementOnHit
|
PlayerHit.Score = PlayerHit.Score + self.ScoreIncrementOnHit
|
||||||
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
|
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit enemy target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. playername .. "' hit scenery target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||||
MESSAGE.Type.Update )
|
MESSAGE.Type.Update )
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
|
|
||||||
self:ScoreCSV( Event.WeaponPlayerName, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
self:ScoreCSV( playername, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
end
|
elseif TargetIsScenery == false and Event.TgtObjectCategory == Object.Category.STATIC and self.ScoringObjects[TgtName] then
|
||||||
else -- A scenery object was hit.
|
Player.Score = Player.Score + self.ScoreIncrementOnHit
|
||||||
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit scenery object.",
|
PlayerHit.Score = PlayerHit.Score + self.ScoreIncrementOnHit
|
||||||
MESSAGE.Type.Update )
|
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
|
||||||
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. playername .. "' hit static target " .. TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
|
||||||
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
|
||||||
|
MESSAGE.Type.Update )
|
||||||
|
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
|
||||||
|
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
|
||||||
|
|
||||||
self:ScoreCSV( Event.WeaponPlayerName, "", "HIT_SCORE", 1, 0, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, "", "Scenery", TargetUnitType )
|
self:ScoreCSV( playername, TargetPlayerName, "HIT_SCORE", 1, 1, Event.WeaponName, Event.WeaponCoalition, Event.WeaponCategory, Event.WeaponTypeName, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
|
||||||
end
|
|
||||||
|
else
|
||||||
|
self:E("Hit unregistered scenery or static object - NO target! ("..TgtName..")")
|
||||||
|
end
|
||||||
|
--end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Check if there are Zones where the destruction happened.
|
||||||
|
for ZoneName, ScoreZoneData in pairs( self.ScoringZones ) do
|
||||||
|
self:F( { ScoringZone = ScoreZoneData } )
|
||||||
|
local hit=Event.TgtUnit
|
||||||
|
local ScoreZone = ScoreZoneData.ScoreZone -- Core.Zone#ZONE_BASE
|
||||||
|
local Score = ScoreZoneData.Score
|
||||||
|
if TargetUNIT and ScoreZone:IsVec2InZone( TargetUNIT:GetVec2() ) then
|
||||||
|
-- A scenery or static got hit, score it.
|
||||||
|
-- Player contains the score data from self.Players[WeaponPlayerName]
|
||||||
|
local PlayerName = Event.IniPlayerName or "Ghost"
|
||||||
|
local Player = self.Players[PlayerName]
|
||||||
|
|
||||||
|
Player.Score = Player.Score + Score
|
||||||
|
Player.Score = Player.Score + self.ScoreIncrementOnHit
|
||||||
|
MESSAGE:NewType( self.DisplayMessagePrefix .. "hit in zone '" .. ScoreZone:GetName() .. "'." ..
|
||||||
|
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! " .. "Total: " .. Player.Score - Player.Penalty,
|
||||||
|
MESSAGE.Type.Information )
|
||||||
|
:ToAllIf( self:IfMessagesZone() and self:IfMessagesToAll() )
|
||||||
|
:ToCoalitionIf( InitCoalition, self:IfMessagesZone() and self:IfMessagesToCoalition() )
|
||||||
|
|
||||||
|
self:ScoreCSV( PlayerName, "", "HIT_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, "", "Zone", TargetUnitType )
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
end
|
||||||
|
|
||||||
--- Track DEAD or CRASH events for the scoring.
|
--- Track DEAD or CRASH events for the scoring.
|
||||||
-- @param #SCORING self
|
-- @param #SCORING self
|
||||||
@@ -1305,7 +1447,7 @@ function SCORING:_EventOnDeadOrCrash( Event )
|
|||||||
local Destroyed = false
|
local Destroyed = false
|
||||||
|
|
||||||
-- What is the player destroying?
|
-- What is the player destroying?
|
||||||
if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 and (TargetUnit.BirthTime == nil or Player.Hit[TargetCategory][TargetUnitName].TimeStamp > TargetUnit.BirthTime) then -- Was there a hit for this unit for this player before registered???
|
if Player and Player.Hit and Player.Hit[TargetCategory] and Player.Hit[TargetCategory][TargetUnitName] and Player.Hit[TargetCategory][TargetUnitName].TimeStamp ~= 0 and TargetUnit and (TargetUnit.BirthTime == nil or Player.Hit[TargetCategory][TargetUnitName].TimeStamp > TargetUnit.BirthTime) then -- Was there a hit for this unit for this player before registered???
|
||||||
|
|
||||||
local TargetThreatLevel = Player.Hit[TargetCategory][TargetUnitName].ThreatLevel
|
local TargetThreatLevel = Player.Hit[TargetCategory][TargetUnitName].ThreatLevel
|
||||||
local TargetThreatType = Player.Hit[TargetCategory][TargetUnitName].ThreatType
|
local TargetThreatType = Player.Hit[TargetCategory][TargetUnitName].ThreatType
|
||||||
|
|||||||
@@ -1132,7 +1132,7 @@
|
|||||||
-- specify an "Assignment". This can be later used to identify the request and take the right actions.
|
-- specify an "Assignment". This can be later used to identify the request and take the right actions.
|
||||||
--
|
--
|
||||||
-- Once the request is processed, the @{#WAREHOUSE.OnAfterSelfRequest} function is called. This is where we hook in and postprocess the spawned assets.
|
-- Once the request is processed, the @{#WAREHOUSE.OnAfterSelfRequest} function is called. This is where we hook in and postprocess the spawned assets.
|
||||||
-- In particular, we use the @{AI.AI_Formation#AI_FORMATION} class to make some nice escorts for our carrier.
|
-- In particular, we use the @{Functional.Formation#FORMATION} class to make some nice escorts for our carrier.
|
||||||
--
|
--
|
||||||
-- When the resue helo is spawned, we can check that this is the correct asset and make the helo go into formation with the carrier.
|
-- When the resue helo is spawned, we can check that this is the correct asset and make the helo go into formation with the carrier.
|
||||||
-- Once the helo runs out of fuel, it will automatically return to the ship and land. For the warehouse, this means that the "cargo", i.e. the helicopter
|
-- Once the helo runs out of fuel, it will automatically return to the ship and land. For the warehouse, this means that the "cargo", i.e. the helicopter
|
||||||
@@ -1175,7 +1175,7 @@
|
|||||||
--
|
--
|
||||||
-- -- Define AI Formation object.
|
-- -- Define AI Formation object.
|
||||||
-- -- Note that this has to be a global variable or the garbage collector will remove it for some reason!
|
-- -- Note that this has to be a global variable or the garbage collector will remove it for some reason!
|
||||||
-- CarrierFormationLeft = AI_FORMATION:New(Mother, groupset, "Left Formation with Carrier", "Escort Carrier.")
|
-- CarrierFormationLeft = FORMATION:New(Mother, groupset, "Left Formation with Carrier")
|
||||||
--
|
--
|
||||||
-- -- Formation parameters.
|
-- -- Formation parameters.
|
||||||
-- CarrierFormationLeft:FormationLeftWing(200 ,50, 0, 0, 500, 50)
|
-- CarrierFormationLeft:FormationLeftWing(200 ,50, 0, 0, 500, 50)
|
||||||
@@ -1190,7 +1190,7 @@
|
|||||||
--
|
--
|
||||||
-- -- Define AI Formation object.
|
-- -- Define AI Formation object.
|
||||||
-- -- Note that this has to be a global variable or the garbage collector will remove it for some reason!
|
-- -- Note that this has to be a global variable or the garbage collector will remove it for some reason!
|
||||||
-- CarrierFormationRight = AI_FORMATION:New(Mother, groupset, "Right Formation with Carrier", "Escort Carrier.")
|
-- CarrierFormationRight = FORMATION:New(Mother, groupset, "Right Formation with Carrier")
|
||||||
--
|
--
|
||||||
-- -- Formation parameters.
|
-- -- Formation parameters.
|
||||||
-- CarrierFormationRight:FormationRightWing(200 ,50, 0, 0, 500, 50)
|
-- CarrierFormationRight:FormationRightWing(200 ,50, 0, 0, 500, 50)
|
||||||
@@ -1208,7 +1208,7 @@
|
|||||||
-- group:StartUncontrolled()
|
-- group:StartUncontrolled()
|
||||||
--
|
--
|
||||||
-- -- Define AI Formation object.
|
-- -- Define AI Formation object.
|
||||||
-- CarrierFormationHelo = AI_FORMATION:New(Mother, groupset, "Helo Formation with Carrier", "Fly Formation.")
|
-- CarrierFormationHelo = FORMATION:New(Mother, groupset, "Helo Formation with Carrier")
|
||||||
--
|
--
|
||||||
-- -- Formation parameters.
|
-- -- Formation parameters.
|
||||||
-- CarrierFormationHelo:FormationCenterWing(-150, 50, 20, 50, 100, 50)
|
-- CarrierFormationHelo:FormationCenterWing(-150, 50, 20, 50, 100, 50)
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ __Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/ZoneGoalCargo.lua'
|
|||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Tiresias.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Tiresias.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Stratego.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Stratego.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/ClientWatch.lua')
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/ClientWatch.lua')
|
||||||
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Functional/Formation.lua')
|
||||||
|
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Airboss.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/Airboss.lua' )
|
||||||
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/RecoveryTanker.lua' )
|
__Moose.Include( MOOSE_DEVELOPMENT_FOLDER..'/Moose/Ops/RecoveryTanker.lua' )
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
-- @module Navigation.Beacons
|
-- @module Navigation.Beacons
|
||||||
-- @image NAVIGATION_Beacons.png
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
--
|
--
|
||||||
-- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `beacons.lua` that can be
|
-- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `beacons.lua` that can be
|
||||||
-- found in the installation directory of DCS for each map or a table that the user needs to provide.
|
-- found in the installation directory of DCS for each map or a table that the user needs to provide.
|
||||||
|
-- **Note** your `MissionScripting` environment needs to be desanitized to read this data. `Package` als needs to be available.
|
||||||
--
|
--
|
||||||
-- # Basic Setup
|
-- # Basic Setup
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
-- @module Navigation.Point
|
-- @module Navigation.Point
|
||||||
-- @image NAVIGATION_Point.png
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
-- @module Navigation.Radios
|
-- @module Navigation.Radios
|
||||||
-- @image NAVIGATION_Radios.png
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
--
|
--
|
||||||
-- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `radio.lua` that can be
|
-- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `radio.lua` that can be
|
||||||
-- found in the installation directory of DCS for each map or a table that the user needs to provide.
|
-- found in the installation directory of DCS for each map or a table that the user needs to provide.
|
||||||
|
-- **Note** your `MissionScripting` environment needs to be desanitized to read this data.
|
||||||
--
|
--
|
||||||
-- # Basic Setup
|
-- # Basic Setup
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
--
|
--
|
||||||
-- ===
|
-- ===
|
||||||
-- @module Navigation.Towns
|
-- @module Navigation.Towns
|
||||||
-- @image NAVIGATION_Towns.png
|
-- @image MOOSE.JPG
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
@@ -43,6 +43,7 @@
|
|||||||
--
|
--
|
||||||
-- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `towns.lua` that can be
|
-- **Note** that try to avoid hard coding stuff in Moose since DCS is updated frequently and things change. Therefore, the main source of information is either a file `towns.lua` that can be
|
||||||
-- found in the installation directory of DCS for each map or a table that the user needs to provide.
|
-- found in the installation directory of DCS for each map or a table that the user needs to provide.
|
||||||
|
-- **Note** your `MissionScripting` environment needs to be desanitized to read this data.
|
||||||
--
|
--
|
||||||
-- # Basic Setup
|
-- # Basic Setup
|
||||||
--
|
--
|
||||||
|
|||||||
@@ -45,7 +45,7 @@
|
|||||||
-- **Supported Aircraft:**
|
-- **Supported Aircraft:**
|
||||||
--
|
--
|
||||||
-- * [F/A-18C Hornet Lot 20](https://forums.eagle.ru/forumdisplay.php?f=557) (Player & AI)
|
-- * [F/A-18C Hornet Lot 20](https://forums.eagle.ru/forumdisplay.php?f=557) (Player & AI)
|
||||||
-- * [F-14A/B Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI)
|
-- * [F-14A/B/A Early Tomcat](https://forums.eagle.ru/forumdisplay.php?f=395) (Player & AI)
|
||||||
-- * [A-4E Skyhawk Community Mod](https://forums.eagle.ru/showthread.php?t=224989) (Player & AI)
|
-- * [A-4E Skyhawk Community Mod](https://forums.eagle.ru/showthread.php?t=224989) (Player & AI)
|
||||||
-- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI)
|
-- * [AV-8B N/A Harrier](https://forums.eagle.ru/forumdisplay.php?f=555) (Player & AI)
|
||||||
-- * [T-45C Goshawk](https://forum.dcs.world/topic/203816-vnao-t-45-goshawk/) (VNAO mod) (Player & AI)
|
-- * [T-45C Goshawk](https://forum.dcs.world/topic/203816-vnao-t-45-goshawk/) (VNAO mod) (Player & AI)
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
-- no other fixed wing aircraft (human or AI controlled) are supposed to land on these ships. Currently only Case I is supported. Case II/III take slightly different steps from the CVN carrier.
|
-- no other fixed wing aircraft (human or AI controlled) are supposed to land on these ships. Currently only Case I is supported. Case II/III take slightly different steps from the CVN carrier.
|
||||||
-- However, if no offset is used for the holding radial this provides a very close representation of the V/STOL Case III, allowing for an approach to over the deck and a vertical landing.
|
-- However, if no offset is used for the holding radial this provides a very close representation of the V/STOL Case III, allowing for an approach to over the deck and a vertical landing.
|
||||||
--
|
--
|
||||||
-- Heatblur's mighty F-14B Tomcat has been added (March 13th 2019) as well. Same goes for the A version.
|
-- Heatblur's mighty F-14A/B/A Early Tomcat has been added as well.
|
||||||
--
|
--
|
||||||
-- The [DCS Supercarriers](https://www.digitalcombatsimulator.com/de/shop/modules/supercarrier/) are also supported.
|
-- The [DCS Supercarriers](https://www.digitalcombatsimulator.com/de/shop/modules/supercarrier/) are also supported.
|
||||||
--
|
--
|
||||||
@@ -1276,6 +1276,7 @@ AIRBOSS = {
|
|||||||
-- @field #string A4EC A-4E Community mod.
|
-- @field #string A4EC A-4E Community mod.
|
||||||
-- @field #string HORNET F/A-18C Lot 20 Hornet by Eagle Dynamics.
|
-- @field #string HORNET F/A-18C Lot 20 Hornet by Eagle Dynamics.
|
||||||
-- @field #string F14A F-14A by Heatblur.
|
-- @field #string F14A F-14A by Heatblur.
|
||||||
|
-- @field #string F14A_Early F-14A-135-GR-Early by Heatblur.
|
||||||
-- @field #string F14B F-14B by Heatblur.
|
-- @field #string F14B F-14B by Heatblur.
|
||||||
-- @field #string F14A_AI F-14A Tomcat (AI).
|
-- @field #string F14A_AI F-14A Tomcat (AI).
|
||||||
-- @field #string FA18C F/A-18C Hornet (AI).
|
-- @field #string FA18C F/A-18C Hornet (AI).
|
||||||
@@ -1294,6 +1295,7 @@ AIRBOSS.AircraftCarrier={
|
|||||||
HORNET="FA-18C_hornet",
|
HORNET="FA-18C_hornet",
|
||||||
A4EC="A-4E-C",
|
A4EC="A-4E-C",
|
||||||
F14A="F-14A-135-GR",
|
F14A="F-14A-135-GR",
|
||||||
|
F14A_Early="F-14A-135-GR-Early",
|
||||||
F14B="F-14B",
|
F14B="F-14B",
|
||||||
F14A_AI="F-14A",
|
F14A_AI="F-14A",
|
||||||
FA18C="F/A-18C",
|
FA18C="F/A-18C",
|
||||||
@@ -5473,7 +5475,7 @@ function AIRBOSS:_GetAircraftAoA( playerData )
|
|||||||
local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C
|
local goshawk = playerData.actype == AIRBOSS.AircraftCarrier.T45C
|
||||||
local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC
|
local skyhawk = playerData.actype == AIRBOSS.AircraftCarrier.A4EC
|
||||||
local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B
|
local harrier = playerData.actype == AIRBOSS.AircraftCarrier.AV8B
|
||||||
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B
|
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B or playerData.actype == AIRBOSS.AircraftCarrier.F14A_Early
|
||||||
local corsair = playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR or playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR_CW
|
local corsair = playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR or playerData.actype == AIRBOSS.AircraftCarrier.CORSAIR_CW
|
||||||
|
|
||||||
-- Table with AoA values.
|
-- Table with AoA values.
|
||||||
@@ -5552,7 +5554,7 @@ function AIRBOSS:_AoAUnit2Deg( playerData, aoaunits )
|
|||||||
local degrees = aoaunits
|
local degrees = aoaunits
|
||||||
|
|
||||||
-- Check aircraft type of player.
|
-- Check aircraft type of player.
|
||||||
if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then
|
if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B or playerData.actype == AIRBOSS.AircraftCarrier.F14A_Early then
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- F-14A/B --
|
-- F-14A/B --
|
||||||
@@ -5595,7 +5597,7 @@ function AIRBOSS:_AoADeg2Units( playerData, degrees )
|
|||||||
local aoaunits = degrees
|
local aoaunits = degrees
|
||||||
|
|
||||||
-- Check aircraft type of player.
|
-- Check aircraft type of player.
|
||||||
if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B then
|
if playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B or playerData.actype == AIRBOSS.AircraftCarrier.F14A_Early then
|
||||||
|
|
||||||
-------------
|
-------------
|
||||||
-- F-14A/B --
|
-- F-14A/B --
|
||||||
@@ -11593,7 +11595,7 @@ function AIRBOSS:_AttitudeMonitor( playerData )
|
|||||||
|
|
||||||
local unitClient = Unit.getByName(unit:GetName()) -- VNAO Edit - Added
|
local unitClient = Unit.getByName(unit:GetName()) -- VNAO Edit - Added
|
||||||
local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET -- VNAO Edit - Added
|
local hornet = playerData.actype == AIRBOSS.AircraftCarrier.HORNET -- VNAO Edit - Added
|
||||||
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B -- VNAO Edit - Added
|
local tomcat = playerData.actype == AIRBOSS.AircraftCarrier.F14A or playerData.actype == AIRBOSS.AircraftCarrier.F14B or playerData.actype == AIRBOSS.AircraftCarrier.F14A_Early -- VNAO Edit - Added
|
||||||
|
|
||||||
if hornet then -- VNAO Edit - Added
|
if hornet then -- VNAO Edit - Added
|
||||||
local nozzlePosL = 0 -- VNAO Edit - Added
|
local nozzlePosL = 0 -- VNAO Edit - Added
|
||||||
@@ -11826,7 +11828,7 @@ function AIRBOSS:_NozzleArgumentLeft( unit ) -- VNAO Edit - Added
|
|||||||
else -- VNAO Edit - Added
|
else -- VNAO Edit - Added
|
||||||
nozzlePosL = 0 -- VNAO Edit - Added
|
nozzlePosL = 0 -- VNAO Edit - Added
|
||||||
end -- VNAO Edit - Added
|
end -- VNAO Edit - Added
|
||||||
elseif typeName == "F-14A-135-GR" or typeName == "F-14B" then -- VNAO Edit - Added
|
elseif typeName == "F-14A-135-GR" or typeName == "F-14B" or typeName == "F-14A-135-GR-Early" then -- VNAO Edit - Added
|
||||||
nozzlePosL = unitClient:getDrawArgumentValue(434) -- VNAO Edit - Added
|
nozzlePosL = unitClient:getDrawArgumentValue(434) -- VNAO Edit - Added
|
||||||
end -- VNAO Edit - Added
|
end -- VNAO Edit - Added
|
||||||
|
|
||||||
@@ -11851,7 +11853,7 @@ function AIRBOSS:_NozzleArgumentRight( unit ) -- VNAO Edit - Added
|
|||||||
else -- VNAO Edit - Added
|
else -- VNAO Edit - Added
|
||||||
nozzlePosR = 0 -- VNAO Edit - Added
|
nozzlePosR = 0 -- VNAO Edit - Added
|
||||||
end -- VNAO Edit - Added
|
end -- VNAO Edit - Added
|
||||||
elseif typeName == "F-14A-135-GR" or typeName == "F-14B" then -- VNAO Edit - Added
|
elseif typeName == "F-14A-135-GR" or typeName == "F-14B" or typeName == "F-14A-135-GR-Early" then -- VNAO Edit - Added
|
||||||
nozzlePosR = unitClient:getDrawArgumentValue(433) -- VNAO Edit - Added
|
nozzlePosR = unitClient:getDrawArgumentValue(433) -- VNAO Edit - Added
|
||||||
end -- VNAO Edit - Added
|
end -- VNAO Edit - Added
|
||||||
return nozzlePosR -- VNAO Edit - Added
|
return nozzlePosR -- VNAO Edit - Added
|
||||||
@@ -15066,7 +15068,7 @@ function AIRBOSS:_GetACNickname( actype )
|
|||||||
nickname = "Hawkeye"
|
nickname = "Hawkeye"
|
||||||
elseif actype == AIRBOSS.AircraftCarrier.C2A then
|
elseif actype == AIRBOSS.AircraftCarrier.C2A then
|
||||||
nickname = "Greyhound"
|
nickname = "Greyhound"
|
||||||
elseif actype == AIRBOSS.AircraftCarrier.F14A_AI or actype == AIRBOSS.AircraftCarrier.F14A or actype == AIRBOSS.AircraftCarrier.F14B then
|
elseif actype == AIRBOSS.AircraftCarrier.F14A_AI or actype == AIRBOSS.AircraftCarrier.F14A or actype == AIRBOSS.AircraftCarrier.F14B or actype == AIRBOSS.AircraftCarrier.F14A_Early then
|
||||||
nickname = "Tomcat"
|
nickname = "Tomcat"
|
||||||
elseif actype == AIRBOSS.AircraftCarrier.FA18C or actype == AIRBOSS.AircraftCarrier.HORNET then
|
elseif actype == AIRBOSS.AircraftCarrier.FA18C or actype == AIRBOSS.AircraftCarrier.HORNET then
|
||||||
nickname = "Hornet"
|
nickname = "Hornet"
|
||||||
|
|||||||
@@ -2037,7 +2037,7 @@ function AUFTRAG:NewRESCUEHELO(Carrier)
|
|||||||
|
|
||||||
-- Mission options:
|
-- Mission options:
|
||||||
mission.missionTask=ENUMS.MissionTask.NOTHING
|
mission.missionTask=ENUMS.MissionTask.NOTHING
|
||||||
mission.missionFraction=0.5
|
mission.missionFraction=0.9
|
||||||
mission.optionROE=ENUMS.ROE.WeaponHold
|
mission.optionROE=ENUMS.ROE.WeaponHold
|
||||||
mission.optionROT=ENUMS.ROT.NoReaction
|
mission.optionROT=ENUMS.ROT.NoReaction
|
||||||
|
|
||||||
|
|||||||
@@ -4309,6 +4309,26 @@ function OPSGROUP:_UpdateTask(Task, Mission)
|
|||||||
|
|
||||||
if Task.dcstask.id==AUFTRAG.SpecialTask.FORMATION then
|
if Task.dcstask.id==AUFTRAG.SpecialTask.FORMATION then
|
||||||
|
|
||||||
|
if Mission.type == AUFTRAG.Type.RESCUEHELO then
|
||||||
|
self:T("**********")
|
||||||
|
self:T("** RESCUEHELO USED")
|
||||||
|
self:T("**********")
|
||||||
|
local param=Task.dcstask.params
|
||||||
|
local followUnit=UNIT:FindByName(param.unitname)
|
||||||
|
local helogroupname = self:GetGroup():GetName()
|
||||||
|
Task.formation = RESCUEHELO:New(followUnit,helogroupname)
|
||||||
|
Task.formation:SetRespawnOnOff(false)
|
||||||
|
Task.formation.respawninair=false
|
||||||
|
Task.formation:SetTakeoffCold()
|
||||||
|
Task.formation:SetHomeBase(followUnit)
|
||||||
|
Task.formation.helo = self:GetGroup()
|
||||||
|
-- Start formation FSM.
|
||||||
|
Task.formation:Start()
|
||||||
|
if self:IsFlightgroup() then
|
||||||
|
self:SetDespawnAfterLanding()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
-- Set of group(s) to follow Mother.
|
-- Set of group(s) to follow Mother.
|
||||||
local followSet=SET_GROUP:New():AddGroup(self.group)
|
local followSet=SET_GROUP:New():AddGroup(self.group)
|
||||||
|
|
||||||
@@ -4317,7 +4337,7 @@ function OPSGROUP:_UpdateTask(Task, Mission)
|
|||||||
local followUnit=UNIT:FindByName(param.unitname)
|
local followUnit=UNIT:FindByName(param.unitname)
|
||||||
|
|
||||||
-- Define AI Formation object.
|
-- Define AI Formation object.
|
||||||
Task.formation=AI_FORMATION:New(followUnit, followSet, AUFTRAG.SpecialTask.FORMATION, "Follow X at given parameters.")
|
Task.formation=FORMATION:New(followUnit, followSet, AUFTRAG.SpecialTask.FORMATION)
|
||||||
|
|
||||||
-- Formation parameters.
|
-- Formation parameters.
|
||||||
Task.formation:FormationCenterWing(-param.offsetX, 50, math.abs(param.altitude), 50, param.offsetZ, 50)
|
Task.formation:FormationCenterWing(-param.offsetX, 50, math.abs(param.altitude), 50, param.offsetZ, 50)
|
||||||
@@ -4326,11 +4346,13 @@ function OPSGROUP:_UpdateTask(Task, Mission)
|
|||||||
Task.formation:SetFollowTimeInterval(param.dtFollow)
|
Task.formation:SetFollowTimeInterval(param.dtFollow)
|
||||||
|
|
||||||
-- Formation mode.
|
-- Formation mode.
|
||||||
Task.formation:SetFlightModeFormation(self.group)
|
--Task.formation:SetFlightModeFormation(self.group)
|
||||||
|
|
||||||
-- Start formation FSM.
|
-- Start formation FSM.
|
||||||
Task.formation:Start()
|
Task.formation:Start()
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
elseif Task.dcstask.id==AUFTRAG.SpecialTask.PATROLZONE then
|
elseif Task.dcstask.id==AUFTRAG.SpecialTask.PATROLZONE then
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -8026,11 +8048,16 @@ function OPSGROUP:onafterDead(From, Event, To)
|
|||||||
-- Get asset.
|
-- Get asset.
|
||||||
local asset=self.legion:GetAssetByName(self.groupname)
|
local asset=self.legion:GetAssetByName(self.groupname)
|
||||||
|
|
||||||
|
if asset then
|
||||||
|
|
||||||
-- Get request.
|
-- Get request.
|
||||||
local request=self.legion:GetRequestByID(asset.rid)
|
local request=self.legion:GetRequestByID(asset.rid)
|
||||||
|
|
||||||
-- Trigger asset dead event.
|
-- Trigger asset dead event.
|
||||||
self.legion:AssetDead(asset, request)
|
self.legion:AssetDead(asset, request)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Stop in 5 sec to give possible respawn attempts a chance.
|
-- Stop in 5 sec to give possible respawn attempts a chance.
|
||||||
@@ -12723,7 +12750,7 @@ end
|
|||||||
-- @return #OPSGROUP self
|
-- @return #OPSGROUP self
|
||||||
function OPSGROUP:SetDefaultCallsign(CallsignName, CallsignNumber)
|
function OPSGROUP:SetDefaultCallsign(CallsignName, CallsignNumber)
|
||||||
|
|
||||||
self:T(self.lid..string.format("Setting Default callsing %s-%s", tostring(CallsignName), tostring(CallsignNumber)))
|
self:T(self.lid..string.format("Setting Default callsign %s-%s", tostring(CallsignName), tostring(CallsignNumber)))
|
||||||
|
|
||||||
self.callsignDefault={} --#OPSGROUP.Callsign
|
self.callsignDefault={} --#OPSGROUP.Callsign
|
||||||
self.callsignDefault.NumberSquad=CallsignName
|
self.callsignDefault.NumberSquad=CallsignName
|
||||||
@@ -13482,8 +13509,8 @@ function OPSGROUP:GetAmmoUnit(unit, display)
|
|||||||
if ammotable then
|
if ammotable then
|
||||||
local weapons=#ammotable
|
local weapons=#ammotable
|
||||||
|
|
||||||
--self:I(ammotable)
|
--self:I(ammotable)
|
||||||
--UTILS.PrintTableToLog(ammotable)
|
--UTILS.PrintTableToLog(ammotable)
|
||||||
|
|
||||||
-- Loop over all weapons.
|
-- Loop over all weapons.
|
||||||
for w=1,weapons do
|
for w=1,weapons do
|
||||||
@@ -13491,9 +13518,9 @@ function OPSGROUP:GetAmmoUnit(unit, display)
|
|||||||
-- Number of current weapon.
|
-- Number of current weapon.
|
||||||
local Nammo=ammotable[w]["count"]
|
local Nammo=ammotable[w]["count"]
|
||||||
|
|
||||||
-- Range in meters. Seems only to exist for missiles (not shells).
|
-- Range in meters. Seems only to exist for missiles (not shells).
|
||||||
local rmin=ammotable[w]["desc"]["rangeMin"] or 0
|
local rmin=ammotable[w]["desc"]["rangeMin"] or 0
|
||||||
local rmax=ammotable[w]["desc"]["rangeMaxAltMin"] or 0
|
local rmax=ammotable[w]["desc"]["rangeMaxAltMin"] or 0
|
||||||
|
|
||||||
-- Type name of current weapon.
|
-- Type name of current weapon.
|
||||||
local Tammo=ammotable[w]["desc"]["typeName"]
|
local Tammo=ammotable[w]["desc"]["typeName"]
|
||||||
|
|||||||
@@ -20,7 +20,6 @@
|
|||||||
-- ===
|
-- ===
|
||||||
--
|
--
|
||||||
-- ### Author: **funkyfranky**
|
-- ### Author: **funkyfranky**
|
||||||
-- ### Contributions: Flightcontrol (@{AI.AI_Formation} class being used here)
|
|
||||||
--
|
--
|
||||||
-- @module Ops.RescueHelo
|
-- @module Ops.RescueHelo
|
||||||
-- @image Ops_RescueHelo.png
|
-- @image Ops_RescueHelo.png
|
||||||
@@ -37,7 +36,7 @@
|
|||||||
-- @field #number takeoff Takeoff type.
|
-- @field #number takeoff Takeoff type.
|
||||||
-- @field Wrapper.Airbase#AIRBASE airbase The airbase object acting as home base of the helo.
|
-- @field Wrapper.Airbase#AIRBASE airbase The airbase object acting as home base of the helo.
|
||||||
-- @field Core.Set#SET_GROUP followset Follow group set.
|
-- @field Core.Set#SET_GROUP followset Follow group set.
|
||||||
-- @field AI.AI_Formation#AI_FORMATION formation AI_FORMATION object.
|
-- @field Functional.Formation#FORMATION formation FORMATION object.
|
||||||
-- @field #number lowfuel Low fuel threshold of helo in percent.
|
-- @field #number lowfuel Low fuel threshold of helo in percent.
|
||||||
-- @field #number altitude Altitude of helo in meters.
|
-- @field #number altitude Altitude of helo in meters.
|
||||||
-- @field #number offsetX Offset in meters to carrier in longitudinal direction.
|
-- @field #number offsetX Offset in meters to carrier in longitudinal direction.
|
||||||
@@ -235,7 +234,7 @@ _RESCUEHELOID=0
|
|||||||
|
|
||||||
--- Class version.
|
--- Class version.
|
||||||
-- @field #string version
|
-- @field #string version
|
||||||
RESCUEHELO.version="1.1.0"
|
RESCUEHELO.version="1.2.0"
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- TODO list
|
-- TODO list
|
||||||
@@ -248,6 +247,7 @@ RESCUEHELO.version="1.1.0"
|
|||||||
-- DONE: Possibility to add already present/spawned aircraft, e.g. for warehouse.
|
-- DONE: Possibility to add already present/spawned aircraft, e.g. for warehouse.
|
||||||
-- DONE: Add rescue event when aircraft crashes.
|
-- DONE: Add rescue event when aircraft crashes.
|
||||||
-- DONE: Make offset input parameter.
|
-- DONE: Make offset input parameter.
|
||||||
|
-- DONE: Make useable for AUFTRAG
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
-- Constructor
|
-- Constructor
|
||||||
@@ -338,6 +338,9 @@ function RESCUEHELO:New(carrierunit, helogroupname)
|
|||||||
self:AddTransition("*", "Stop", "Stopped")
|
self:AddTransition("*", "Stop", "Stopped")
|
||||||
|
|
||||||
|
|
||||||
|
self:I(self.lid.."Started.")
|
||||||
|
|
||||||
|
|
||||||
--- Triggers the FSM event "Start" that starts the rescue helo. Initializes parameters and starts event handlers.
|
--- Triggers the FSM event "Start" that starts the rescue helo. Initializes parameters and starts event handlers.
|
||||||
-- @function [parent=#RESCUEHELO] Start
|
-- @function [parent=#RESCUEHELO] Start
|
||||||
-- @param #RESCUEHELO self
|
-- @param #RESCUEHELO self
|
||||||
@@ -872,14 +875,24 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
|||||||
-- Delay before formation is started.
|
-- Delay before formation is started.
|
||||||
local delay=120
|
local delay=120
|
||||||
|
|
||||||
-- Spawn helo. We need to introduce an alias in case this class is used twice. This would confuse the spawn routine.
|
local UsesAliveGroup=false
|
||||||
local Spawn=SPAWN:NewWithAlias(self.helogroupname, self.alias)
|
local Spawn = GROUP:FindByName(self.helogroupname)
|
||||||
|
if Spawn and Spawn:IsAlive() then
|
||||||
|
self.helo=Spawn
|
||||||
|
UsesAliveGroup = true
|
||||||
|
delay = 1
|
||||||
|
else
|
||||||
|
|
||||||
-- Set modex for spawn.
|
-- Spawn helo. We need to introduce an alias in case this class is used twice. This would confuse the spawn routine.
|
||||||
Spawn:InitModex(self.modex)
|
local Spawn=SPAWN:NewWithAlias(self.helogroupname, self.alias)
|
||||||
|
|
||||||
|
-- Set modex for spawn.
|
||||||
|
Spawn:InitModex(self.modex)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
-- Spawn in air or at airbase.
|
-- Spawn in air or at airbase.
|
||||||
if self.takeoff==SPAWN.Takeoff.Air then
|
if UsesAliveGroup==false and self.takeoff==SPAWN.Takeoff.Air then
|
||||||
|
|
||||||
-- Carrier heading
|
-- Carrier heading
|
||||||
local hdg=self.carrier:GetHeading()
|
local hdg=self.carrier:GetHeading()
|
||||||
@@ -899,7 +912,7 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
|||||||
-- Start formation in 1 seconds
|
-- Start formation in 1 seconds
|
||||||
delay=1
|
delay=1
|
||||||
|
|
||||||
else
|
elseif UsesAliveGroup==false and self.uncontrolledac then
|
||||||
|
|
||||||
-- Check if an uncontrolled helo group was requested.
|
-- Check if an uncontrolled helo group was requested.
|
||||||
if self.uncontrolledac then
|
if self.uncontrolledac then
|
||||||
@@ -921,7 +934,7 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
else
|
elseif UsesAliveGroup==false then
|
||||||
|
|
||||||
-- Spawn at airbase.
|
-- Spawn at airbase.
|
||||||
self.helo=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, AIRBASE.TerminalType.HelicopterUsable)
|
self.helo=Spawn:SpawnAtAirbase(self.airbase, self.takeoff, nil, AIRBASE.TerminalType.HelicopterUsable)
|
||||||
@@ -947,17 +960,13 @@ function RESCUEHELO:onafterStart(From, Event, To)
|
|||||||
self.HeloFuel0=self.helo:GetFuel()
|
self.HeloFuel0=self.helo:GetFuel()
|
||||||
|
|
||||||
-- Define AI Formation object.
|
-- Define AI Formation object.
|
||||||
self.formation=AI_FORMATION:New(self.carrier, self.followset, "Helo Formation with Carrier", "Follow Carrier at given parameters.")
|
self.formation=FORMATION:New(self.carrier, self.followset, "Helo Formation with Carrier")
|
||||||
|
|
||||||
-- Formation parameters.
|
-- Formation parameters.
|
||||||
self.formation:FormationCenterWing(-self.offsetX, 50, math.abs(self.altitude), 50, self.offsetZ, 50)
|
self.formation:FormationCenterWing(-self.offsetX, 50, math.abs(self.altitude), 50, self.offsetZ, 50)
|
||||||
|
|
||||||
-- Set follow time interval.
|
-- Set follow time interval.
|
||||||
self.formation:SetFollowTimeInterval(self.dtFollow)
|
self.formation:SetFollowTimeInterval(self.dtFollow)
|
||||||
|
|
||||||
-- Formation mode.
|
|
||||||
self.formation:SetFlightModeFormation(self.helo)
|
|
||||||
|
|
||||||
-- Start formation FSM.
|
-- Start formation FSM.
|
||||||
self.formation:__Start(delay)
|
self.formation:__Start(delay)
|
||||||
|
|
||||||
|
|||||||
@@ -5236,3 +5236,116 @@ function UTILS.ValidateAndRepositionStatic(Country, Category, Type, Position, Sh
|
|||||||
|
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---
|
||||||
|
-- This function can be used to scan all airdromes of a map and write the Moose enums to a file.
|
||||||
|
function UTILS.CreateAirbaseEnum()
|
||||||
|
|
||||||
|
-- Save file function
|
||||||
|
local function _savefile( filename, data )
|
||||||
|
local file=lfs.writedir() .. filename
|
||||||
|
local f = io.open(file , "wb")
|
||||||
|
if f then
|
||||||
|
f:write( data )
|
||||||
|
f:close()
|
||||||
|
env.info(string.format("Saving to file %s", tostring(file) ))
|
||||||
|
else
|
||||||
|
env.info(string.format("ERROR: Could not save results to file %s", tostring(file) ))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Get all airbases
|
||||||
|
local airbases=world.getAirbases()
|
||||||
|
|
||||||
|
-- Get map name
|
||||||
|
local mapname=env.mission.theatre
|
||||||
|
|
||||||
|
-- Put airbases in a table
|
||||||
|
local myab={}
|
||||||
|
for i,_airbase in pairs(airbases) do
|
||||||
|
local airbase=_airbase --DCS#Airbase
|
||||||
|
|
||||||
|
|
||||||
|
local cat=airbase:getDesc().category
|
||||||
|
|
||||||
|
if cat==Airbase.Category.AIRDROME then
|
||||||
|
|
||||||
|
-- Get airbase name
|
||||||
|
local name=airbase:getName()
|
||||||
|
|
||||||
|
-- Key is the name with illigal characters replaced
|
||||||
|
local key=name
|
||||||
|
|
||||||
|
-- Germany map specifics
|
||||||
|
if name=="Airracing Lubeck" then
|
||||||
|
key="Airracing_Luebeck"
|
||||||
|
elseif name=="Bad Durkheim" then
|
||||||
|
key="Bad_Duerkheim"
|
||||||
|
elseif name=="Buchel" then
|
||||||
|
key="Buechel"
|
||||||
|
elseif name=="Buckeburg" then
|
||||||
|
key="Bueckeburg"
|
||||||
|
elseif name=="Dusseldorf" then
|
||||||
|
key="Duesseldorf"
|
||||||
|
elseif name=="Gutersloh" then
|
||||||
|
key="Guetersloh"
|
||||||
|
elseif name=="Kothen" then
|
||||||
|
key="Koethen"
|
||||||
|
elseif name=="Larz" then
|
||||||
|
key="Laerz"
|
||||||
|
elseif name=="Lubeck" then
|
||||||
|
key="Luebeck"
|
||||||
|
elseif name=="Luneburg" then
|
||||||
|
key="Lueneburg"
|
||||||
|
elseif name=="Norvenich" then
|
||||||
|
key="Noervenich"
|
||||||
|
elseif name=="Ober-Morlen" then
|
||||||
|
key="Ober_Moerlen"
|
||||||
|
elseif name=="Peenemunde" then
|
||||||
|
key="Peenemuende"
|
||||||
|
elseif name=="Pottschutthohe" then
|
||||||
|
key="Pottschutthoehe"
|
||||||
|
elseif name=="Schonefeld" then
|
||||||
|
key="Schoenefeld"
|
||||||
|
elseif name=="Weser Wumme" then
|
||||||
|
key="Weser_Wuemme"
|
||||||
|
elseif name=="Zollschen" then
|
||||||
|
key="Zoellschen"
|
||||||
|
elseif name=="Zweibrucken" then
|
||||||
|
key="Zweibruecken"
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Replace blanks, hyphens by underscores
|
||||||
|
key=key:gsub(" ", "_")
|
||||||
|
key=key:gsub("-", "_")
|
||||||
|
key=key:gsub("'", "_")
|
||||||
|
key=UTILS.ReplaceIllegalCharacters(key, "_")
|
||||||
|
|
||||||
|
local entry={}
|
||||||
|
entry.key=key
|
||||||
|
entry.name=name
|
||||||
|
table.insert(myab, entry)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sort by name
|
||||||
|
table.sort(myab, function(a,b) return a.name < b.name end)
|
||||||
|
|
||||||
|
local text=string.format("\n--- Airbases of the %s map", mapname)
|
||||||
|
text=text.."\n--"
|
||||||
|
for _,ab in pairs(myab) do
|
||||||
|
text=text..string.format("\n-- * `AIRBASE.%s.%s` %s", mapname, ab.key, ab.name)
|
||||||
|
end
|
||||||
|
text=text.."\n--"
|
||||||
|
text=text..string.format("\n-- @field %s", mapname)
|
||||||
|
text=text..string.format("\nAIRBASE.%s = {", mapname)
|
||||||
|
for _,ab in pairs(myab) do
|
||||||
|
text=text..string.format('\n\t["%s"] = "%s",', ab.key, ab.name)
|
||||||
|
end
|
||||||
|
text=text.."\n}"
|
||||||
|
|
||||||
|
_savefile(string.format("%s-enums.txt", env.mission.theatre), text)
|
||||||
|
--env.info(text)
|
||||||
|
end
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -409,7 +409,7 @@ function CONTROLLABLE:SetTask( DCSTask, WaitTime )
|
|||||||
local Controller = self:_GetController()
|
local Controller = self:_GetController()
|
||||||
-- self:I( "Before SetTask" )
|
-- self:I( "Before SetTask" )
|
||||||
Controller:setTask( DCSTask )
|
Controller:setTask( DCSTask )
|
||||||
-- AI_FORMATION class (used by RESCUEHELO) calls SetTask twice per second! hence spamming the DCS log file ==> setting this to trace.
|
-- FORMATION class (used by RESCUEHELO) calls SetTask twice per second! hence spamming the DCS log file ==> setting this to trace.
|
||||||
self:T( { ControllableName = self:GetName(), DCSTask = DCSTask } )
|
self:T( { ControllableName = self:GetName(), DCSTask = DCSTask } )
|
||||||
else
|
else
|
||||||
BASE:E( { DCSControllableName .. " is not alive anymore.", DCSTask = DCSTask } )
|
BASE:E( { DCSControllableName .. " is not alive anymore.", DCSTask = DCSTask } )
|
||||||
|
|||||||
@@ -18,7 +18,13 @@
|
|||||||
-- @field #string SceneryName Name of the scenery object.
|
-- @field #string SceneryName Name of the scenery object.
|
||||||
-- @field DCS#Object SceneryObject DCS scenery object.
|
-- @field DCS#Object SceneryObject DCS scenery object.
|
||||||
-- @field #number Life0 Initial life points.
|
-- @field #number Life0 Initial life points.
|
||||||
-- @field #table Properties
|
-- @field #table Properties.
|
||||||
|
-- @field #number ID.
|
||||||
|
-- @field Core.Zone#ZONE_POLYGON SceneryZone.
|
||||||
|
-- @field Core.Point#COORDINATE Coordinate.
|
||||||
|
-- @field DCS#Vec2 Vec2.
|
||||||
|
-- @field DCS#Vec3 Vec3.
|
||||||
|
-- @field Core.Vector#VECTOR Vector.
|
||||||
-- @extends Wrapper.Positionable#POSITIONABLE
|
-- @extends Wrapper.Positionable#POSITIONABLE
|
||||||
|
|
||||||
|
|
||||||
@@ -35,27 +41,79 @@ SCENERY = {
|
|||||||
ClassName = "SCENERY",
|
ClassName = "SCENERY",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_SCENERY = {}
|
||||||
|
|
||||||
--- Register scenery object as POSITIONABLE.
|
--- Register scenery object as POSITIONABLE.
|
||||||
--@param #SCENERY self
|
--@param #SCENERY self
|
||||||
--@param #string SceneryName Scenery name.
|
--@param #string SceneryName Scenery name.
|
||||||
--@param DCS#Object SceneryObject DCS scenery object.
|
--@param DCS#Object SceneryObject DCS scenery object.
|
||||||
|
--@param Core.Zone#ZONE_POLYGON SceneryZone (optional) The zone object.
|
||||||
--@return #SCENERY Scenery object.
|
--@return #SCENERY Scenery object.
|
||||||
function SCENERY:Register( SceneryName, SceneryObject )
|
function SCENERY:Register( SceneryName, SceneryObject, SceneryZone )
|
||||||
|
|
||||||
|
local ID = (SceneryObject and SceneryObject.getID) and SceneryObject:getID() or SceneryName
|
||||||
|
|
||||||
|
if _SCENERY[ID] and _SCENERY[ID].SceneryObject == nil then
|
||||||
|
|
||||||
|
_SCENERY[ID].SceneryObject=SceneryObject
|
||||||
|
SCENERY._UpdateFromDCSObject(_SCENERY[ID])
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if _SCENERY[ID] then return _SCENERY[ID] end
|
||||||
|
|
||||||
local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) )
|
local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) )
|
||||||
|
|
||||||
self.SceneryName = tostring(SceneryName)
|
self.SceneryName = tostring(SceneryName)
|
||||||
|
self.ID = ID
|
||||||
self.SceneryObject = SceneryObject
|
self.SceneryObject = SceneryObject
|
||||||
|
self.SceneryZone = SceneryZone
|
||||||
|
|
||||||
|
if SceneryZone then
|
||||||
|
self.Vec3 = SceneryZone:GetVec3()
|
||||||
|
self.Vec2 = SceneryZone:GetVec2()
|
||||||
|
self.Vector = (self.Vec3 and VECTOR) and VECTOR:NewFromVec(self.Vec3) or nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if SceneryObject then
|
||||||
|
local vec3 = SceneryObject:getPoint()
|
||||||
|
self.Vec3 = { x = vec3.x, y = vec3.y, z = vec3.z }
|
||||||
|
self.Vec2 = { x = vec3.x, y = vec3.z }
|
||||||
|
self.Vector = (self.Vec3 and VECTOR) and VECTOR:NewFromVec(self.Vec3) or nil
|
||||||
|
end
|
||||||
|
|
||||||
if self.SceneryObject and self.SceneryObject.getLife then -- fix some objects do not have all functions
|
if self.SceneryObject and self.SceneryObject.getLife then -- fix some objects do not have all functions
|
||||||
self.Life0 = self.SceneryObject:getLife() or 0
|
self.Life0 = self.SceneryObject:getLife() or 1
|
||||||
else
|
else
|
||||||
self.Life0 = 0
|
self.Life0 = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
self.Properties = {}
|
self.Properties = {}
|
||||||
|
|
||||||
|
_SCENERY[self.ID] = self
|
||||||
|
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--- [INTERNAL] Update data
|
||||||
|
-- @param Wrapper.Scenery#SCENERY Scenery The object to update.
|
||||||
|
function SCENERY._UpdateFromDCSObject(Scenery)
|
||||||
|
env.info("APPLE _UpdateFromDCSObject "..tostring(Scenery.SceneryName))
|
||||||
|
local self=Scenery
|
||||||
|
if self.Vec2 == nil and self.SceneryObject ~= nil then
|
||||||
|
self.Vec3 = self.SceneryObject:getPoint()
|
||||||
|
if self.Vec3 then
|
||||||
|
self.Vec2 = {x=self.Vec3.x,y=self.Vec3.z}
|
||||||
|
self.Vector = VECTOR:NewFromVec(self.Vec3)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not self.Life0 or self.Life0 == 1 then
|
||||||
|
if self.SceneryObject and self.SceneryObject.getLife() then
|
||||||
|
self.Life = self.SceneryObject:getLife() or 1
|
||||||
|
self.Life0 = self.Life
|
||||||
|
end
|
||||||
|
end
|
||||||
return self
|
return self
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -99,6 +157,39 @@ function SCENERY:GetName()
|
|||||||
return self.SceneryName
|
return self.SceneryName
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Obtain object coordinate.
|
||||||
|
--@param #SCENERY self
|
||||||
|
--@return Core.Point#COORDINATE Coordinate
|
||||||
|
function SCENERY:GetCoordinate()
|
||||||
|
if self.Coordinate then
|
||||||
|
return self.Coordinate
|
||||||
|
elseif self.Vec3 then
|
||||||
|
self.Coordinate = COORDINATE:NewFromVec3(self.Vec3):SetAlt()
|
||||||
|
end
|
||||||
|
return self.Coordinate
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Obtain object coordinate.
|
||||||
|
--@param #SCENERY self
|
||||||
|
--@return DCS#Vec3 Vec3
|
||||||
|
function SCENERY:GetVec3()
|
||||||
|
return self.Vec3
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Obtain object coordinate.
|
||||||
|
--@param #SCENERY self
|
||||||
|
--@return DCS#Vec2 Vec2
|
||||||
|
function SCENERY:GetVec2()
|
||||||
|
return self.Vec2
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Obtain object coordinate.
|
||||||
|
--@param #SCENERY self
|
||||||
|
--@return Core.Vector#VECTOR Vector
|
||||||
|
function SCENERY:GetVector()
|
||||||
|
return self.Vector
|
||||||
|
end
|
||||||
|
|
||||||
--- Obtain DCS Object from the SCENERY Object.
|
--- Obtain DCS Object from the SCENERY Object.
|
||||||
--@param #SCENERY self
|
--@param #SCENERY self
|
||||||
--@return DCS#Object DCS scenery object.
|
--@return DCS#Object DCS scenery object.
|
||||||
@@ -106,6 +197,13 @@ function SCENERY:GetDCSObject()
|
|||||||
return self.SceneryObject
|
return self.SceneryObject
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Obtain object ID.
|
||||||
|
--@param #SCENERY self
|
||||||
|
--@return #string Name
|
||||||
|
function SCENERY:GetID()
|
||||||
|
return self.ID
|
||||||
|
end
|
||||||
|
|
||||||
--- Get current life points from the SCENERY Object. Note - Some scenery objects always have 0 life points.
|
--- Get current life points from the SCENERY Object. Note - Some scenery objects always have 0 life points.
|
||||||
-- **CAVEAT**: Some objects change their life value or "hitpoints" **after** the first hit. Hence we will adjust the life0 value to 120%
|
-- **CAVEAT**: Some objects change their life value or "hitpoints" **after** the first hit. Hence we will adjust the life0 value to 120%
|
||||||
-- of the last life value if life exceeds life0 (initial life) at any point. Thus will will get a smooth percentage decrease, if you use this e.g. as success
|
-- of the last life value if life exceeds life0 (initial life) at any point. Thus will will get a smooth percentage decrease, if you use this e.g. as success
|
||||||
@@ -113,12 +211,14 @@ end
|
|||||||
--@param #SCENERY self
|
--@param #SCENERY self
|
||||||
--@return #number life
|
--@return #number life
|
||||||
function SCENERY:GetLife()
|
function SCENERY:GetLife()
|
||||||
local life = 0
|
local life = 1
|
||||||
if self.SceneryObject and self.SceneryObject.getLife then
|
if self.SceneryObject and self.SceneryObject.getLife then
|
||||||
life = self.SceneryObject:getLife()
|
life = self.SceneryObject:getLife()
|
||||||
if life > self.Life0 then
|
if life > self.Life0 then
|
||||||
self.Life0 = math.floor(life * 1.2)
|
self.Life0 = math.floor(life * 1.2)
|
||||||
end
|
end
|
||||||
|
elseif self.Life then
|
||||||
|
life = self.Life
|
||||||
end
|
end
|
||||||
return life
|
return life
|
||||||
end
|
end
|
||||||
@@ -176,11 +276,18 @@ end
|
|||||||
--- Find a SCENERY object from its name or id. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
|
--- Find a SCENERY object from its name or id. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
|
||||||
-- to find the correct object.
|
-- to find the correct object.
|
||||||
--@param #SCENERY self
|
--@param #SCENERY self
|
||||||
--@param #string Name The name/id of the scenery object as taken from the ME. Ex. '595785449'
|
--@param #string Name The name/id of the scenery object as taken from the ME. Ex. '595785449'.
|
||||||
--@param Core.Point#COORDINATE Coordinate Where to find the scenery object
|
--@param Core.Point#COORDINATE Coordinate Where to find the scenery object.
|
||||||
--@param #number Radius (optional) Search radius around coordinate, defaults to 100
|
--@param #number Radius (optional) Search radius around coordinate, defaults to 100.
|
||||||
--@return #SCENERY Scenery Object or `nil` if it cannot be found
|
--@param #string Role (optional) The role if set on the zone object.
|
||||||
function SCENERY:FindByName(Name, Coordinate, Radius, Role)
|
--@param Core.Zone#ZONE_POLYGON Zone (optional) The Zone where the scenery is located.
|
||||||
|
--@return #SCENERY Scenery Object or `nil` if it cannot be found.
|
||||||
|
function SCENERY:FindByName(Name, Coordinate, Radius, Role, Zone)
|
||||||
|
|
||||||
|
--BASE:I("Coordinate x = "..Coordinate.x .. " y = "..Coordinate.y.." z = "..Coordinate.z)
|
||||||
|
|
||||||
|
local findme = self:_FindByName(Name)
|
||||||
|
if findme then return findme end
|
||||||
|
|
||||||
local radius = Radius or 100
|
local radius = Radius or 100
|
||||||
local name = Name or "unknown"
|
local name = Name or "unknown"
|
||||||
@@ -193,12 +300,13 @@ function SCENERY:FindByName(Name, Coordinate, Radius, Role)
|
|||||||
local function SceneryScan(scoordinate, sradius, sname)
|
local function SceneryScan(scoordinate, sradius, sname)
|
||||||
if scoordinate ~= nil then
|
if scoordinate ~= nil then
|
||||||
local Vec2 = scoordinate:GetVec2()
|
local Vec2 = scoordinate:GetVec2()
|
||||||
local scanzone = ZONE_RADIUS:New("Zone-"..sname,Vec2,sradius,true)
|
local scanzone = ZONE_RADIUS:New("Zone-"..sname,Vec2,sradius)
|
||||||
scanzone:Scan({Object.Category.SCENERY})
|
scanzone:Scan({Object.Category.SCENERY})
|
||||||
local scanned = scanzone:GetScannedSceneryObjects()
|
local scanned = scanzone:GetScannedSceneryObjects()
|
||||||
local rscenery = nil -- Wrapper.Scenery#SCENERY
|
local rscenery = nil -- Wrapper.Scenery#SCENERY
|
||||||
for _,_scenery in pairs(scanned) do
|
for _,_scenery in pairs(scanned) do
|
||||||
local scenery = _scenery -- Wrapper.Scenery#SCENERY
|
local scenery = _scenery -- Wrapper.Scenery#SCENERY
|
||||||
|
--BASE:I({tostring(scenery.SceneryName),tostring(sname)})
|
||||||
if tostring(scenery.SceneryName) == tostring(sname) then
|
if tostring(scenery.SceneryName) == tostring(sname) then
|
||||||
rscenery = scenery
|
rscenery = scenery
|
||||||
if Role then rscenery:SetProperty("ROLE",Role) end
|
if Role then rscenery:SetProperty("ROLE",Role) end
|
||||||
@@ -211,13 +319,36 @@ function SCENERY:FindByName(Name, Coordinate, Radius, Role)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if Coordinate then
|
if Coordinate then
|
||||||
--BASE:I("Coordinate Scenery Scan")
|
|
||||||
scenery = SceneryScan(Coordinate, radius, name)
|
scenery = SceneryScan(Coordinate, radius, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if not scenery then scenery = SCENERY:Register(Name,nil,Zone) end
|
||||||
|
|
||||||
return scenery
|
return scenery
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Find a SCENERY object that was previously registered(!) by it's ID.
|
||||||
|
-- @param #SCENERY self
|
||||||
|
-- @param #number ID
|
||||||
|
-- @return Wrapper.Scenery#SCENERY Scenery or nil if it could not be found
|
||||||
|
function SCENERY:FindByID(ID)
|
||||||
|
return _SCENERY[ID]
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Find a SCENERY object that was previously registered(!) by it's name.
|
||||||
|
-- @param #SCENERY self
|
||||||
|
-- @param #string Name
|
||||||
|
-- @return Wrapper.Scenery#SCENERY Scenery or nil if it could not be found
|
||||||
|
function SCENERY:_FindByName(Name)
|
||||||
|
for _id,_object in pairs(_SCENERY) do
|
||||||
|
if _object and _object.GetName and _object:GetName() then
|
||||||
|
local name = _object:GetName()
|
||||||
|
if Name == name then return _object end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
--- Find a SCENERY object from its name or id. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
|
--- Find a SCENERY object from its name or id. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
|
||||||
-- to find the correct object.
|
-- to find the correct object.
|
||||||
--@param #SCENERY self
|
--@param #SCENERY self
|
||||||
@@ -231,8 +362,8 @@ function SCENERY:FindByNameInZone(Name, Zone, Radius)
|
|||||||
if type(Zone) == "string" then
|
if type(Zone) == "string" then
|
||||||
Zone = ZONE:FindByName(Zone)
|
Zone = ZONE:FindByName(Zone)
|
||||||
end
|
end
|
||||||
local coordinate = Zone:GetCoordinate()
|
local coordinate = Zone:GetCoordinate():SetAlt()
|
||||||
return self:FindByName(Name,coordinate,Radius,Zone:GetProperty("ROLE"))
|
return self:FindByName(Name,coordinate,Radius,Zone:GetProperty("ROLE"),Zone)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Find a SCENERY object from its zone name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
|
--- Find a SCENERY object from its zone name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
|
||||||
@@ -241,14 +372,18 @@ end
|
|||||||
--@param #string ZoneName The name of the scenery zone as created with a right-click on the map in the mission editor and select "assigned to...". Can be handed over as ZONE object.
|
--@param #string ZoneName The name of the scenery zone as created with a right-click on the map in the mission editor and select "assigned to...". Can be handed over as ZONE object.
|
||||||
--@return #SCENERY First found Scenery Object or `nil` if it cannot be found
|
--@return #SCENERY First found Scenery Object or `nil` if it cannot be found
|
||||||
function SCENERY:FindByZoneName( ZoneName )
|
function SCENERY:FindByZoneName( ZoneName )
|
||||||
|
--BASE:I(ZoneName)
|
||||||
|
|
||||||
local zone = ZoneName -- Core.Zone#ZONE_BASE
|
local zone = ZoneName -- Core.Zone#ZONE_BASE
|
||||||
|
|
||||||
if type(ZoneName) == "string" then
|
if type(ZoneName) == "string" then
|
||||||
zone = ZONE:FindByName(ZoneName) -- Core.Zone#ZONE_POLYGON
|
zone = ZONE:FindByName(ZoneName) -- Core.Zone#ZONE_POLYGON
|
||||||
end
|
end
|
||||||
|
|
||||||
local _id = zone:GetProperty('OBJECT ID')
|
local _id = zone:GetProperty('OBJECT ID')
|
||||||
--local properties = zone:GetAllProperties() or {}
|
|
||||||
--BASE:I(string.format("Object ID is: %s",_id or "none"))
|
--BASE:I("Object ID ".._id)
|
||||||
--BASE:T("Object ID ".._id)
|
|
||||||
if not _id then
|
if not _id then
|
||||||
-- this zone has no object ID
|
-- this zone has no object ID
|
||||||
BASE:E("**** Zone without object ID: "..ZoneName.." | Type: "..tostring(zone.ClassName))
|
BASE:E("**** Zone without object ID: "..ZoneName.." | Type: "..tostring(zone.ClassName))
|
||||||
@@ -257,23 +392,27 @@ function SCENERY:FindByZoneName( ZoneName )
|
|||||||
local scanned = zone:GetScannedSceneryObjects()
|
local scanned = zone:GetScannedSceneryObjects()
|
||||||
for _,_scenery in (scanned) do
|
for _,_scenery in (scanned) do
|
||||||
local scenery = _scenery -- Wrapper.Scenery#SCENERY
|
local scenery = _scenery -- Wrapper.Scenery#SCENERY
|
||||||
if scenery:IsAlive() then
|
--if scenery:IsAlive() then
|
||||||
local role = zone:GetProperty("ROLE")
|
local role = zone:GetProperty("ROLE")
|
||||||
if role then scenery:SetProperty("ROLE",role) end
|
if role then scenery:SetProperty("ROLE",role) end
|
||||||
return scenery
|
return scenery
|
||||||
end
|
--end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
else
|
else
|
||||||
return self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE"))
|
local coordinate = zone:GetCoordinate()
|
||||||
|
coordinate:SetAlt()
|
||||||
|
return self:FindByName(_id, coordinate,nil,zone:GetProperty("ROLE"),zone)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
return self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE"))
|
local coordinate = zone:GetCoordinate()
|
||||||
|
coordinate:SetAlt()
|
||||||
|
return self:FindByName(_id, coordinate,nil,zone:GetProperty("ROLE"),zone)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Scan and find all SCENERY objects from a zone by zone-name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
|
--- Scan and find all SCENERY objects from a zone by zone-name. Since SCENERY isn't registered in the Moose database (just too many objects per map), we need to do a scan first
|
||||||
-- to find the correct object.
|
-- to find the correct object. Might return nil!
|
||||||
--@param #SCENERY self
|
--@param #SCENERY self
|
||||||
--@param #string ZoneName The name of the zone, can be handed as ZONE_RADIUS or ZONE_POLYGON object
|
--@param #string ZoneName The name of the zone, can be handed as ZONE_RADIUS or ZONE_POLYGON object
|
||||||
--@return #table of SCENERY Objects, or `nil` if nothing found
|
--@return #table of SCENERY Objects, or `nil` if nothing found
|
||||||
@@ -295,7 +434,7 @@ function SCENERY:FindAllByZoneName( ZoneName )
|
|||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
local obj = self:FindByName(_id, zone:GetCoordinate(),nil,zone:GetProperty("ROLE"))
|
local obj = self:FindByName(_id, zone:GetCoordinate():SetAlt(),nil,zone:GetProperty("ROLE"), zone)
|
||||||
if obj then
|
if obj then
|
||||||
return {obj}
|
return {obj}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -75,6 +75,7 @@ Functional/ZoneGoalCargo.lua
|
|||||||
Functional/Tiresias.lua
|
Functional/Tiresias.lua
|
||||||
Functional/Stratego.lua
|
Functional/Stratego.lua
|
||||||
Functional/ClientWatch.lua
|
Functional/ClientWatch.lua
|
||||||
|
Functional/Formation.lua
|
||||||
|
|
||||||
Ops/Airboss.lua
|
Ops/Airboss.lua
|
||||||
Ops/RecoveryTanker.lua
|
Ops/RecoveryTanker.lua
|
||||||
|
|||||||
Reference in New Issue
Block a user