Merge branch 'master' into funkyfranky

This commit is contained in:
funkyfranky
2017-09-22 19:03:04 +02:00
30 changed files with 817 additions and 139 deletions

View File

@@ -248,6 +248,7 @@ function AI_A2A:New( AIGroup )
-- @param #AI_A2A self
-- @param #number Delay
self:AddTransition( "*", "Takeoff", "Airborne" )
self:AddTransition( "*", "Return", "Returning" )
self:AddTransition( "*", "Hold", "Holding" )
self:AddTransition( "*", "Home", "Home" )
@@ -263,6 +264,13 @@ function AI_A2A:New( AIGroup )
return self
end
--- @param Wrapper.Group#GROUP self
-- @param Core.Event#EVENTDATA EventData
function GROUP:OnEventTakeoff( EventData, Fsm )
Fsm:Takeoff()
self:UnHandleEvent( EVENTS.Takeoff )
end
function AI_A2A:SetDispatcher( Dispatcher )
self.Dispatcher = Dispatcher
end

View File

@@ -141,7 +141,7 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
self.EngageMinSpeed = EngageMinSpeed
self.EngageMaxSpeed = EngageMaxSpeed
self:AddTransition( { "Patrolling", "Engaging", "Returning" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_CAP.
self:AddTransition( { "Patrolling", "Engaging", "Returning", "Airborne" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_CAP.
--- OnBefore Transition Handler for Event Engage.
-- @function [parent=#AI_A2A_CAP] OnBeforeEngage
@@ -302,6 +302,17 @@ function AI_A2A_CAP:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeiling
return self
end
--- onafter State Transition for Event Patrol.
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_CAP:onafterStart( AIGroup, From, Event, To )
AIGroup:HandleEvent( EVENTS.Takeoff, nil, self )
end
--- Set the Engage Zone which defines where the AI will engage bogies.
-- @param #AI_A2A_CAP self

View File

@@ -978,6 +978,7 @@ do -- AI_A2A_DISPATCHER
-- This will avoid the detection to still "know" the shot unit until the next detection.
-- Otherwise, a new intercept or engage may happen for an already shot plane!
self:HandleEvent( EVENTS.Crash, self.OnEventCrashOrDead )
self:HandleEvent( EVENTS.Dead, self.OnEventCrashOrDead )
@@ -1360,6 +1361,8 @@ do -- AI_A2A_DISPATCHER
-- @param #AI_A2A_DISPATCHER self
function AI_A2A_DISPATCHER:SetDefenderTask( SquadronName, Defender, Type, Fsm, Target )
self:F( { SquadronName = SquadronName, Defender = Defender:GetName() } )
self.DefenderTasks[Defender] = self.DefenderTasks[Defender] or {}
self.DefenderTasks[Defender].Type = Type
self.DefenderTasks[Defender].Fsm = Fsm
@@ -2526,15 +2529,18 @@ do -- AI_A2A_DISPATCHER
DetectedSet:Flush()
local DefenderTasks = self:GetDefenderTasks()
for Defender, DefenderTask in pairs( DefenderTasks ) do
local Defender = Defender -- Wrapper.Group#GROUP
for DefenderGroup, DefenderTask in pairs( DefenderTasks ) do
local Defender = DefenderGroup -- Wrapper.Group#GROUP
local DefenderTaskTarget = DefenderTask.Target
local DefenderSquadronName = DefenderTask.SquadronName
if DefenderTaskTarget and DefenderTaskTarget.Index == AttackerDetection.Index then
local Squadron = self:GetSquadron( DefenderSquadronName )
local SquadronOverhead = Squadron.Overhead or self.DefenderDefault.Overhead
DefenderCount = DefenderCount + Defender:GetSize() / SquadronOverhead
self:E( "Defender Group Name: " .. Defender:GetName() .. ", Size: " .. Defender:GetSize() )
local SquadronOverhead = Squadron.Overhead or self.DefenderDefault.Overhead
local DefenderSize = Defender:GetInitialSize()
DefenderCount = DefenderCount + DefenderSize / SquadronOverhead
self:F( "Defender Group Name: " .. Defender:GetName() .. ", Size: " .. DefenderSize )
end
end
@@ -2622,10 +2628,21 @@ do -- AI_A2A_DISPATCHER
Fsm:SetDisengageRadius( self.DisengageRadius )
Fsm:SetTanker( DefenderSquadron.TankerName or self.DefenderDefault.TankerName )
Fsm:Start()
Fsm:__Patrol( 2 )
self:SetDefenderTask( SquadronName, DefenderCAP, "CAP", Fsm )
function Fsm:onafterTakeoff( Defender, From, Event, To )
self:F({"GCI Birth", Defender:GetName()})
--self:GetParent(self).onafterBirth( self, Defender, From, Event, To )
local Dispatcher = Fsm:GetDispatcher() -- #AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
if Squadron then
Fsm:__Patrol( 2 ) -- Start Patrolling
end
end
function Fsm:onafterRTB( Defender, From, Event, To )
self:F({"CAP RTB", Defender:GetName()})
self:GetParent(self).onafterRTB( self, Defender, From, Event, To )
@@ -2721,7 +2738,7 @@ do -- AI_A2A_DISPATCHER
local SpawnCoord = DefenderSquadron.Airbase:GetCoordinate() -- Core.Point#COORDINATE
local AttackerCoord = AttackerUnit:GetCoordinate()
local InterceptCoord = AttackerDetection.InterceptCoord
self:F({InterceptCoord = InterceptCoord})
self:F( { InterceptCoord = InterceptCoord } )
if InterceptCoord then
local InterceptDistance = SpawnCoord:Get2DDistance( InterceptCoord )
local AirbaseDistance = SpawnCoord:Get2DDistance( AttackerCoord )
@@ -2757,6 +2774,11 @@ do -- AI_A2A_DISPATCHER
self:F( { Grouping = DefenderGrouping, SquadronGrouping = DefenderSquadron.Grouping, DefaultGrouping = self.DefenderDefault.Grouping } )
self:F( { DefendersCount = DefenderCount, DefendersNeeded = DefendersNeeded } )
if DefendersNeeded > DefenderSquadron.Resources then
DefendersNeeded = DefenderSquadron.Resources
BreakLoop = true
end
while ( DefendersNeeded > 0 ) do
local Spawn = DefenderSquadron.Spawn[ math.random( 1, #DefenderSquadron.Spawn ) ] -- Functional.Spawn#SPAWN
@@ -2769,14 +2791,14 @@ do -- AI_A2A_DISPATCHER
local TakeoffMethod = self:GetSquadronTakeoff( ClosestDefenderSquadronName )
local DefenderGCI = Spawn:SpawnAtAirbase( DefenderSquadron.Airbase, TakeoffMethod, DefenderSquadron.TakeoffAltitude or self.DefenderDefault.TakeoffAltitude ) -- Wrapper.Group#GROUP
self:F( { GCIDefender = DefenderGCI:GetName() } )
self:E( { GCIDefender = DefenderGCI:GetName() } )
DefendersNeeded = DefendersNeeded - DefenderGrouping
self:AddDefenderToSquadron( DefenderSquadron, DefenderGCI, DefenderGrouping )
if DefenderGCI then
DefenderCount = DefenderCount - DefenderGrouping / DefenderOverhead
local Fsm = AI_A2A_GCI:New( DefenderGCI, Gci.EngageMinSpeed, Gci.EngageMaxSpeed )
@@ -2786,12 +2808,24 @@ do -- AI_A2A_DISPATCHER
Fsm:SetDamageThreshold( self.DefenderDefault.DamageThreshold )
Fsm:SetDisengageRadius( self.DisengageRadius )
Fsm:Start()
Fsm:__Engage( 2, AttackerDetection.Set ) -- Engage on the TargetSetUnit
self:SetDefenderTask( ClosestDefenderSquadronName, DefenderGCI, "GCI", Fsm, AttackerDetection )
function Fsm:onafterTakeoff( Defender, From, Event, To )
self:F({"GCI Birth", Defender:GetName()})
--self:GetParent(self).onafterBirth( self, Defender, From, Event, To )
local Dispatcher = Fsm:GetDispatcher() -- #AI_A2A_DISPATCHER
local Squadron = Dispatcher:GetSquadronFromDefender( Defender )
local DefenderTarget = Dispatcher:GetDefenderTaskTarget( Defender )
if DefenderTarget then
Fsm:__Engage( 2, DefenderTarget.Set ) -- Engage on the TargetSetUnit
end
end
function Fsm:onafterRTB( Defender, From, Event, To )
self:F({"GCI RTB", Defender:GetName()})
self:GetParent(self).onafterRTB( self, Defender, From, Event, To )
@@ -2920,7 +2954,11 @@ do -- AI_A2A_DISPATCHER
for AIGroup, DefenderTask in pairs( self:GetDefenderTasks() ) do
local AIGroup = AIGroup -- Wrapper.Group#GROUP
if not AIGroup:IsAlive() then
self:ClearDefenderTask( AIGroup )
local DefenderTaskFsm = self:GetDefenderTaskFsm( AIGroup )
self:E( { Defender = AIGroup:GetName(), DefenderState = DefenderTaskFsm:GetState() } )
if not DefenderTaskFsm:Is( "Started" ) then
self:ClearDefenderTask( AIGroup )
end
else
if DefenderTask.Target then
local AttackerItem = Detection:GetDetectedItem( DefenderTask.Target.Index )

View File

@@ -134,7 +134,7 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
self.PatrolAltType = "RADIO"
self:AddTransition( { "Started", "Engaging", "Returning" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_GCI.
self:AddTransition( { "Started", "Engaging", "Returning", "Airborne" }, "Engage", "Engaging" ) -- FSM_CONTROLLABLE Transition for type #AI_A2A_GCI.
--- OnBefore Transition Handler for Event Engage.
-- @function [parent=#AI_A2A_GCI] OnBeforeEngage
@@ -295,6 +295,19 @@ function AI_A2A_GCI:New( AIGroup, EngageMinSpeed, EngageMaxSpeed )
return self
end
--- onafter State Transition for Event Patrol.
-- @param #AI_A2A_GCI self
-- @param Wrapper.Group#GROUP AIGroup The AI Group managed by the FSM.
-- @param #string From The From State string.
-- @param #string Event The Event string.
-- @param #string To The To State string.
function AI_A2A_GCI:onafterStart( AIGroup, From, Event, To )
AIGroup:HandleEvent( EVENTS.Takeoff, nil, self )
end
--- onafter State Transition for Event Patrol.
-- @param #AI_A2A_GCI self

View File

@@ -179,7 +179,7 @@ function AI_A2A_PATROL:New( AIGroup, PatrolZone, PatrolFloorAltitude, PatrolCeil
-- defafult PatrolAltType to "RADIO" if not specified
self.PatrolAltType = PatrolAltType or "RADIO"
self:AddTransition( { "Started", "Refuelling" }, "Patrol", "Patrolling" )
self:AddTransition( { "Started", "Airborne", "Refuelling" }, "Patrol", "Patrolling" )
--- OnBefore Transition Handler for Event Patrol.
-- @function [parent=#AI_A2A_PATROL] OnBeforePatrol

View File

@@ -358,16 +358,20 @@ function AI_CAP_ZONE:onafterStart( Controllable, From, Event, To )
end
-- todo: need to fix this global function
--- @param Wrapper.Controllable#CONTROLLABLE AIControllable
function _NewEngageCapRoute( AIControllable )
--- @param AI.AI_CAP#AI_CAP_ZONE
-- @param Wrapper.Group#GROUP EngageGroup
function AI_CAP_ZONE.EngageRoute( EngageGroup, Fsm )
AIControllable:T( "NewEngageRoute" )
local EngageZone = AIControllable:GetState( AIControllable, "EngageZone" ) -- AI.AI_Cap#AI_CAP_ZONE
EngageZone:__Engage( 1 )
EngageGroup:F( { "AI_CAP_ZONE.EngageRoute:", EngageGroup:GetName() } )
if EngageGroup:IsAlive() then
Fsm:__Engage( 1 )
end
end
--- @param #AI_CAP_ZONE self
-- @param Wrapper.Controllable#CONTROLLABLE Controllable The Controllable Object managed by the FSM.
-- @param #string From The From State string.
@@ -503,28 +507,20 @@ function AI_CAP_ZONE:onafterEngage( Controllable, From, Event, To )
end
end
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
self.Controllable:WayPointInitialize( EngageRoute )
if #AttackTasks == 0 then
self:F("No targets found -> Going back to Patrolling")
self:__Abort( 1 )
self:__Route( 1 )
self:SetDetectionActivated()
else
AttackTasks[#AttackTasks+1] = Controllable:TaskFunction( "AI_CAP_ZONE.EngageRoute", self )
EngageRoute[1].task = Controllable:TaskCombo( AttackTasks )
--- Do a trick, link the NewEngageRoute function of the object to the AIControllable in a temporary variable ...
self.Controllable:SetState( self.Controllable, "EngageZone", self )
self.Controllable:WayPointFunction( #EngageRoute, 1, "_NewEngageCapRoute" )
self:SetDetectionDeactivated()
end
--- NOW ROUTE THE GROUP!
self.Controllable:WayPointExecute( 1, 2 )
Controllable:Route( EngageRoute, 0.5 )
end
end

View File

@@ -373,12 +373,15 @@ function AI_CAS_ZONE:onafterStart( Controllable, From, Event, To )
self:SetDetectionDeactivated() -- When not engaging, set the detection off.
end
--- @param Wrapper.Controllable#CONTROLLABLE AIControllable
function _NewEngageRoute( AIControllable )
--- @param AI.AI_CAS#AI_CAS_ZONE
-- @param Wrapper.Group#GROUP EngageGroup
function AI_CAS_ZONE.EngageRoute( EngageGroup, Fsm )
AIControllable:T( "NewEngageRoute" )
local EngageZone = AIControllable:GetState( AIControllable, "EngageZone" ) -- AI.AI_Cas#AI_CAS_ZONE
EngageZone:__Engage( 1, EngageZone.EngageSpeed, EngageZone.EngageAltitude, EngageZone.EngageWeaponExpend, EngageZone.EngageAttackQty, EngageZone.EngageDirection )
EngageGroup:F( { "AI_CAS_ZONE.EngageRoute:", EngageGroup:GetName() } )
if EngageGroup:IsAlive() then
Fsm:__Engage( 1, Fsm.EngageSpeed, Fsm.EngageAltitude, Fsm.EngageWeaponExpend, Fsm.EngageAttackQty, Fsm.EngageDirection )
end
end
@@ -464,6 +467,9 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
if Controllable:IsAlive() then
Controllable:OptionROEOpenFire()
Controllable:OptionROTVertical()
local EngageRoute = {}
--- Calculate the current route point.
@@ -485,7 +491,7 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
local AttackTasks = {}
for DetectedUnitID, DetectedUnit in pairs( self.DetectedUnits ) do
for DetectedUnit, Detected in pairs( self.DetectedUnits ) do
local DetectedUnit = DetectedUnit -- Wrapper.Unit#UNIT
self:T( DetectedUnit )
if DetectedUnit:IsAlive() then
@@ -503,7 +509,8 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
end
end
EngageRoute[1].task = Controllable:TaskCombo( AttackTasks )
AttackTasks[#AttackTasks+1] = Controllable:TaskFunction( "AI_CAS_ZONE.EngageRoute", self )
EngageRoute[#EngageRoute].task = Controllable:TaskCombo( AttackTasks )
--- Define a random point in the @{Zone}. The AI will fly to that point within the zone.
@@ -524,20 +531,8 @@ function AI_CAS_ZONE:onafterEngage( Controllable, From, Event, To,
)
EngageRoute[#EngageRoute+1] = ToTargetRoutePoint
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
Controllable:WayPointInitialize( EngageRoute )
--- Do a trick, link the NewEngageRoute function of the object to the AIControllable in a temporary variable ...
Controllable:SetState( Controllable, "EngageZone", self )
Controllable:WayPointFunction( #EngageRoute, 1, "_NewEngageRoute" )
--- NOW ROUTE THE GROUP!
Controllable:WayPointExecute( 1 )
Controllable:OptionROEOpenFire()
Controllable:OptionROTVertical()
Controllable:Route( EngageRoute, 0.5 )
self:SetRefreshTimeInterval( 2 )
self:SetDetectionActivated()

View File

@@ -608,6 +608,22 @@ function BASE:CreateEventCrash( EventTime, Initiator )
world.onEvent( Event )
end
--- Creation of a Takeoff Event.
-- @param #BASE self
-- @param Dcs.DCSTypes#Time EventTime The time stamp of the event.
-- @param Dcs.DCSWrapper.Object#Object Initiator The initiating object of the event.
function BASE:CreateEventTakeoff( EventTime, Initiator )
self:F( { EventTime, Initiator } )
local Event = {
id = world.event.S_EVENT_TAKEOFF,
time = EventTime,
initiator = Initiator,
}
world.onEvent( Event )
end
-- TODO: Complete Dcs.DCSTypes#Event structure.
--- The main event handling function... This function captures all events generated for the class.
-- @param #BASE self

View File

@@ -561,12 +561,13 @@ end
-- @param Core.Base#BASE EventClass The self instance of the class for which the event is.
-- @param EventID
-- @return #EVENT
function EVENT:OnEventForGroup( GroupName, EventFunction, EventClass, EventID )
self:F2( GroupName )
function EVENT:OnEventForGroup( GroupName, EventFunction, EventClass, EventID, ... )
self:E( GroupName )
local Event = self:Init( EventID, EventClass )
Event.EventGroup = true
Event.EventFunction = EventFunction
Event.Params = arg
return self
end
@@ -950,7 +951,7 @@ function EVENT:onEvent( Event )
local Result, Value = xpcall(
function()
return EventData.EventFunction( EventClass, Event )
return EventData.EventFunction( EventClass, Event, unpack( EventData.Params ) )
end, ErrorHandler )
else
@@ -966,14 +967,14 @@ function EVENT:onEvent( Event )
local Result, Value = xpcall(
function()
return EventFunction( EventClass, Event )
return EventFunction( EventClass, Event, unpack( EventData.Params ) )
end, ErrorHandler )
end
end
end
else
-- The EventClass is not alive anymore, we remove it from the EventHandlers...
self:RemoveEvent( EventClass, Event.id )
--self:RemoveEvent( EventClass, Event.id )
end
else

View File

@@ -139,11 +139,24 @@ do -- MENU_COMMAND_BASE
function MENU_COMMAND_BASE:New( MenuText, ParentMenu, CommandMenuFunction, CommandMenuArguments )
local self = BASE:Inherit( self, MENU_BASE:New( MenuText, ParentMenu ) ) -- #MENU_COMMAND_BASE
-- When a menu function goes into error, DCS displays an obscure menu message.
-- This error handler catches the menu error and displays the full call stack.
local ErrorHandler = function( errmsg )
env.info( "MOOSE error in MENU COMMAND function: " .. errmsg )
if debug ~= nil then
env.info( debug.traceback() )
end
return errmsg
end
self:SetCommandMenuFunction( CommandMenuFunction )
self:SetCommandMenuArguments( CommandMenuArguments )
self.MenuCallHandler = function()
self.CommandMenuFunction( unpack( self.CommandMenuArguments ) )
local function MenuFunction()
return self.CommandMenuFunction( unpack( self.CommandMenuArguments ) )
end
local Status, Result = xpcall( MenuFunction, ErrorHandler )
end
return self

View File

@@ -488,9 +488,9 @@ do -- COORDINATE
function COORDINATE:GetHeadingText( Settings )
local Heading = self:GetHeading()
if Heading then
return string.format( " heading %3.2f °", Heading )
return string.format( " bearing %3d°", Heading )
else
return " heading cannot be determined"
return " bearing unknown"
end
end
@@ -1072,7 +1072,7 @@ do -- COORDINATE
end
if ModeA2A then
if ModeA2A == true then
return self:ToStringA2A( Controllable, Settings )
else
return self:ToStringA2G( Controllable, Settings )

View File

@@ -1883,7 +1883,7 @@ end
-- @return #number Heading Heading in degrees and speed in mps in case of moving units.
function SET_UNIT:GetHeading()
local AvgHeading = nil
local HeadingSet = nil
local MovingCount = 0
for UnitName, UnitData in pairs( self:GetSet() ) do
@@ -1894,15 +1894,20 @@ function SET_UNIT:GetHeading()
local Velocity = Coordinate:GetVelocity()
if Velocity ~= 0 then
local Heading = Coordinate:GetHeading()
AvgHeading = AvgHeading and ( AvgHeading + Heading ) or Heading
MovingCount = MovingCount + 1
if HeadingSet == nil then
HeadingSet = Heading
else
local HeadingDiff = ( HeadingSet - Heading + 180 + 360 ) % 360 - 180
HeadingDiff = math.abs( HeadingDiff )
if HeadingDiff > 5 then
HeadingSet = nil
break
end
end
end
end
AvgHeading = AvgHeading and ( AvgHeading / MovingCount )
self:F( { AvgHeading = AvgHeading } )
return AvgHeading
return HeadingSet
end

View File

@@ -608,9 +608,9 @@ function SCORING:_AddPlayerFromUnit( UnitData )
if self.Players[PlayerName].UnitCoalition ~= UnitCoalition then
self.Players[PlayerName].Penalty = self.Players[PlayerName].Penalty + 50
self.Players[PlayerName].PenaltyCoalition = self.Players[PlayerName].PenaltyCoalition + 1
MESSAGE:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' changed coalition from " .. _SCORINGCoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _SCORINGCoalition[UnitCoalition] ..
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' changed coalition from " .. _SCORINGCoalition[self.Players[PlayerName].UnitCoalition] .. " to " .. _SCORINGCoalition[UnitCoalition] ..
"(changed " .. self.Players[PlayerName].PenaltyCoalition .. " times the coalition). 50 Penalty points added.",
2
MESSAGE.Type.Information
):ToAll()
self:ScoreCSV( PlayerName, "", "COALITION_PENALTY", 1, -50, self.Players[PlayerName].UnitName, _SCORINGCoalition[self.Players[PlayerName].UnitCoalition], _SCORINGCategory[self.Players[PlayerName].UnitCategory], self.Players[PlayerName].UnitType,
UnitName, _SCORINGCoalition[UnitCoalition], _SCORINGCategory[UnitCategory], UnitData:GetTypeName() )
@@ -626,16 +626,16 @@ function SCORING:_AddPlayerFromUnit( UnitData )
if self.Players[PlayerName].Penalty > self.Fratricide * 0.50 then
if self.Players[PlayerName].PenaltyWarning < 1 then
MESSAGE:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than " .. self.Fratricide .. ", you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty,
30
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "': WARNING! If you continue to commit FRATRICIDE and have a PENALTY score higher than " .. self.Fratricide .. ", you will be COURT MARTIALED and DISMISSED from this mission! \nYour total penalty is: " .. self.Players[PlayerName].Penalty,
MESSAGE.Type.Information
):ToAll()
self.Players[PlayerName].PenaltyWarning = self.Players[PlayerName].PenaltyWarning + 1
end
end
if self.Players[PlayerName].Penalty > self.Fratricide then
MESSAGE:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!",
10
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' committed FRATRICIDE, he will be COURT MARTIALED and is DISMISSED from this mission!",
MESSAGE.Type.Information
):ToAll()
UnitData:GetGroup():Destroy()
end
@@ -668,7 +668,7 @@ function SCORING:AddGoalScore( PlayerUnit, GoalTag, Text, Score )
PlayerData.Goals[GoalTag].Score = PlayerData.Goals[GoalTag].Score + Score
PlayerData.Score = PlayerData.Score + Score
MESSAGE:New( self.DisplayMessagePrefix .. Text, 30 ):ToAll()
MESSAGE:NewType( self.DisplayMessagePrefix .. Text, MESSAGE.Type.Information ):ToAll()
self:ScoreCSV( PlayerName, "", "GOAL_" .. string.upper( GoalTag ), 1, Score, PlayerUnit:GetName() )
end
@@ -704,7 +704,7 @@ function SCORING:_AddMissionTaskScore( Mission, PlayerUnit, Text, Score )
PlayerData.Score = self.Players[PlayerName].Score + Score
PlayerData.Mission[MissionName].ScoreTask = self.Players[PlayerName].Mission[MissionName].ScoreTask + Score
MESSAGE:New( self.DisplayMessagePrefix .. MissionName .. " : " .. Text .. " Score: " .. Score, 30 ):ToAll()
MESSAGE:NewType( self.DisplayMessagePrefix .. MissionName .. " : " .. Text .. " Score: " .. Score, MESSAGE.Type.Information ):ToAll()
self:ScoreCSV( PlayerName, "", "TASK_" .. MissionName:gsub( ' ', '_' ), 1, Score, PlayerUnit:GetName() )
end
@@ -732,9 +732,9 @@ function SCORING:_AddMissionScore( Mission, Text, Score )
PlayerData.Score = PlayerData.Score + Score
PlayerData.Mission[MissionName].ScoreMission = PlayerData.Mission[MissionName].ScoreMission + Score
MESSAGE:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in Mission '" .. MissionName .. "'. " ..
MESSAGE:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' has " .. Text .. " in Mission '" .. MissionName .. "'. " ..
Score .. " mission score!",
60 ):ToAll()
MESSAGE.Type.Information ):ToAll()
self:ScoreCSV( PlayerName, "", "MISSION_" .. MissionName:gsub( ' ', '_' ), 1, Score )
end
@@ -902,19 +902,19 @@ function SCORING:_EventOnHit( Event )
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly player '" .. TargetPlayerName .. "' " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly player '" .. TargetPlayerName .. "' " ..
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
2
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
else
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly target " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit friendly target " ..
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.PenaltyHit .. " times. " ..
"Penalty: -" .. PlayerHit.Penalty .. ". Score Total:" .. Player.Score - Player.Penalty,
2
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -926,19 +926,19 @@ function SCORING:_EventOnHit( Event )
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
if TargetPlayerName ~= nil then -- It is a player hitting another player ...
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy player '" .. TargetPlayerName .. "' " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy player '" .. TargetPlayerName .. "' " ..
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
2
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
else
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit enemy target " ..
TargetUnitCategory .. " ( " .. TargetType .. " ) " .. PlayerHit.ScoreHit .. " times. " ..
"Score: " .. PlayerHit.Score .. ". Score Total:" .. Player.Score - Player.Penalty,
2
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -947,8 +947,8 @@ function SCORING:_EventOnHit( Event )
end
else -- A scenery object was hit.
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object.",
2
:NewType( self.DisplayMessagePrefix .. "Player '" .. InitPlayerName .. "' hit scenery object.",
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -1008,10 +1008,10 @@ function SCORING:_EventOnHit( Event )
PlayerHit.PenaltyHit = PlayerHit.PenaltyHit + 1
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit friendly target " ..
TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
"Penalty: -" .. PlayerHit.Penalty .. " = " .. Player.Score - Player.Penalty,
2
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -1021,10 +1021,10 @@ function SCORING:_EventOnHit( Event )
PlayerHit.Score = PlayerHit.Score + 1
PlayerHit.ScoreHit = PlayerHit.ScoreHit + 1
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit enemy target " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit enemy target " ..
TargetUnitCategory .. " ( " .. TargetType .. " ) " ..
"Score: +" .. PlayerHit.Score .. " = " .. Player.Score - Player.Penalty,
2
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( Event.WeaponCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -1032,8 +1032,8 @@ function SCORING:_EventOnHit( Event )
end
else -- A scenery object was hit.
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit scenery object.",
2
:NewType( self.DisplayMessagePrefix .. "Player '" .. Event.WeaponPlayerName .. "' hit scenery object.",
MESSAGE.Type.Update
)
:ToAllIf( self:IfMessagesHit() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesHit() and self:IfMessagesToCoalition() )
@@ -1131,19 +1131,19 @@ function SCORING:_EventOnDeadOrCrash( Event )
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly player '" .. TargetPlayerName .. "' " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly player '" .. TargetPlayerName .. "' " ..
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Penalty: -" .. TargetDestroy.Penalty .. " = " .. Player.Score - Player.Penalty,
15
MESSAGE.Type.Information
)
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
else
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly target " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed friendly target " ..
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Penalty: -" .. TargetDestroy.Penalty .. " = " .. Player.Score - Player.Penalty,
15
MESSAGE.Type.Information
)
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
@@ -1165,19 +1165,19 @@ function SCORING:_EventOnDeadOrCrash( Event )
TargetDestroy.ScoreDestroy = TargetDestroy.ScoreDestroy + 1
if Player.HitPlayers[TargetPlayerName] then -- A player destroyed another player
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy player '" .. TargetPlayerName .. "' " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy player '" .. TargetPlayerName .. "' " ..
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Score: +" .. TargetDestroy.Score .. " = " .. Player.Score - Player.Penalty,
15
MESSAGE.Type.Information
)
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
else
MESSAGE
:New( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy " ..
:NewType( self.DisplayMessagePrefix .. "Player '" .. PlayerName .. "' destroyed enemy " ..
TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " ..
"Score: +" .. TargetDestroy.Score .. " = " .. Player.Score - Player.Penalty,
15
MESSAGE.Type.Information
)
:ToAllIf( self:IfMessagesDestroy() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesDestroy() and self:IfMessagesToCoalition() )
@@ -1191,9 +1191,9 @@ function SCORING:_EventOnDeadOrCrash( Event )
Player.Score = Player.Score + Score
TargetDestroy.Score = TargetDestroy.Score + Score
MESSAGE
:New( self.DisplayMessagePrefix .. "Special target '" .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. " destroyed! " ..
:NewType( self.DisplayMessagePrefix .. "Special target '" .. TargetUnitCategory .. " ( " .. ThreatTypeTarget .. " ) " .. " destroyed! " ..
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! Total: " .. Player.Score - Player.Penalty,
15
MESSAGE.Type.Information
)
:ToAllIf( self:IfMessagesScore() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesScore() and self:IfMessagesToCoalition() )
@@ -1210,10 +1210,10 @@ function SCORING:_EventOnDeadOrCrash( Event )
Player.Score = Player.Score + Score
TargetDestroy.Score = TargetDestroy.Score + Score
MESSAGE
:New( self.DisplayMessagePrefix .. "Target destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
:NewType( self.DisplayMessagePrefix .. "Target destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! " ..
"Total: " .. Player.Score - Player.Penalty,
15 )
MESSAGE.Type.Information )
:ToAllIf( self:IfMessagesZone() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesZone() and self:IfMessagesToCoalition() )
self:ScoreCSV( PlayerName, TargetPlayerName, "DESTROY_SCORE", 1, Score, InitUnitName, InitUnitCoalition, InitUnitCategory, InitUnitType, TargetUnitName, TargetUnitCoalition, TargetUnitCategory, TargetUnitType )
@@ -1232,10 +1232,10 @@ function SCORING:_EventOnDeadOrCrash( Event )
Player.Score = Player.Score + Score
TargetDestroy.Score = TargetDestroy.Score + Score
MESSAGE
:New( self.DisplayMessagePrefix .. "Scenery destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
:NewType( self.DisplayMessagePrefix .. "Scenery destroyed in zone '" .. ScoreZone:GetName() .. "'." ..
"Player '" .. PlayerName .. "' receives an extra " .. Score .. " points! " ..
"Total: " .. Player.Score - Player.Penalty,
15
MESSAGE.Type.Information
)
:ToAllIf( self:IfMessagesZone() and self:IfMessagesToAll() )
:ToCoalitionIf( InitCoalition, self:IfMessagesZone() and self:IfMessagesToCoalition() )
@@ -1522,7 +1522,7 @@ function SCORING:ReportScoreGroupSummary( PlayerGroup )
PlayerScore,
PlayerPenalty
)
MESSAGE:New( PlayerMessage, 30, "Player '" .. PlayerName .. "'" ):ToGroup( PlayerGroup )
MESSAGE:NewType( PlayerMessage, MESSAGE.Type.Detailed ):ToGroup( PlayerGroup )
end
end
@@ -1579,7 +1579,7 @@ function SCORING:ReportScoreGroupDetailed( PlayerGroup )
ReportGoals,
ReportMissions
)
MESSAGE:New( PlayerMessage, 30, "Player '" .. PlayerName .. "'" ):ToGroup( PlayerGroup )
MESSAGE:NewType( PlayerMessage, MESSAGE.Type.Detailed ):ToGroup( PlayerGroup )
end
end
@@ -1628,7 +1628,7 @@ function SCORING:ReportScoreAllSummary( PlayerGroup )
PlayerScore,
PlayerPenalty
)
MESSAGE:New( PlayerMessage, 30, "Player '" .. PlayerName .. "'" ):ToGroup( PlayerGroup )
MESSAGE:NewType( PlayerMessage, MESSAGE.Type.Overview ):ToGroup( PlayerGroup )
end
end

View File

@@ -1109,8 +1109,18 @@ function SPAWN:SpawnAtAirbase( SpawnAirbase, Takeoff, TakeoffAltitude ) -- R2.2
SpawnTemplate.x = PointVec3.x
SpawnTemplate.y = PointVec3.z
local GroupSpawned = self:SpawnWithIndex( self.SpawnIndex )
-- When spawned in the air, we need to generate a Takeoff Event
if Takeoff == GROUP.Takeoff.Air then
for UnitID, UnitSpawned in pairs( GroupSpawned:GetUnits() ) do
SCHEDULER:New( nil, BASE.CreateEventTakeoff, { GroupSpawned, timer.getTime(), UnitSpawned:GetDCSObject() } , 1 )
end
end
return self:SpawnWithIndex( self.SpawnIndex )
return GroupSpawned
end
end

View File

@@ -888,6 +888,8 @@ end
-- @return #string
function MISSION:ReportOverview( ReportGroup, TaskStatus )
self:F( { TaskStatus = TaskStatus } )
local Report = REPORT:New()
-- List the name of the mission.

View File

@@ -1589,8 +1589,9 @@ function TASK:ReportDetails( ReportGroup )
Report:Add( TaskInfoIDText .. TaskInfo.TaskInfoText )
elseif type(TaskInfo) == "table" then
if TaskInfoID == "Coordinates" then
local FromCoordinate = ReportGroup:GetUnit(1):GetCoordinate()
local ToCoordinate = TaskInfo.TaskInfoText -- Core.Point#COORDINATE
Report:Add( TaskInfoIDText .. ToCoordinate:ToString() )
Report:Add( TaskInfoIDText .. ToCoordinate:ToString( ReportGroup:GetUnit(1), nil, self ) )
else
end
end

View File

@@ -366,7 +366,8 @@ do -- TASK_A2G_SEAD
end
function TASK_A2G_SEAD:ReportOrder( ReportGroup )
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Coordinate = self:GetInfo( "Coordinates" )
--local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
return Distance
@@ -515,7 +516,8 @@ do -- TASK_A2G_BAI
function TASK_A2G_BAI:ReportOrder( ReportGroup )
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Coordinate = self:GetInfo( "Coordinates" )
--local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
return Distance
@@ -630,9 +632,9 @@ do -- TASK_A2G_CAS
function TASK_A2G_CAS:UpdateTaskInfo()
local TargetCoordinate = self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) or self.TargetSetUnit:GetFirst():GetCoordinate()
local TargetCoordinate = ( self.Detection and self.Detection:GetDetectedItemCoordinate( self.DetectedItemIndex ) ) or self.TargetSetUnit:GetFirst():GetCoordinate()
self:SetInfo( "Coordinates", TargetCoordinate, 0 )
local ThreatLevel, ThreatText
if self.Detection then
ThreatLevel, ThreatText = self.Detection:GetDetectedItemThreatLevel( self.DetectedItemIndex )
@@ -661,8 +663,10 @@ do -- TASK_A2G_CAS
end
function TASK_A2G_CAS:ReportOrder( ReportGroup )
local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
--- @param #TASK_A2G_CAS self
function TASK_A2G_CAS:ReportOrder( ReportGroup )
local Coordinate = self:GetInfo( "Coordinates" )
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
return Distance

View File

@@ -372,6 +372,7 @@ do -- TASK_A2G_DISPATCHER
self.Tasks[TaskIndex] = Task
Task:SetTargetZone( DetectedZone )
Task:SetDispatcher( self )
Task:UpdateTaskInfo()
Mission:AddTask( Task )
TaskReport:Add( Task:GetName() )

View File

@@ -1161,9 +1161,9 @@ do -- Event Handling
-- @param Core.Event#EVENTS Event
-- @param #function EventFunction (optional) The function to be called when the event occurs for the GROUP.
-- @return #GROUP
function GROUP:HandleEvent( Event, EventFunction )
function GROUP:HandleEvent( Event, EventFunction, ... )
self:EventDispatcher():OnEventForGroup( self:GetName(), EventFunction, self, Event )
self:EventDispatcher():OnEventForGroup( self:GetName(), EventFunction, self, Event, ... )
return self
end

View File

@@ -635,7 +635,7 @@ function POSITIONABLE:MessageToSetGroup( Message, Duration, MessageSetGroup, Nam
if DCSObject:isExist() then
MessageSetGroup:ForEachGroup(
function( MessageGroup )
self:GetMessageType( Message, Duration, Name ):ToGroup( MessageGroup )
self:GetMessage( Message, Duration, Name ):ToGroup( MessageGroup )
end
)
end