Merge remote-tracking branch 'refs/remotes/origin/master' into master-bugfix

This commit is contained in:
FlightControl 2017-03-04 15:48:12 +01:00
commit bf5dce5b5f
201 changed files with 7996 additions and 1690 deletions

Binary file not shown.

View File

@ -1,4 +1,4 @@
--- Single-Player:**No** / Mulit-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**All** -- **AI Balancing will replace in multi player missions
--- Single-Player:**No** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**All** -- **AI Balancing will replace in multi player missions
-- non-occupied human slots with AI groups, in order to provide an engaging simulation environment,
-- even when there are hardly any players in the mission.**
--
@ -116,6 +116,7 @@ function AI_BALANCER:New( SetClient, SpawnAI )
-- Inherits from BASE
local self = BASE:Inherit( self, FSM_SET:New( SET_GROUP:New() ) ) -- AI.AI_Balancer#AI_BALANCER
-- TODO: Define the OnAfterSpawned event
self:SetStartState( "None" )
self:AddTransition( "*", "Monitor", "Monitoring" )
self:AddTransition( "*", "Spawn", "Spawning" )
@ -179,15 +180,17 @@ function AI_BALANCER:onenterSpawning( SetGroup, From, Event, To, ClientName )
-- OK, Spawn a new group from the default SpawnAI object provided.
local AIGroup = self.SpawnAI:Spawn() -- Wrapper.Group#GROUP
AIGroup:E( "Spawning new AIGroup" )
--TODO: need to rework UnitName thing ...
SetGroup:Add( ClientName, AIGroup )
self.SpawnQueue[ClientName] = nil
-- Fire the Spawned event. The first parameter is the AIGroup just Spawned.
-- Mission designers can catch this event to bind further actions to the AIGroup.
self:Spawned( AIGroup )
if AIGroup then
AIGroup:E( "Spawning new AIGroup" )
--TODO: need to rework UnitName thing ...
SetGroup:Add( ClientName, AIGroup )
self.SpawnQueue[ClientName] = nil
-- Fire the Spawned event. The first parameter is the AIGroup just Spawned.
-- Mission designers can catch this event to bind further actions to the AIGroup.
self:Spawned( AIGroup )
end
end
--- @param #AI_BALANCER self

View File

@ -1,4 +1,4 @@
--- Single-Player:**Yes** / Mulit-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** -- **Execute Combat Air Patrol (CAP).**
--- Single-Player:**Yes** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** -- **Execute Combat Air Patrol (CAP).**
--
-- ![Banner Image](..\Presentations\AI_CAP\Dia1.JPG)
--

View File

@ -1,4 +1,4 @@
--- Single-Player:**Yes** / Mulit-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** --
--- Single-Player:**Yes** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** --
-- **Provide Close Air Support to friendly ground troops.**
--
-- ![Banner Image](..\Presentations\AI_CAS\Dia1.JPG)

View File

@ -1,4 +1,4 @@
---Single-Player:**Yes** / Mulit-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Ground** --
---Single-Player:**Yes** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Ground** --
-- **Management of logical cargo objects, that can be transported from and to transportation carriers.**
--
-- ![Banner Image](..\Presentations\AI_CARGO\CARGO.JPG)

View File

@ -1,4 +1,4 @@
--- Single-Player:**Yes** / Mulit-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** --
--- Single-Player:**Yes** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**Air** --
-- **Air Patrolling or Staging.**
--
-- ![Banner Image](..\Presentations\AI_PATROL\Dia1.JPG)

View File

@ -127,14 +127,14 @@
-- **IMPORTANT NOTE:** Some events can involve not just UNIT objects, but also STATIC objects!!!
-- In that case the initiator or target unit fields will refer to a STATIC object!
-- In case a STATIC object is involved, the documentation indicates which fields will and won't not be populated.
-- The fields **IniCategory** and **TgtCategory** contain the indicator which **kind of object is involved** in the event.
-- You can use the enumerator **Object.Category.UNIT** and **Object.Category.STATIC** to check on IniCategory and TgtCategory.
-- The fields **IniObjectCategory** and **TgtObjectCategory** contain the indicator which **kind of object is involved** in the event.
-- You can use the enumerator **Object.Category.UNIT** and **Object.Category.STATIC** to check on IniObjectCategory and TgtObjectCategory.
-- Example code snippet:
--
-- if Event.IniCategory == Object.Category.UNIT then
-- if Event.IniObjectCategory == Object.Category.UNIT then
-- ...
-- end
-- if Event.IniCategory == Object.Category.STATIC then
-- if Event.IniObjectCategory == Object.Category.STATIC then
-- ...
-- end
--
@ -169,7 +169,7 @@
-- @module Event
-- TODO: Need to update the EVENTDATA documentation with IniPlayerName and TgtPlayerName
-- TODO: Need to update the EVENTDATA documentation with IniCategory and TgtCategory
-- TODO: Need to update the EVENTDATA documentation with IniObjectCategory and TgtObjectCategory
@ -220,8 +220,8 @@ EVENTS = {
-- @type EVENTDATA
-- @field #number id The identifier of the event.
--
-- @field Dcs.DCSUnit#Unit initiator (UNIT/STATIC) The initiating @{Dcs.DCSUnit#Unit} or @{Dcs.DCSStaticObject#StaticObject}.
-- @field Dcs.DCSObject#Object.Category IniCategory (UNIT/STATIC) The initiator object category ( Object.Category.UNIT or Object.Category.STATIC ).
-- @field Dcs.DCSUnit#Unit initiator (UNIT/STATIC/SCENERY) The initiating @{Dcs.DCSUnit#Unit} or @{Dcs.DCSStaticObject#StaticObject}.
-- @field Dcs.DCSObject#Object.Category IniObjectCategory (UNIT/STATIC/SCENERY) The initiator object category ( Object.Category.UNIT or Object.Category.STATIC ).
-- @field Dcs.DCSUnit#Unit IniDCSUnit (UNIT/STATIC) The initiating @{Dcs.DCSUnit#Unit} or @{Dcs.DCSStaticObject#StaticObject}.
-- @field #string IniDCSUnitName (UNIT/STATIC) The initiating Unit name.
-- @field Wrapper.Unit#UNIT IniUnit (UNIT/STATIC) The initiating MOOSE wrapper @{Wrapper.Unit#UNIT} of the initiator Unit object.
@ -231,9 +231,12 @@ EVENTS = {
-- @field Wrapper.Group#GROUP IniGroup (UNIT) The initiating MOOSE wrapper @{Wrapper.Group#GROUP} of the initiator Group object.
-- @field #string IniGroupName (UNIT) The initiating GROUP name (same as IniDCSGroupName).
-- @field #string IniPlayerName (UNIT) The name of the initiating player in case the Unit is a client or player slot.
-- @field Dcs.DCScoalition#coalition.side IniCoalition (UNIT) The coalition of the initiator.
-- @field Dcs.DCSUnit#Unit.Category IniCategory (UNIT) The category of the initiator.
-- @field #string IniTypeName (UNIT) The type name of the initiator.
--
-- @field Dcs.DCSUnit#Unit target (UNIT/STATIC) The target @{Dcs.DCSUnit#Unit} or @{Dcs.DCSStaticObject#StaticObject}.
-- @field Dcs.DCSObject#Object.Category TgtCategory (UNIT/STATIC) The target object category ( Object.Category.UNIT or Object.Category.STATIC ).
-- @field Dcs.DCSObject#Object.Category TgtObjectCategory (UNIT/STATIC) The target object category ( Object.Category.UNIT or Object.Category.STATIC ).
-- @field Dcs.DCSUnit#Unit TgtDCSUnit (UNIT/STATIC) The target @{Dcs.DCSUnit#Unit} or @{Dcs.DCSStaticObject#StaticObject}.
-- @field #string TgtDCSUnitName (UNIT/STATIC) The target Unit name.
-- @field Wrapper.Unit#UNIT TgtUnit (UNIT/STATIC) The target MOOSE wrapper @{Wrapper.Unit#UNIT} of the target Unit object.
@ -243,6 +246,9 @@ EVENTS = {
-- @field Wrapper.Group#GROUP TgtGroup (UNIT) The target MOOSE wrapper @{Wrapper.Group#GROUP} of the target Group object.
-- @field #string TgtGroupName (UNIT) The target GROUP name (same as TgtDCSGroupName).
-- @field #string TgtPlayerName (UNIT) The name of the target player in case the Unit is a client or player slot.
-- @field Dcs.DCScoalition#coalition.side TgtCoalition (UNIT) The coalition of the target.
-- @field Dcs.DCSUnit#Unit.Category TgtCategory (UNIT) The category of the target.
-- @field #string TgtTypeName (UNIT) The type name of the target.
--
-- @field weapon The weapon used during the event.
-- @field Weapon
@ -1050,8 +1056,10 @@ function EVENT:onEvent( Event )
if Event.initiator then
Event.IniCategory = Event.initiator:getCategory()
if Event.IniCategory == Object.Category.UNIT then
Event.IniObjectCategory = Event.initiator:getCategory()
if Event.IniObjectCategory == Object.Category.UNIT then
Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName
@ -1068,19 +1076,36 @@ function EVENT:onEvent( Event )
self:E( { IniGroup = Event.IniGroup } )
end
Event.IniPlayerName = Event.IniDCSUnit:getPlayerName()
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
Event.IniCategory = Event.IniDCSUnit:getDesc().category
end
if Event.IniCategory == Object.Category.STATIC then
if Event.IniObjectCategory == Object.Category.STATIC then
Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName
Event.IniUnit = STATIC:FindByName( Event.IniDCSUnitName )
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
Event.IniCategory = Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
end
if Event.IniObjectCategory == Object.Category.SCENERY then
Event.IniDCSUnit = Event.initiator
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
Event.IniUnitName = Event.IniDCSUnitName
Event.IniUnit = SCENERY:Register( Event.IniDCSUnitName, Event.initiator )
Event.IniCategory = Event.IniDCSUnit:getDesc().category
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
end
end
if Event.target then
Event.TgtCategory = Event.target:getCategory()
if Event.TgtCategory == Object.Category.UNIT then
Event.TgtObjectCategory = Event.target:getCategory()
if Event.TgtObjectCategory == Object.Category.UNIT then
Event.TgtDCSUnit = Event.target
Event.TgtDCSGroup = Event.TgtDCSUnit:getGroup()
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
@ -1091,18 +1116,31 @@ function EVENT:onEvent( Event )
Event.TgtDCSGroupName = Event.TgtDCSGroup:getName()
end
Event.TgtPlayerName = Event.TgtDCSUnit:getPlayerName()
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
end
if Event.TgtCategory == Object.Category.STATIC then
if Event.TgtObjectCategory == Object.Category.STATIC then
Event.TgtDCSUnit = Event.target
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
Event.TgtUnitName = Event.TgtDCSUnitName
Event.TgtUnit = STATIC:FindByName( Event.TgtDCSUnitName )
Event.TgtCoalition = Event.TgtDCSUnit:getCoalition()
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
end
if Event.TgtObjectCategory == Object.Category.SCENERY then
Event.TgtDCSUnit = Event.target
Event.TgtDCSUnitName = Event.TgtDCSUnit:getName()
Event.TgtUnitName = Event.TgtDCSUnitName
Event.TgtUnit = SCENERY:Register( Event.TgtDCSUnitName, Event.target )
Event.TgtCategory = Event.TgtDCSUnit:getDesc().category
Event.TgtTypeName = Event.TgtDCSUnit:getTypeName()
end
end
if Event.weapon then
Event.Weapon = Event.weapon
Event.WeaponName = Event.Weapon:getTypeName()

View File

@ -182,6 +182,20 @@ function MESSAGE:ToCoalition( CoalitionSide )
return self
end
--- Sends a MESSAGE to a Coalition if the given Condition is true.
-- @param #MESSAGE self
-- @param CoalitionSide needs to be filled out by the defined structure of the standard scripting engine @{coalition.side}.
-- @return #MESSAGE
function MESSAGE:ToCoalitionIf( CoalitionSide, Condition )
self:F( CoalitionSide )
if Condition and Condition == true then
self:ToCoalition( CoalitionSide )
end
return self
end
--- Sends a MESSAGE to all players.
-- @param #MESSAGE self
-- @return #MESSAGE
@ -194,10 +208,24 @@ end
-- MessageAll = MESSAGE:New( "To all Players: BLUE has won! Each player of BLUE wins 50 points!", "End of Mission", 25, "Win" )
-- MessageAll:ToAll()
function MESSAGE:ToAll()
self:F()
self:F()
self:ToCoalition( coalition.side.RED )
self:ToCoalition( coalition.side.BLUE )
self:ToCoalition( coalition.side.RED )
self:ToCoalition( coalition.side.BLUE )
return self
end
--- Sends a MESSAGE to all players if the given Condition is true.
-- @param #MESSAGE self
-- @return #MESSAGE
function MESSAGE:ToAllIf( Condition )
if Condition and Condition == true then
self:ToCoalition( coalition.side.RED )
self:ToCoalition( coalition.side.BLUE )
end
return self
end

View File

@ -7,13 +7,56 @@
-- **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 of the MIST framework was created by Grimes, who you can find on the Eagle Dynamics Forums.
--
-- 1.1) POINT_VEC3 constructor
-- ---------------------------
-- ## 1.1) POINT_VEC3 constructor
--
-- A new POINT_VEC3 instance can be created with:
--
-- * @{Point#POINT_VEC3.New}(): a 3D point.
-- * @{Point#POINT_VEC3.NewFromVec3}(): a 3D point created from a @{DCSTypes#Vec3}.
--
--
-- ## 1.2) Manupulate the X, Y, Z coordinates of the point
--
-- 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()
--
--
-- ## 1.5) Smoke, flare, explode, illuminate
--
-- At the point a smoke, flare, explosion and illumination bomb can be triggered. Use the following methods:
--
-- ### 1.5.1) Smoke
--
-- * @{#POINT_VEC3.Smoke}(): To smoke the point in a certain color.
-- * @{#POINT_VEC3.SmokeBlue}(): To smoke the point in blue.
-- * @{#POINT_VEC3.SmokeRed}(): To smoke the point in red.
-- * @{#POINT_VEC3.SmokeOrange}(): To smoke the point in orange.
-- * @{#POINT_VEC3.SmokeWhite}(): To smoke the point in white.
-- * @{#POINT_VEC3.SmokeGreen}(): To smoke the point in green.
--
-- ### 1.5.2) Flare
--
-- * @{#POINT_VEC3.Flare}(): To flare the point in a certain color.
-- * @{#POINT_VEC3.FlareRed}(): To flare the point in red.
-- * @{#POINT_VEC3.FlareYellow}(): To flare the point in yellow.
-- * @{#POINT_VEC3.FlareWhite}(): To flare the point in white.
-- * @{#POINT_VEC3.FlareGreen}(): To flare the point in green.
--
-- ### 1.5.3) Explode
--
-- * @{#POINT_VEC3.Explosion}(): To explode the point with a certain intensity.
--
-- ### 1.5.4) Illuminate
--
-- * @{#POINT_VEC3.IlluminationBomb}(): To illuminate the point.
--
--
-- 2) @{Point#POINT_VEC2} class, extends @{Point#POINT_VEC3}
-- =========================================================
@ -26,6 +69,19 @@
-- * @{Point#POINT_VEC2.New}(): a 2D point, taking an additional height parameter.
-- * @{Point#POINT_VEC2.NewFromVec2}(): a 2D point created from a @{DCSTypes#Vec2}.
--
-- ## 1.2) 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 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()
--
-- ===
--
-- **API CHANGE HISTORY**
@ -38,9 +94,12 @@
--
-- Hereby the change log:
--
-- 2017-02-18: POINT_VEC3:**NewFromVec2( Vec2, LandHeightAdd )** added.
-- 2017-03-03: POINT\_VEC3:**Explosion( ExplosionIntensity )** added.
-- 2017-03-03: POINT\_VEC3:**IlluminationBomb()** added.
--
-- 2016-08-12: POINT_VEC3:**Translate( Distance, Angle )** added.
-- 2017-02-18: POINT\_VEC3:**NewFromVec2( Vec2, LandHeightAdd )** added.
--
-- 2016-08-12: POINT\_VEC3:**Translate( Distance, Angle )** added.
--
-- 2016-08-06: Made PointVec3 and Vec3, PointVec2 and Vec2 terminology used in the code consistent.
--
@ -196,21 +255,57 @@ function POINT_VEC3:GetZ()
end
--- Set the x coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number x The x coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:SetX( x )
self.x = x
return self
end
--- Set the y coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number y The y coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:SetY( y )
self.y = y
return self
end
--- Set the z coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number z The z coordinate.
-- @return #POINT_VEC3
function POINT_VEC3:SetZ( z )
self.z = z
return self
end
--- Add to the x coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number x The x coordinate value to add to the current x coodinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddX( x )
self.x = self.x + x
return self
end
--- Add to the y coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number y The y coordinate value to add to the current y coodinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddY( y )
self.y = self.y + y
return self
end
--- Add to the z coordinate of the POINT_VEC3.
-- @param #POINT_VEC3 self
-- @param #number z The z coordinate value to add to the current z coodinate.
-- @return #POINT_VEC3
function POINT_VEC3:AddZ( z )
self.z = self.z +z
return self
end
--- Return a random Vec2 within an Outer Radius and optionally NOT within an Inner Radius of the POINT_VEC3.
@ -501,6 +596,21 @@ function POINT_VEC3:RoutePointGround( Speed, Formation )
return RoutePoint
end
--- Creates an explosion at the point of a certain intensity.
-- @param #POINT_VEC3 self
-- @param #number ExplosionIntensity
function POINT_VEC3:Explosion( ExplosionIntensity )
self:F2( { ExplosionIntensity } )
trigger.action.explosion( self:GetVec3(), ExplosionIntensity )
end
--- Creates an illumination bomb at the point.
-- @param #POINT_VEC3 self
function POINT_VEC3:IlluminationBomb()
self:F2()
trigger.action.illuminationBomb( self:GetVec3() )
end
--- Smokes the point in a color.
-- @param #POINT_VEC3 self
@ -666,15 +776,57 @@ function POINT_VEC2:GetAlt()
end
--- Set the x coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number x The x coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:SetX( x )
self.x = x
return self
end
--- Set the y coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number y The y coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:SetY( y )
self.z = y
return self
end
--- Set the altitude of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number Altitude The land altitude. If nothing (nil) is given, then the current land altitude is set.
-- @return #POINT_VEC2
function POINT_VEC2:SetAlt( Altitude )
self.y = Altitude or land.getHeight( { x = self.x, y = self.z } )
return self
end
--- Add to the x coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number x The x coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:AddX( x )
self.x = self.x + x
return self
end
--- Add to the y coordinate of the POINT_VEC2.
-- @param #POINT_VEC2 self
-- @param #number y The y coordinate.
-- @return #POINT_VEC2
function POINT_VEC2:AddY( y )
self.z = self.z + y
return self
end
--- Add to the current land height an altitude.
-- @param #POINT_VEC2 self
-- @param #number Altitude The Altitude to add. If nothing (nil) is given, then the current land altitude is set.
-- @return #POINT_VEC2
function POINT_VEC2:AddAlt( Altitude )
self.y = land.getHeight( { x = self.x, y = self.z } ) + Altitude or 0
return self
end

View File

@ -64,7 +64,7 @@ function SCHEDULEDISPATCHER:AddSchedule( Scheduler, ScheduleFunction, ScheduleAr
-- Initialize the ObjectSchedulers array, which is a weakly coupled table.
-- If the object used as the key is nil, then the garbage collector will remove the item from the Functions array.
self.ObjectSchedulers = self.ObjectSchedulers or setmetatable( {}, { __mode = "v" } )
self.ObjectSchedulers = self.ObjectSchedulers or {} -- setmetatable( {}, { __mode = "v" } )
if Scheduler.MasterObject then
self.ObjectSchedulers[self.CallID] = Scheduler

View File

@ -35,8 +35,8 @@
--
-- ## 1.2) Each zone implements two polymorphic functions defined in @{Zone#ZONE_BASE}:
--
-- * @{#ZONE_BASE.IsPointVec2InZone}(): Returns if a @{Point#POINT_VEC2} is within the zone.
-- * @{#ZONE_BASE.IsPointVec3InZone}(): Returns if a @{Point#POINT_VEC3} is within the zone.
-- * @{#ZONE_BASE.IsVec2InZone}(): Returns if a Vec2 is within the zone.
-- * @{#ZONE_BASE.IsVec3InZone}(): Returns if a Vec3 is within the zone.
--
-- ## 1.3) A zone has a probability factor that can be set to randomize a selection between zones:
--
@ -145,21 +145,28 @@
--
-- Hereby the change log:
--
-- 2017-02-18: ZONE_POLYGON_BASE:**GetRandomPointVec2()** added.
-- 2017-02-28: ZONE\_BASE:**IsVec2InZone()** replaces ZONE\_BASE:_IsPointVec2InZone()_.
-- 2017-02-28: ZONE\_BASE:**IsVec3InZone()** replaces ZONE\_BASE:_IsPointVec3InZone()_.
-- 2017-02-28: ZONE\_RADIUS:**IsVec2InZone()** replaces ZONE\_RADIUS:_IsPointVec2InZone()_.
-- 2017-02-28: ZONE\_RADIUS:**IsVec3InZone()** replaces ZONE\_RADIUS:_IsPointVec3InZone()_.
-- 2017-02-28: ZONE\_POLYGON:**IsVec2InZone()** replaces ZONE\_POLYGON:_IsPointVec2InZone()_.
-- 2017-02-28: ZONE\_POLYGON:**IsVec3InZone()** replaces ZONE\_POLYGON:_IsPointVec3InZone()_.
--
-- 2017-02-18: ZONE_POLYGON_BASE:**GetRandomPointVec3()** added.
-- 2017-02-18: ZONE\_POLYGON_BASE:**GetRandomPointVec2()** added.
--
-- 2017-02-18: ZONE_RADIUS:**GetRandomPointVec3( inner, outer )** added.
-- 2017-02-18: ZONE\_POLYGON_BASE:**GetRandomPointVec3()** added.
--
-- 2017-02-18: ZONE_RADIUS:**GetRandomPointVec2( inner, outer )** added.
-- 2017-02-18: ZONE\_RADIUS:**GetRandomPointVec3( inner, outer )** added.
--
-- 2016-08-15: ZONE_BASE:**GetName()** added.
-- 2017-02-18: ZONE\_RADIUS:**GetRandomPointVec2( inner, outer )** added.
--
-- 2016-08-15: ZONE_BASE:**SetZoneProbability( ZoneProbability )** added.
-- 2016-08-15: ZONE\_BASE:**GetName()** added.
--
-- 2016-08-15: ZONE_BASE:**GetZoneProbability()** added.
-- 2016-08-15: ZONE\_BASE:**SetZoneProbability( ZoneProbability )** added.
--
-- 2016-08-15: ZONE_BASE:**GetZoneMaybe()** added.
-- 2016-08-15: ZONE\_BASE:**GetZoneProbability()** added.
--
-- 2016-08-15: ZONE\_BASE:**GetZoneMaybe()** added.
--
-- ===
--
@ -212,7 +219,7 @@ end
-- @param #ZONE_BASE self
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.
-- @return #boolean true if the location is within the zone.
function ZONE_BASE:IsPointVec2InZone( Vec2 )
function ZONE_BASE:IsVec2InZone( Vec2 )
self:F2( Vec2 )
return false
@ -222,10 +229,10 @@ end
-- @param #ZONE_BASE self
-- @param Dcs.DCSTypes#Vec3 Vec3 The point to test.
-- @return #boolean true if the point is within the zone.
function ZONE_BASE:IsPointVec3InZone( Vec3 )
function ZONE_BASE:IsVec3InZone( Vec3 )
self:F2( Vec3 )
local InZone = self:IsPointVec2InZone( { x = Vec3.x, y = Vec3.z } )
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
return InZone
end
@ -455,7 +462,7 @@ end
-- @param #ZONE_RADIUS self
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.
-- @return #boolean true if the location is within the zone.
function ZONE_RADIUS:IsPointVec2InZone( Vec2 )
function ZONE_RADIUS:IsVec2InZone( Vec2 )
self:F2( Vec2 )
local ZoneVec2 = self:GetVec2()
@ -473,10 +480,10 @@ end
-- @param #ZONE_RADIUS self
-- @param Dcs.DCSTypes#Vec3 Vec3 The point to test.
-- @return #boolean true if the point is within the zone.
function ZONE_RADIUS:IsPointVec3InZone( Vec3 )
function ZONE_RADIUS:IsVec3InZone( Vec3 )
self:F2( Vec3 )
local InZone = self:IsPointVec2InZone( { x = Vec3.x, y = Vec3.z } )
local InZone = self:IsVec2InZone( { x = Vec3.x, y = Vec3.z } )
return InZone
end
@ -795,7 +802,7 @@ end
-- @param #ZONE_POLYGON_BASE self
-- @param Dcs.DCSTypes#Vec2 Vec2 The location to test.
-- @return #boolean true if the location is within the zone.
function ZONE_POLYGON_BASE:IsPointVec2InZone( Vec2 )
function ZONE_POLYGON_BASE:IsVec2InZone( Vec2 )
self:F2( Vec2 )
local Next
@ -837,7 +844,7 @@ function ZONE_POLYGON_BASE:GetRandomVec2()
while Vec2Found == false do
Vec2 = { x = math.random( BS.x1, BS.x2 ), y = math.random( BS.y1, BS.y2 ) }
self:T2( Vec2 )
if self:IsPointVec2InZone( Vec2 ) then
if self:IsVec2InZone( Vec2 ) then
Vec2Found = true
end
end

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
--- Single-Player:**Yes** / Mulit-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**All** --
--- Single-Player:**Yes** / Multi-Player:**Yes** / AI:**Yes** / Human:**No** / Types:**All** --
-- **Spawn groups of units dynamically in your missions.**
--
-- ![Banner Image](..\Presentations\SPAWN\SPAWN.JPG)
@ -1304,10 +1304,12 @@ function SPAWN:_RandomizeTemplate( SpawnIndex )
self.SpawnGroups[SpawnIndex].SpawnTemplate.x = self.SpawnTemplate.x
self.SpawnGroups[SpawnIndex].SpawnTemplate.y = self.SpawnTemplate.y
self.SpawnGroups[SpawnIndex].SpawnTemplate.start_time = self.SpawnTemplate.start_time
local OldX = self.SpawnGroups[SpawnIndex].SpawnTemplate.units[1].x
local OldY = self.SpawnGroups[SpawnIndex].SpawnTemplate.units[1].y
for UnitID = 1, #self.SpawnGroups[SpawnIndex].SpawnTemplate.units do
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].heading = self.SpawnTemplate.units[1].heading
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].x = self.SpawnTemplate.units[1].x
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].y = self.SpawnTemplate.units[1].y
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].x = self.SpawnTemplate.units[1].x + ( self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].x - OldX )
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].y = self.SpawnTemplate.units[1].y + ( self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].y - OldY )
self.SpawnGroups[SpawnIndex].SpawnTemplate.units[UnitID].alt = self.SpawnTemplate.units[1].alt
end
end

View File

@ -27,6 +27,7 @@ Include.File( "Wrapper/Unit" )
Include.File( "Wrapper/Client" )
Include.File( "Wrapper/Static" )
Include.File( "Wrapper/Airbase" )
Include.File( "Wrapper/Scenery" )
--- Functional Classes
Include.File( "Functional/Scoring" )

View File

@ -14,6 +14,7 @@
-- * @{#TASK.HasStateMachine}():Enquire if the task has a @{Fsm}
-- * @{#TASK.AssignToUnit}(): Assign a task to a unit. (Needs to be implemented in the derived classes from @{#TASK}.
-- * @{#TASK.UnAssignFromUnit}(): Unassign the task from a unit.
-- * @{#TASK.SetTimeOut}(): Set timer in seconds before task gets cancelled if not assigned.
--
-- 1.2) Set and enquire task status (beyond the task state machine processing).
-- ----------------------------------------------------------------------------
@ -70,6 +71,7 @@ TASK = {
FsmTemplate = nil,
Mission = nil,
CommandCenter = nil,
TimeOut = 0,
}
--- FSM PlayerAborted event handler prototype for TASK.
@ -163,6 +165,7 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType )
self:AddTransition( "*", "PlayerAborted", "*" )
self:AddTransition( "*", "PlayerDead", "*" )
self:AddTransition( { "Failed", "Aborted", "Cancelled" }, "Replan", "Planned" )
self:AddTransition( "*", "TimeOut", "Cancelled" )
self:E( "New TASK " .. TaskName )
@ -404,6 +407,17 @@ function TASK:UnAssignFromUnit( TaskUnit )
return self
end
--- Sets the TimeOut for the @{Task}. If @{Task} stayed planned for longer than TimeOut, it gets into Cancelled status.
-- @param #TASK self
-- @param #integer Timer in seconds
-- @return #TASK self
function TASK:SetTimeOut ( Timer )
self:F( Timer )
self.TimeOut = Timer
self:__TimeOut( self.TimeOut )
return self
end
--- Send a message of the @{Task} to the assigned @{Group}s.
-- @param #TASK self
function TASK:MessageToGroups( Message )
@ -935,6 +949,30 @@ function TASK:onstatechange( From, Event, To )
end
--- FSM function for a TASK
-- @param #TASK self
-- @param #string Event
-- @param #string From
-- @param #string To
function TASK:onenterPlanned( From, Event, To)
if not self.TimeOut == 0 then
self.__TimeOut( self.TimeOut )
end
end
--- FSM function for a TASK
-- @param #TASK self
-- @param #string Event
-- @param #string From
-- @param #string To
function TASK:onbeforeTimeOut( From, Event, To )
if From == "Planned" then
self:RemoveMenu()
return true
end
return false
end
do -- Reporting
--- Create a summary report of the Task.

View File

@ -455,8 +455,7 @@ function GROUP:IsCompletelyInZone( Zone )
for UnitID, UnitData in pairs( self:GetUnits() ) do
local Unit = UnitData -- Wrapper.Unit#UNIT
-- TODO: Rename IsPointVec3InZone to IsVec3InZone
if Zone:IsPointVec3InZone( Unit:GetVec3() ) then
if Zone:IsVec3InZone( Unit:GetVec3() ) then
else
return false
end
@ -474,7 +473,7 @@ function GROUP:IsPartlyInZone( Zone )
for UnitID, UnitData in pairs( self:GetUnits() ) do
local Unit = UnitData -- Wrapper.Unit#UNIT
if Zone:IsPointVec3InZone( Unit:GetVec3() ) then
if Zone:IsVec3InZone( Unit:GetVec3() ) then
return true
end
end
@ -491,7 +490,7 @@ function GROUP:IsNotInZone( Zone )
for UnitID, UnitData in pairs( self:GetUnits() ) do
local Unit = UnitData -- Wrapper.Unit#UNIT
if Zone:IsPointVec3InZone( Unit:GetVec3() ) then
if Zone:IsVec3InZone( Unit:GetVec3() ) then
return false
end
end

View File

@ -217,10 +217,7 @@ function IDENTIFIABLE:GetCallsign()
end
function IDENTIFIABLE:GetThreatLevel()
return 0, "Scenery"
end

View File

@ -0,0 +1,39 @@
--- This module contains the SCENERY class.
--
-- 1) @{Scenery#SCENERY} class, extends @{Positionable#POSITIONABLE}
-- ===============================================================
-- Scenery objects are defined on the map.
-- The @{Scenery#SCENERY} class is a wrapper class to handle the DCS Scenery objects:
--
-- * Wraps the DCS Scenery objects.
-- * Support all DCS Scenery APIs.
-- * Enhance with Scenery specific APIs not in the DCS API set.
--
-- @module Scenery
-- @author FlightControl
--- The SCENERY class
-- @type SCENERY
-- @extends Wrapper.Positionable#POSITIONABLE
SCENERY = {
ClassName = "SCENERY",
}
function SCENERY:Register( SceneryName, SceneryObject )
local self = BASE:Inherit( self, POSITIONABLE:New( SceneryName ) )
self.SceneryName = SceneryName
self.SceneryObject = SceneryObject
return self
end
function SCENERY:GetDCSObject()
return self.SceneryObject
end
function SCENERY:GetThreatLevel()
return 0, "Scenery"
end

View File

@ -79,3 +79,8 @@ function STATIC:GetDCSObject()
return nil
end
function STATIC:GetThreatLevel()
return 1, "Static"
end

View File

@ -536,45 +536,129 @@ end
-- * Threat level 8: Unit is a Short Range SAM, radar guided.
-- * Threat level 9: Unit is a Medium Range SAM, radar guided.
-- * Threat level 10: Unit is a Long Range SAM, radar guided.
-- @param #UNIT self
function UNIT:GetThreatLevel()
local Attributes = self:GetDesc().attributes
self:E( Attributes )
local ThreatLevel = 0
local ThreatText = ""
if self:IsGround() then
local ThreatLevels = {
"Unarmed",
"Infantry",
"Old Tanks & APCs",
"Tanks & IFVs without ATGM",
"Tanks & IFV with ATGM",
"Modern Tanks",
"AAA",
"IR Guided SAMs",
"SR SAMs",
"MR SAMs",
"LR SAMs"
}
self:E( "Ground" )
self:T2( Attributes )
local ThreatLevels = {
"Unarmed",
"Infantry",
"Old Tanks & APCs",
"Tanks & IFVs without ATGM",
"Tanks & IFV with ATGM",
"Modern Tanks",
"AAA",
"IR Guided SAMs",
"SR SAMs",
"MR SAMs",
"LR SAMs"
}
if Attributes["LR SAM"] then ThreatLevel = 10
elseif Attributes["MR SAM"] then ThreatLevel = 9
elseif Attributes["SR SAM"] and
not Attributes["IR Guided SAM"] then ThreatLevel = 8
elseif ( Attributes["SR SAM"] or Attributes["MANPADS"] ) and
Attributes["IR Guided SAM"] then ThreatLevel = 7
elseif Attributes["AAA"] then ThreatLevel = 6
elseif Attributes["Modern Tanks"] then ThreatLevel = 5
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
Attributes["ATGM"] then ThreatLevel = 4
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
not Attributes["ATGM"] then ThreatLevel = 3
elseif Attributes["Old Tanks"] or Attributes["APC"] or Attributes["Artillery"] then ThreatLevel = 2
elseif Attributes["Infantry"] then ThreatLevel = 1
end
ThreatText = ThreatLevels[ThreatLevel+1]
end
if Attributes["LR SAM"] then ThreatLevel = 10
elseif Attributes["MR SAM"] then ThreatLevel = 9
elseif Attributes["SR SAM"] and
not Attributes["IR Guided SAM"] then ThreatLevel = 8
elseif ( Attributes["SR SAM"] or Attributes["MANPADS"] ) and
Attributes["IR Guided SAM"] then ThreatLevel = 7
elseif Attributes["AAA"] then ThreatLevel = 6
elseif Attributes["Modern Tanks"] then ThreatLevel = 5
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
Attributes["ATGM"] then ThreatLevel = 4
elseif ( Attributes["Tanks"] or Attributes["IFV"] ) and
not Attributes["ATGM"] then ThreatLevel = 3
elseif Attributes["Old Tanks"] or Attributes["APC"] then ThreatLevel = 2
elseif Attributes["Infantry"] then ThreatLevel = 1
if self:IsAir() then
self:E( "Air" )
local ThreatLevels = {
"Unarmed",
"Tanker",
"AWACS",
"Transport Helicpter",
"UAV",
"Bomber",
"Strategic Bomber",
"Attack Helicopter",
"Interceptor",
"Multirole Fighter",
"Fighter"
}
if Attributes["Fighters"] then ThreatLevel = 10
elseif Attributes["Multirole fighters"] then ThreatLevel = 9
elseif Attributes["Battleplanes"] then ThreatLevel = 8
elseif Attributes["Attack helicopters"] then ThreatLevel = 7
elseif Attributes["Strategic bombers"] then ThreatLevel = 6
elseif Attributes["Bombers"] then ThreatLevel = 5
elseif Attributes["UAVs"] then ThreatLevel = 4
elseif Attributes["Transport helicopters"] then ThreatLevel = 3
elseif Attributes["AWACS"] then ThreatLevel = 2
elseif Attributes["Tankers"] then ThreatLevel = 1
end
ThreatText = ThreatLevels[ThreatLevel+1]
end
if self:IsShip() then
self:E( "Ship" )
--["Aircraft Carriers"] = {"Heavy armed ships",},
--["Cruisers"] = {"Heavy armed ships",},
--["Destroyers"] = {"Heavy armed ships",},
--["Frigates"] = {"Heavy armed ships",},
--["Corvettes"] = {"Heavy armed ships",},
--["Heavy armed ships"] = {"Armed ships", "Armed Air Defence", "HeavyArmoredUnits",},
--["Light armed ships"] = {"Armed ships","NonArmoredUnits"},
--["Armed ships"] = {"Ships"},
--["Unarmed ships"] = {"Ships","HeavyArmoredUnits",},
local ThreatLevels = {
"Unarmed ship",
"Light armed ships",
"Corvettes",
"",
"Frigates",
"",
"Cruiser",
"",
"Destroyer",
"",
"Aircraft Carrier"
}
if Attributes["Aircraft Carriers"] then ThreatLevel = 10
elseif Attributes["Destroyers"] then ThreatLevel = 8
elseif Attributes["Cruisers"] then ThreatLevel = 6
elseif Attributes["Frigates"] then ThreatLevel = 4
elseif Attributes["Corvettes"] then ThreatLevel = 2
elseif Attributes["Light armed ships"] then ThreatLevel = 1
end
ThreatText = ThreatLevels[ThreatLevel+1]
end
self:T2( ThreatLevel )
return ThreatLevel, ThreatLevels[ThreatLevel+1]
return ThreatLevel, ThreatText
end
@ -589,7 +673,7 @@ function UNIT:IsInZone( Zone )
self:F2( { self.UnitName, Zone } )
if self:IsAlive() then
local IsInZone = Zone:IsPointVec3InZone( self:GetVec3() )
local IsInZone = Zone:IsVec3InZone( self:GetVec3() )
self:T( { IsInZone } )
return IsInZone
@ -606,7 +690,7 @@ function UNIT:IsNotInZone( Zone )
self:F2( { self.UnitName, Zone } )
if self:IsAlive() then
local IsInZone = not Zone:IsPointVec3InZone( self:GetVec3() )
local IsInZone = not Zone:IsVec3InZone( self:GetVec3() )
self:T( { IsInZone } )
return IsInZone

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -65,6 +65,7 @@ COPY /b Moose.lua + %1\Wrapper\Unit.lua Moose.lua
COPY /b Moose.lua + %1\Wrapper\Client.lua Moose.lua
COPY /b Moose.lua + %1\Wrapper\Static.lua Moose.lua
COPY /b Moose.lua + %1\Wrapper\Airbase.lua Moose.lua
COPY /b Moose.lua + %1\Wrapper\Scenery.lua Moose.lua
rem Functional Classes
COPY /b Moose.lua + %1\Functional\Scoring.lua Moose.lua

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 254 KiB

View File

@ -14,8 +14,25 @@
local HQ = GROUP:FindByName( "HQ", "Bravo HQ" )
local CommandCenter = COMMANDCENTER:New( HQ, "Lima" )
local CommandCenter = COMMANDCENTER:New( HQ, "Bravo" )
local Scoring = SCORING:New( "Detect Demo" )
local Scoring = SCORING:New( "Shooting Range 1" )
Scoring:SetMultiplierDestroyScore( 10 )
Scoring:SetMultiplierDestroyPenalty( 40 )
Scoring:AddUnitScore( UNIT:FindByName( "Unit #001" ), 200 )
-- Test for zone scores.
-- This one is to test scoring on normal units.
local ShootingRangeZone = ZONE:New( "ScoringZone1" )
Scoring:AddZoneScore( ShootingRangeZone, 200 )
-- This one is to test scoring on scenery.
-- Note that you can only destroy scenery with heavy weapons.
local SceneryZone = ZONE:New( "ScoringZone2" )
Scoring:AddZoneScore( SceneryZone, 200 )

View File

@ -0,0 +1,21 @@
---
-- Name: SCO-101 - Scoring Client to Client
-- Author: FlightControl
-- Date Created: 24 Feb 2017
--
-- # Situation:
--
-- A shooting range has been setup to test client to client scoring.
--
-- # Test cases:
--
-- 1. Observe the scoring granted to your flight when you hit and kill other clients.
local HQ = GROUP:FindByName( "HQ", "Bravo HQ" )
local CommandCenter = COMMANDCENTER:New( HQ, "Lima" )
local Scoring = SCORING:New( "Detect Demo" )

Some files were not shown because too many files have changed in this diff Show More