This commit is contained in:
FlightControl_Master 2017-10-04 14:34:24 +02:00
parent 1f5030fcbc
commit 454c0e5543
5 changed files with 422 additions and 4 deletions

View File

@ -70,6 +70,8 @@ DATABASE = {
NavPoints = {},
PLAYERSETTINGS = {},
ZONENAMES = {},
HITS = {},
DESTROYS = {},
}
local _DATABASECoalition =
@ -104,6 +106,7 @@ function DATABASE:New()
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
self:HandleEvent( EVENTS.Hit, self.AccountHits )
self:HandleEvent( EVENTS.NewCargo )
self:HandleEvent( EVENTS.DeleteCargo )
@ -722,6 +725,8 @@ function DATABASE:_EventOnDeadOrCrash( Event )
end
end
end
self:AccountDestroys( Event )
end
@ -1053,6 +1058,120 @@ function DATABASE:_RegisterTemplates()
return self
end
--- Account the Hits of the Players.
-- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event
function DATABASE:AccountHits( Event )
self:F( { Event } )
if Event.IniPlayerName ~= nil then -- It is a player that is hitting something
self:T( "Hitting Something" )
-- What is he hitting?
if Event.TgtCategory then
-- A target got hit
self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {}
local Hit = self.HITS[Event.TgtUnitName]
Hit.Players = Hit.Players or {}
Hit.Players[Event.IniPlayerName] = true
end
end
-- It is a weapon initiated by a player, that is hitting something
-- This seems to occur only with scenery and static objects.
if Event.WeaponPlayerName ~= nil then
self:T( "Hitting Scenery" )
-- What is he hitting?
if Event.TgtCategory then
if Event.IniCoalition then -- A coalition object was hit, probably a static.
-- A target got hit
self.HITS[Event.TgtUnitName] = self.HITS[Event.TgtUnitName] or {}
local Hit = self.HITS[Event.TgtUnitName]
Hit.Players = Hit.Players or {}
Hit.Players[Event.WeaponPlayerName] = true
else -- A scenery object was hit.
end
end
end
end
--- Account the destroys.
-- @param #DATABASE self
-- @param Core.Event#EVENTDATA Event
function DATABASE:AccountDestroys( Event )
self:F( { Event } )
local TargetUnit = nil
local TargetGroup = nil
local TargetUnitName = ""
local TargetGroupName = ""
local TargetPlayerName = ""
local TargetCoalition = nil
local TargetCategory = nil
local TargetType = nil
local TargetUnitCoalition = nil
local TargetUnitCategory = nil
local TargetUnitType = nil
if Event.IniDCSUnit then
TargetUnit = Event.IniUnit
TargetUnitName = Event.IniDCSUnitName
TargetGroup = Event.IniDCSGroup
TargetGroupName = Event.IniDCSGroupName
TargetPlayerName = Event.IniPlayerName
TargetCoalition = Event.IniCoalition
--TargetCategory = TargetUnit:getCategory()
--TargetCategory = TargetUnit:getDesc().category -- Workaround
TargetCategory = Event.IniCategory
TargetType = Event.IniTypeName
TargetUnitCoalition = _SCORINGCoalition[TargetCoalition]
TargetUnitCategory = _SCORINGCategory[TargetCategory]
TargetUnitType = TargetType
self:T( { TargetUnitName, TargetGroupName, TargetPlayerName, TargetCoalition, TargetCategory, TargetType } )
end
-- Player contains the score and reference data for the player.
for PlayerName, Player in pairs( self.Players ) do
if Player then -- This should normally not happen, but i'll test it anyway.
self:T( "Something got destroyed" )
-- Some variables
local InitUnitName = Player.UnitName
local InitUnitType = Player.UnitType
local InitCoalition = Player.UnitCoalition
local InitCategory = Player.UnitCategory
local InitUnitCoalition = _SCORINGCoalition[InitCoalition]
local InitUnitCategory = _SCORINGCategory[InitCategory]
self:T( { InitUnitName, InitUnitType, InitUnitCoalition, InitCoalition, InitUnitCategory, InitCategory } )
local Destroyed = false
-- What is the player destroying?
if self.HITS[TargetUnitName] then -- Was there a hit for this unit for this player before registered???
self.DESTROYS[Event.TgtUnitName] = self.DESTROYS[Event.TgtUnitName] or {}
local PlayerDestroys = self.DESTROYS[Event.TgtUnitName]
if TargetCoalition then
PlayerDestroys = PlayerDestroys or {}
PlayerDestroys[PlayerName] = true
end
end
end
end
end

View File

@ -200,7 +200,7 @@ do -- Goal
-- @param #GOAL self
-- @param #number Delay
self:AddTransition( "On", "Achieved", "Achieved" )
self:AddTransition( "*", "Achieved", "Achieved" )
--- Achieved Handler OnBefore for GOAL
-- @function [parent=#GOAL] OnBeforeAchieved
@ -230,10 +230,11 @@ do -- Goal
self.AchievedScheduler = nil
self:SetEventPriority( 5 )
return self
end
--- @param #GOAL self
-- @param From
-- @param Event

View File

@ -57,7 +57,6 @@ do -- Zone
self.Zone = Zone -- Core.Zone#ZONE_BASE
self.Goal = GOAL:New()
self.Goal:Start()
do

View File

@ -58,7 +58,7 @@ do -- ZoneGoal
--- @param #ZONE_CAPTURE_COALITION self
function ZONE_CAPTURE_COALITION:onenterCaptured()
self:GetParent( self ):onenterCaptured()
self:GetParent( self, ZONE_CAPTURE_COALITION ).onenterCaptured( self )
self.Goal:Achieved()
end

View File

@ -0,0 +1,299 @@
--- **Tasking** - The TASK_Protect models tasks for players to protect or capture specific zones.
--
-- ====
--
-- ### Author: **Sven Van de Velde (FlightControl)**
--
-- ### Contributions: MillerTime
--
-- ====
--
-- @module Task_Protect
do -- TASK_ZONE_GOAL
--- The TASK_ZONE_GOAL class
-- @type TASK_ZONE_GOAL
-- @field Core.ZoneGoal#ZONE_GOAL ZoneGoal
-- @extends Tasking.Task#TASK
--- # TASK_ZONE_GOAL class, extends @{Task#TASK}
--
-- The TASK_ZONE_GOAL class defines the task to protect or capture a protection zone.
-- The TASK_ZONE_GOAL is implemented using a @{Fsm#FSM_TASK}, and has the following statuses:
--
-- * **None**: Start of the process
-- * **Planned**: The A2G task is planned.
-- * **Assigned**: The A2G task is assigned to a @{Group#GROUP}.
-- * **Success**: The A2G task is successfully completed.
-- * **Failed**: The A2G task has failed. This will happen if the player exists the task early, without communicating a possible cancellation to HQ.
--
-- ## Set the scoring of achievements in an A2G attack.
--
-- Scoring or penalties can be given in the following circumstances:
--
-- * @{#TASK_ZONE_GOAL.SetScoreOnDestroy}(): Set a score when a target in scope of the A2G attack, has been destroyed.
-- * @{#TASK_ZONE_GOAL.SetScoreOnSuccess}(): Set a score when all the targets in scope of the A2G attack, have been destroyed.
-- * @{#TASK_ZONE_GOAL.SetPenaltyOnFailed}(): Set a penalty when the A2G attack has failed.
--
-- @field #TASK_ZONE_GOAL
TASK_ZONE_GOAL = {
ClassName = "TASK_ZONE_GOAL",
}
--- Instantiates a new TASK_ZONE_GOAL.
-- @param #TASK_ZONE_GOAL self
-- @param Tasking.Mission#MISSION Mission
-- @param Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal
-- @return #TASK_ZONE_GOAL self
function TASK_ZONE_GOAL:New( Mission, SetGroup, TaskName, ZoneGoal, TaskType, TaskBriefing )
local self = BASE:Inherit( self, TASK:New( Mission, SetGroup, TaskName, TaskType, TaskBriefing ) ) -- #TASK_ZONE_GOAL
self:F()
self.ZoneGoal = ZoneGoal
self.TaskType = TaskType
local Fsm = self:GetUnitProcess()
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "StartMonitoring", Rejected = "Reject" } )
Fsm:AddTransition( "Assigned", "StartMonitoring", "Monitoring" )
Fsm:AddTransition( "Monitoring", "Monitor", "Monitoring", {} )
Fsm:AddTransition( "Monitoring", "RouteToTarget", "Monitoring" )
Fsm:AddProcess( "Monitoring", "RouteToZone", ACT_ROUTE_ZONE:New(), {} )
--Fsm:AddTransition( "Accounted", "DestroyedAll", "Accounted" )
--Fsm:AddTransition( "Accounted", "Success", "Success" )
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
Fsm:AddTransition( "Failed", "Fail", "Failed" )
self:SetTargetZone( self.ZoneGoal:GetZone() )
--- Test
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task#TASK_ZONE_GOAL Task
function Fsm:onafterStartMonitoring( TaskUnit, Task )
self:E( { self } )
self:__Protect( 0.1 )
self:__RouteToTarget( 0.1 )
end
--- Monitor Loop
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task#TASK_ZONE_GOAL Task
function Fsm:onafterMonitor( TaskUnit, Task )
self:E( { self } )
self:__Protect( 15 )
end
--- Test
-- @param #FSM_PROCESS self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @param Tasking.Task_A2G#TASK_ZONE_GOAL Task
function Fsm:onafterRouteToTarget( TaskUnit, Task )
self:E( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
-- Determine the first Unit from the self.TargetSetUnit
if Task:GetTargetZone( TaskUnit ) then
self:__RouteToTargetZone( 0.1 )
end
end
return self
end
--- @param #TASK_ZONE_GOAL self
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal The ZoneGoal Engine.
function TASK_ZONE_GOAL:SetProtect( ZoneGoal )
self.ZoneGoal = ZoneGoal -- Core.ZoneGoal#ZONE_GOAL
end
--- @param #TASK_ZONE_GOAL self
function TASK_ZONE_GOAL:GetPlannedMenuText()
return self:GetStateString() .. " - " .. self:GetTaskName() .. " ( " .. self.ZoneGoal:GetZoneName() .. " )"
end
--- @param #TASK_ZONE_GOAL self
-- @param Core.Zone#ZONE_BASE TargetZone The Zone object where the Target is located on the map.
-- @param Wrapper.Unit#UNIT TaskUnit
function TASK_ZONE_GOAL:SetTargetZone( TargetZone, TaskUnit )
local ProcessUnit = self:GetUnitProcess( TaskUnit )
local ActRouteZone = ProcessUnit:GetProcess( "Monitoring", "RouteToZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
ActRouteZone:SetZone( TargetZone )
end
--- @param #TASK_ZONE_GOAL self
-- @param Wrapper.Unit#UNIT TaskUnit
-- @return Core.Zone#ZONE_BASE The Zone object where the Target is located on the map.
function TASK_ZONE_GOAL:GetTargetZone( TaskUnit )
local ProcessUnit = self:GetUnitProcess( TaskUnit )
local ActRouteZone = ProcessUnit:GetProcess( "Monitoring", "RouteToZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
return ActRouteZone:GetZone()
end
function TASK_ZONE_GOAL:SetGoalTotal()
self.GoalTotal = 1
end
function TASK_ZONE_GOAL:GetGoalTotal()
return self.GoalTotal
end
end
do -- TASK_CAPTURE_ZONE
--- The TASK_CAPTURE_ZONE class
-- @type TASK_CAPTURE_ZONE
-- @field Set#SET_UNIT TargetSetUnit
-- @extends Tasking.TaskZoneGoal#TASK_ZONE_GOAL
--- # TASK_CAPTURE_ZONE class, extends @{TaskZoneGoal#TASK_ZONE_GOAL}
--
-- The TASK_CAPTURE_ZONE class defines an Suppression or Extermination of Air Defenses task for a human player to be executed.
-- These tasks are important to be executed as they will help to achieve air superiority at the vicinity.
--
-- The TASK_CAPTURE_ZONE is used by the @{Task_A2G_Dispatcher#TASK_A2G_DISPATCHER} to automatically create SEAD tasks
-- based on detected enemy ground targets.
--
-- @field #TASK_CAPTURE_ZONE
TASK_CAPTURE_ZONE = {
ClassName = "TASK_CAPTURE_ZONE",
}
--- Instantiates a new TASK_CAPTURE_ZONE.
-- @param #TASK_CAPTURE_ZONE self
-- @param Tasking.Mission#MISSION Mission
-- @param Core.Set#SET_GROUP SetGroup The set of groups for which the Task can be assigned.
-- @param #string TaskName The name of the Task.
-- @param Core.ZoneGoal#ZONE_GOAL ZoneGoal
-- @param #string TaskBriefing The briefing of the task.
-- @return #TASK_CAPTURE_ZONE self
function TASK_CAPTURE_ZONE:New( Mission, SetGroup, TaskName, ZoneGoal, TaskBriefing)
local self = BASE:Inherit( self, TASK_ZONE_GOAL:New( Mission, SetGroup, TaskName, ZoneGoal, "CAPTURE", TaskBriefing ) ) -- #TASK_CAPTURE_ZONE
self:F()
Mission:AddTask( self )
self.TaskCoalition = ZoneGoal:GetCoalition()
self.TaskCoalitionName = ZoneGoal:GetCoalitionName()
self.TaskZoneName = self.ZoneGoal:GetZoneName()
self:SetBriefing(
TaskBriefing or
"Capture zone " .. self.TaskZoneName .. "."
)
self:UpdateTaskInfo()
return self
end
--- Instantiates a new TASK_CAPTURE_ZONE.
-- @param #TASK_CAPTURE_ZONE self
function TASK_CAPTURE_ZONE:UpdateTaskInfo()
local ZoneCoordinate = self.ZoneGoal:GetZone():GetCoordinate()
self:SetInfo( "Coordinates", ZoneCoordinate, 0 )
self:SetInfo( "Zone Name", self.TaskZoneName, 10 )
self:SetInfo( "Zone Coalition", self.TaskCoalitionName, 11 )
end
function TASK_CAPTURE_ZONE:ReportOrder( ReportGroup )
local Coordinate = self:GetInfo( "Coordinates" )
--local Coordinate = self.TaskInfo.Coordinates.TaskInfoText
local Distance = ReportGroup:GetCoordinate():Get2DDistance( Coordinate )
return Distance
end
--- @param #TASK_CAPTURE_ZONE self
-- @param Wrapper.Unit#UNIT TaskUnit
function TASK_CAPTURE_ZONE:OnAfterGoal( From, Event, To, PlayerUnit, PlayerName )
self:E( { PlayerUnit = PlayerUnit } )
if self.ZoneGoal then
local ProtectCoalition = self.ZoneGoal:GetCoalition()
local TaskCoalition = self.Coalition
self:E( { ProtectCoalition = ProtectCoalition, TaskCoalition = TaskCoalition } )
if ProtectCoalition ~= TaskCoalition then
self:Success()
end
end
self:__Goal( -10, PlayerUnit, PlayerName )
end
--- Set a score when a target in scope of the A2G attack, has been destroyed .
-- @param #TASK_CAPTURE_ZONE self
-- @param #string PlayerName The name of the player.
-- @param #number Score The score in points to be granted when task process has been achieved.
-- @param Wrapper.Unit#UNIT TaskUnit
-- @return #TASK_CAPTURE_ZONE
function TASK_CAPTURE_ZONE:SetScoreOnProgress( PlayerName, Score, TaskUnit )
self:F( { PlayerName, Score, TaskUnit } )
local ProcessUnit = self:GetUnitProcess( TaskUnit )
--ProcessUnit:AddScoreProcess( "Protecting", "ZoneGoal", "Captured", "Player " .. PlayerName .. " has SEADed a target.", Score )
return self
end
--- Set a score when all the targets in scope of the A2G attack, have been destroyed.
-- @param #TASK_CAPTURE_ZONE self
-- @param #string PlayerName The name of the player.
-- @param #number Score The score in points.
-- @param Wrapper.Unit#UNIT TaskUnit
-- @return #TASK_CAPTURE_ZONE
function TASK_CAPTURE_ZONE:SetScoreOnSuccess( PlayerName, Score, TaskUnit )
self:F( { PlayerName, Score, TaskUnit } )
local ProcessUnit = self:GetUnitProcess( TaskUnit )
ProcessUnit:AddScore( "Success", "The zone has been captured!", Score )
return self
end
--- Set a penalty when the A2G attack has failed.
-- @param #TASK_CAPTURE_ZONE self
-- @param #string PlayerName The name of the player.
-- @param #number Penalty The penalty in points, must be a negative value!
-- @param Wrapper.Unit#UNIT TaskUnit
-- @return #TASK_CAPTURE_ZONE
function TASK_CAPTURE_ZONE:SetScoreOnFail( PlayerName, Penalty, TaskUnit )
self:F( { PlayerName, Penalty, TaskUnit } )
local ProcessUnit = self:GetUnitProcess( TaskUnit )
ProcessUnit:AddScore( "Failed", "The zone has been lost!", Penalty )
return self
end
end