mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-08-15 10:47:21 +00:00
Merge branch 'develop' into FF/Develop
This commit is contained in:
commit
06b555a50a
@ -6,9 +6,9 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module AI_Cargo_Troops
|
||||
-- @module AI_Cargo_APC
|
||||
|
||||
--- @type AI_CARGO_TROOPS
|
||||
--- @type AI_CARGO_APC
|
||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||
|
||||
|
||||
@ -16,21 +16,21 @@
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CARGO_TROOPS
|
||||
AI_CARGO_TROOPS = {
|
||||
ClassName = "AI_CARGO_TROOPS",
|
||||
-- @field #AI_CARGO_APC
|
||||
AI_CARGO_APC = {
|
||||
ClassName = "AI_CARGO_APC",
|
||||
Coordinate = nil -- Core.Point#COORDINATE,
|
||||
}
|
||||
|
||||
--- Creates a new AI_CARGO_TROOPS object.
|
||||
-- @param #AI_CARGO_TROOPS self
|
||||
--- Creates a new AI_CARGO_APC object.
|
||||
-- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
-- @param Cargo.CargoGroup#CARGO_GROUP CargoGroup
|
||||
-- @param #number CombatRadius
|
||||
-- @return #AI_CARGO_TROOPS
|
||||
function AI_CARGO_TROOPS:New( CargoCarrier, CargoGroup, CombatRadius )
|
||||
-- @return #AI_CARGO_APC
|
||||
function AI_CARGO_APC:New( CargoCarrier, CargoGroup, CombatRadius )
|
||||
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New( ) ) -- #AI_CARGO_TROOPS
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_CARGO_APC
|
||||
|
||||
self.CargoGroup = CargoGroup -- Cargo.CargoGroup#CARGO_GROUP
|
||||
self.CombatRadius = CombatRadius
|
||||
@ -59,20 +59,20 @@ end
|
||||
|
||||
|
||||
--- Set the Carrier.
|
||||
-- @param #AI_CARGO_TROOPS self
|
||||
-- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
-- @return #AI_CARGO_TROOPS
|
||||
function AI_CARGO_TROOPS:SetCarrier( CargoCarrier )
|
||||
-- @return #AI_CARGO_APC
|
||||
function AI_CARGO_APC:SetCarrier( CargoCarrier )
|
||||
|
||||
self.CargoCarrier = CargoCarrier -- Wrapper.Unit#UNIT
|
||||
self.CargoCarrier:SetState( self.CargoCarrier, "AI_CARGO_TROOPS", self )
|
||||
self.CargoCarrier:SetState( self.CargoCarrier, "AI_CARGO_APC", self )
|
||||
|
||||
CargoCarrier:HandleEvent( EVENTS.Dead )
|
||||
CargoCarrier:HandleEvent( EVENTS.Hit )
|
||||
|
||||
function CargoCarrier:OnEventDead( EventData )
|
||||
self:F({"dead"})
|
||||
local AICargoTroops = self:GetState( self, "AI_CARGO_TROOPS" )
|
||||
local AICargoTroops = self:GetState( self, "AI_CARGO_APC" )
|
||||
self:F({AICargoTroops=AICargoTroops})
|
||||
if AICargoTroops then
|
||||
self:F({})
|
||||
@ -85,7 +85,7 @@ function AI_CARGO_TROOPS:SetCarrier( CargoCarrier )
|
||||
|
||||
function CargoCarrier:OnEventHit( EventData )
|
||||
self:F({"hit"})
|
||||
local AICargoTroops = self:GetState( self, "AI_CARGO_TROOPS" )
|
||||
local AICargoTroops = self:GetState( self, "AI_CARGO_APC" )
|
||||
if AICargoTroops then
|
||||
self:F( { OnHitLoaded = AICargoTroops:Is( "Loaded" ) } )
|
||||
if AICargoTroops:Is( "Loaded" ) or AICargoTroops:Is( "Boarding" ) then
|
||||
@ -107,18 +107,18 @@ end
|
||||
|
||||
|
||||
--- Find a free Carrier within a range.
|
||||
-- @param #AI_CARGO_TROOPS self
|
||||
-- @param #AI_CARGO_APC self
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
-- @param #number Radius
|
||||
-- @return Wrapper.Unit#UNIT NewCarrier
|
||||
function AI_CARGO_TROOPS:FindCarrier( Coordinate, Radius )
|
||||
function AI_CARGO_APC:FindCarrier( Coordinate, Radius )
|
||||
|
||||
local CoordinateZone = ZONE_RADIUS:New( "Zone" , Coordinate:GetVec2(), Radius )
|
||||
CoordinateZone:Scan( { Object.Category.UNIT } )
|
||||
for _, DCSUnit in pairs( CoordinateZone:GetScannedUnits() ) do
|
||||
local NearUnit = UNIT:Find( DCSUnit )
|
||||
self:F({NearUnit=NearUnit})
|
||||
if not NearUnit:GetState( NearUnit, "AI_CARGO_TROOPS" ) then
|
||||
if not NearUnit:GetState( NearUnit, "AI_CARGO_APC" ) then
|
||||
local Attributes = NearUnit:GetDesc()
|
||||
self:F({Desc=Attributes})
|
||||
if NearUnit:HasAttribute( "Trucks" ) then
|
||||
@ -133,12 +133,12 @@ end
|
||||
|
||||
|
||||
--- Follow Infantry to the Carrier.
|
||||
-- @param #AI_CARGO_TROOPS self
|
||||
-- @param #AI_CARGO_TROOPS Me
|
||||
-- @param #AI_CARGO_APC self
|
||||
-- @param #AI_CARGO_APC Me
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
-- @param Wrapper.Group#GROUP InfantryGroup
|
||||
-- @return #AI_CARGO_TROOPS
|
||||
function AI_CARGO_TROOPS:FollowToCarrier( Me, CargoCarrier, InfantryGroup )
|
||||
-- @return #AI_CARGO_APC
|
||||
function AI_CARGO_APC:FollowToCarrier( Me, CargoCarrier, InfantryGroup )
|
||||
|
||||
self:F( { self = self:GetClassNameAndID(), InfantryGroup = InfantryGroup:GetName() } )
|
||||
|
||||
@ -172,7 +172,7 @@ function AI_CARGO_TROOPS:FollowToCarrier( Me, CargoCarrier, InfantryGroup )
|
||||
self:F({ToGround=ToGround})
|
||||
table.insert( Waypoints, ToGround )
|
||||
|
||||
local TaskRoute = InfantryGroup:TaskFunction( "AI_CARGO_TROOPS.FollowToCarrier", Me, CargoCarrier, InfantryGroup )
|
||||
local TaskRoute = InfantryGroup:TaskFunction( "AI_CARGO_APC.FollowToCarrier", Me, CargoCarrier, InfantryGroup )
|
||||
|
||||
self:F({Waypoints = Waypoints})
|
||||
local Waypoint = Waypoints[#Waypoints]
|
||||
@ -185,9 +185,9 @@ function AI_CARGO_TROOPS:FollowToCarrier( Me, CargoCarrier, InfantryGroup )
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_TROOPS self
|
||||
--- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function AI_CARGO_TROOPS:onafterMonitor( CargoCarrier, From, Event, To )
|
||||
function AI_CARGO_APC:onafterMonitor( CargoCarrier, From, Event, To )
|
||||
self:F( { CargoCarrier, From, Event, To } )
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
@ -235,9 +235,9 @@ function AI_CARGO_TROOPS:onafterMonitor( CargoCarrier, From, Event, To )
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_TROOPS self
|
||||
--- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function AI_CARGO_TROOPS:onafterLoad( CargoCarrier, From, Event, To )
|
||||
function AI_CARGO_APC:onafterLoad( CargoCarrier, From, Event, To )
|
||||
self:F( { CargoCarrier, From, Event, To } )
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
@ -248,9 +248,9 @@ function AI_CARGO_TROOPS:onafterLoad( CargoCarrier, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_TROOPS self
|
||||
--- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function AI_CARGO_TROOPS:onafterBoard( CargoCarrier, From, Event, To )
|
||||
function AI_CARGO_APC:onafterBoard( CargoCarrier, From, Event, To )
|
||||
self:F( { CargoCarrier, From, Event, To } )
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
@ -264,9 +264,9 @@ function AI_CARGO_TROOPS:onafterBoard( CargoCarrier, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_TROOPS self
|
||||
--- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function AI_CARGO_TROOPS:onafterLoaded( CargoCarrier, From, Event, To )
|
||||
function AI_CARGO_APC:onafterLoaded( CargoCarrier, From, Event, To )
|
||||
self:F( { CargoCarrier, From, Event, To } )
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
@ -276,9 +276,9 @@ function AI_CARGO_TROOPS:onafterLoaded( CargoCarrier, From, Event, To )
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_TROOPS self
|
||||
--- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function AI_CARGO_TROOPS:onafterUnload( CargoCarrier, From, Event, To )
|
||||
function AI_CARGO_APC:onafterUnload( CargoCarrier, From, Event, To )
|
||||
self:F( { CargoCarrier, From, Event, To } )
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
@ -289,9 +289,9 @@ function AI_CARGO_TROOPS:onafterUnload( CargoCarrier, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_TROOPS self
|
||||
--- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function AI_CARGO_TROOPS:onafterUnboard( CargoCarrier, From, Event, To )
|
||||
function AI_CARGO_APC:onafterUnboard( CargoCarrier, From, Event, To )
|
||||
self:F( { CargoCarrier, From, Event, To } )
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
@ -304,9 +304,9 @@ function AI_CARGO_TROOPS:onafterUnboard( CargoCarrier, From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_TROOPS self
|
||||
--- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function AI_CARGO_TROOPS:onafterUnloaded( CargoCarrier, From, Event, To )
|
||||
function AI_CARGO_APC:onafterUnloaded( CargoCarrier, From, Event, To )
|
||||
self:F( { CargoCarrier, From, Event, To } )
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() then
|
||||
@ -318,9 +318,9 @@ function AI_CARGO_TROOPS:onafterUnloaded( CargoCarrier, From, Event, To )
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_TROOPS self
|
||||
--- @param #AI_CARGO_APC self
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function AI_CARGO_TROOPS:onafterFollow( CargoCarrier, From, Event, To )
|
||||
function AI_CARGO_APC:onafterFollow( CargoCarrier, From, Event, To )
|
||||
self:F( { CargoCarrier, From, Event, To } )
|
||||
|
||||
self:F( "Follow" )
|
||||
348
Moose Development/Moose/AI/AI_Cargo_Airplane.lua
Normal file
348
Moose Development/Moose/AI/AI_Cargo_Airplane.lua
Normal file
@ -0,0 +1,348 @@
|
||||
--- **AI** -- (R2.3) - Models the intelligent transportation of infantry (cargo).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **FlightControl**
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module AI_Cargo_Airplane
|
||||
|
||||
--- @type AI_CARGO_AIRPLANE
|
||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||
|
||||
|
||||
--- # AI\_CARGO\_AIRPLANE class, extends @{Core.Base@BASE}
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CARGO_AIRPLANE
|
||||
AI_CARGO_AIRPLANE = {
|
||||
ClassName = "AI_CARGO_AIRPLANE",
|
||||
Coordinate = nil -- Core.Point#COORDINATE,
|
||||
}
|
||||
|
||||
--- Creates a new AI_CARGO_AIRPLANE object.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @param Core.Set#SET_CARGO CargoSet
|
||||
-- @param #number CombatRadius
|
||||
-- @return #AI_CARGO_AIRPLANE
|
||||
function AI_CARGO_AIRPLANE:New( Airplane, CargoSet )
|
||||
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_CARGO_AIRPLANE
|
||||
|
||||
self.CargoSet = CargoSet -- Cargo.CargoGroup#CARGO_GROUP
|
||||
|
||||
self:SetStartState( "Unloaded" )
|
||||
|
||||
self:AddTransition( "Unloaded", "Pickup", "*" )
|
||||
self:AddTransition( "Loaded", "Deploy", "*" )
|
||||
|
||||
self:AddTransition( "Unloaded", "Load", "Boarding" )
|
||||
self:AddTransition( "Boarding", "Board", "Boarding" )
|
||||
self:AddTransition( "Boarding", "Loaded", "Loaded" )
|
||||
self:AddTransition( "Loaded", "Unload", "Unboarding" )
|
||||
self:AddTransition( "Unboarding", "Unboard", "Unboarding" )
|
||||
self:AddTransition( "Unboarding", "Unloaded", "Unloaded" )
|
||||
|
||||
self:AddTransition( "*", "Landed", "*" )
|
||||
|
||||
self:AddTransition( "*", "Destroyed", "Destroyed" )
|
||||
|
||||
--- Pickup Handler OnBefore for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnBeforePickup
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @return #boolean
|
||||
|
||||
--- Pickup Handler OnAfter for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnAfterPickup
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
|
||||
--- Pickup Trigger for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] Pickup
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
|
||||
--- Pickup Asynchronous Trigger for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] __Pickup
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param #number Delay
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
|
||||
--- Deploy Handler OnBefore for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnBeforeDeploy
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @return #boolean
|
||||
|
||||
--- Deploy Handler OnAfter for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] OnAfterDeploy
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
|
||||
--- Deploy Trigger for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] Deploy
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
|
||||
--- Deploy Asynchronous Trigger for AI_CARGO_AIRPLANE
|
||||
-- @function [parent=#AI_CARGO_AIRPLANE] __Deploy
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
self:SetCarrier( Airplane )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set the Carrier.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @return #AI_CARGO_AIRPLANE
|
||||
function AI_CARGO_AIRPLANE:SetCarrier( Airplane )
|
||||
|
||||
local AICargo = self
|
||||
|
||||
self.Airplane = Airplane -- Wrapper.Group#GROUP
|
||||
self.Airplane:SetState( self.Airplane, "AI_CARGO_AIRPLANE", self )
|
||||
|
||||
self.RoutePickup = false
|
||||
self.RouteDeploy = false
|
||||
|
||||
Airplane:HandleEvent( EVENTS.Dead )
|
||||
Airplane:HandleEvent( EVENTS.Hit )
|
||||
Airplane:HandleEvent( EVENTS.EngineShutdown )
|
||||
|
||||
function Airplane:OnEventDead( EventData )
|
||||
local AICargoTroops = self:GetState( self, "AI_CARGO_AIRPLANE" )
|
||||
self:F({AICargoTroops=AICargoTroops})
|
||||
if AICargoTroops then
|
||||
self:F({})
|
||||
if not AICargoTroops:Is( "Loaded" ) then
|
||||
-- There are enemies within combat range. Unload the Airplane.
|
||||
AICargoTroops:Destroyed()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Airplane:OnEventHit( EventData )
|
||||
local AICargoTroops = self:GetState( self, "AI_CARGO_AIRPLANE" )
|
||||
if AICargoTroops then
|
||||
self:F( { OnHitLoaded = AICargoTroops:Is( "Loaded" ) } )
|
||||
if AICargoTroops:Is( "Loaded" ) or AICargoTroops:Is( "Boarding" ) then
|
||||
-- There are enemies within combat range. Unload the Airplane.
|
||||
AICargoTroops:Unload()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Airplane:OnEventEngineShutdown( EventData )
|
||||
AICargo:Landed()
|
||||
end
|
||||
|
||||
self.Coalition = self.Airplane:GetCoalition()
|
||||
|
||||
self:SetControllable( Airplane )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Find a free Carrier within a range.
|
||||
-- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param #number Radius
|
||||
-- @return Wrapper.Group#GROUP NewCarrier
|
||||
function AI_CARGO_AIRPLANE:FindCarrier( Coordinate, Radius )
|
||||
|
||||
local CoordinateZone = ZONE_RADIUS:New( "Zone" , Coordinate:GetVec2(), Radius )
|
||||
CoordinateZone:Scan( { Object.Category.UNIT } )
|
||||
for _, DCSUnit in pairs( CoordinateZone:GetScannedUnits() ) do
|
||||
local NearUnit = UNIT:Find( DCSUnit )
|
||||
self:F({NearUnit=NearUnit})
|
||||
if not NearUnit:GetState( NearUnit, "AI_CARGO_AIRPLANE" ) then
|
||||
local Attributes = NearUnit:GetDesc()
|
||||
self:F({Desc=Attributes})
|
||||
if NearUnit:HasAttribute( "Trucks" ) then
|
||||
self:SetCarrier( NearUnit )
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param #number Speed
|
||||
function AI_CARGO_AIRPLANE:onafterLanded( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
if self.RoutePickup == true then
|
||||
self:Load( Airplane:GetPointVec2() )
|
||||
self.RoutePickup = false
|
||||
end
|
||||
|
||||
if self.RouteDeploy == true then
|
||||
self:Unload()
|
||||
self.RouteDeploy = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param #number Speed
|
||||
function AI_CARGO_AIRPLANE:onafterPickup( Airplane, From, Event, To, Airbase, Speed )
|
||||
|
||||
if self.Airbase then
|
||||
Airplane:RespawnAtAirbase( self.Airbase )
|
||||
end
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
self.RoutePickup = true
|
||||
self.Airbase = Airbase
|
||||
|
||||
Airplane:RouteRTB( Airbase, Speed)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Wrapper.Airbase#AIRBASE Airbase
|
||||
-- @param #number Speed
|
||||
function AI_CARGO_AIRPLANE:onafterDeploy( Airplane, From, Event, To, Airbase, Speed )
|
||||
|
||||
if self.Airbase then
|
||||
Airplane:RespawnAtAirbase( self.Airbase )
|
||||
end
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
self.RouteDeploy = true
|
||||
self.Airbase = Airbase
|
||||
|
||||
Airplane:RouteRTB( Airbase, Speed )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
function AI_CARGO_AIRPLANE:onafterLoad( Airplane, From, Event, To, Coordinate )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
|
||||
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
|
||||
if Cargo:IsInLoadRadius( Coordinate ) then
|
||||
self:__Board( 5 )
|
||||
Cargo:Board( Airplane, 25 )
|
||||
self.Cargo = Cargo
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
function AI_CARGO_AIRPLANE:onafterBoard( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
self:F({ IsLoaded = self.Cargo:IsLoaded() } )
|
||||
if not self.Cargo:IsLoaded() then
|
||||
self:__Board( 10 )
|
||||
else
|
||||
self:__Loaded( 1 )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
function AI_CARGO_AIRPLANE:onafterLoaded( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
function AI_CARGO_AIRPLANE:onafterUnload( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
self.Cargo:UnBoard()
|
||||
self:__Unboard( 10 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
function AI_CARGO_AIRPLANE:onafterUnboard( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
if not self.Cargo:IsUnLoaded() then
|
||||
self:__Unboard( 10 )
|
||||
else
|
||||
self:__Unloaded( 1 )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_AIRPLANE self
|
||||
-- @param Wrapper.Group#GROUP Airplane
|
||||
function AI_CARGO_AIRPLANE:onafterUnloaded( Airplane, From, Event, To )
|
||||
|
||||
if Airplane and Airplane:IsAlive() then
|
||||
self.Airplane = Airplane
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
411
Moose Development/Moose/AI/AI_Cargo_Helicopter.lua
Normal file
411
Moose Development/Moose/AI/AI_Cargo_Helicopter.lua
Normal file
@ -0,0 +1,411 @@
|
||||
--- **AI** -- (R2.3) - Models the intelligent transportation of infantry (cargo).
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- ### Author: **FlightControl**
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @module AI_Cargo_Helicopter
|
||||
|
||||
--- @type AI_CARGO_HELICOPTER
|
||||
-- @extends Core.Fsm#FSM_CONTROLLABLE
|
||||
|
||||
|
||||
--- # AI\_CARGO\_TROOPS class, extends @{Core.Base@BASE}
|
||||
--
|
||||
-- ===
|
||||
--
|
||||
-- @field #AI_CARGO_HELICOPTER
|
||||
AI_CARGO_HELICOPTER = {
|
||||
ClassName = "AI_CARGO_HELICOPTER",
|
||||
Coordinate = nil -- Core.Point#COORDINATE,
|
||||
}
|
||||
|
||||
--- Creates a new AI_CARGO_HELICOPTER object.
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
-- @param Core.Set#SET_CARGO CargoSet
|
||||
-- @param #number CombatRadius
|
||||
-- @return #AI_CARGO_HELICOPTER
|
||||
function AI_CARGO_HELICOPTER:New( Helicopter, CargoSet )
|
||||
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- #AI_CARGO_HELICOPTER
|
||||
|
||||
self.CargoSet = CargoSet -- Cargo.CargoGroup#CARGO_GROUP
|
||||
|
||||
self:SetStartState( "Unloaded" )
|
||||
|
||||
self:AddTransition( "Unloaded", "Pickup", "*" )
|
||||
self:AddTransition( "Loaded", "Deploy", "*" )
|
||||
|
||||
self:AddTransition( "Unloaded", "Load", "Boarding" )
|
||||
self:AddTransition( "Boarding", "Board", "Boarding" )
|
||||
self:AddTransition( "Boarding", "Loaded", "Loaded" )
|
||||
self:AddTransition( "Loaded", "Unload", "Unboarding" )
|
||||
self:AddTransition( "Unboarding", "Unboard", "Unboarding" )
|
||||
self:AddTransition( "Unboarding", "Unloaded", "Unloaded" )
|
||||
|
||||
self:AddTransition( "*", "Landed", "*" )
|
||||
|
||||
self:AddTransition( "*", "Destroyed", "Destroyed" )
|
||||
|
||||
--- Pickup Handler OnBefore for AI_CARGO_HELICOPTER
|
||||
-- @function [parent=#AI_CARGO_HELICOPTER] OnBeforePickup
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
-- @return #boolean
|
||||
|
||||
--- Pickup Handler OnAfter for AI_CARGO_HELICOPTER
|
||||
-- @function [parent=#AI_CARGO_HELICOPTER] OnAfterPickup
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
|
||||
--- Pickup Trigger for AI_CARGO_HELICOPTER
|
||||
-- @function [parent=#AI_CARGO_HELICOPTER] Pickup
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
|
||||
--- Pickup Asynchronous Trigger for AI_CARGO_HELICOPTER
|
||||
-- @function [parent=#AI_CARGO_HELICOPTER] __Pickup
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param #number Delay
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
|
||||
--- Deploy Handler OnBefore for AI_CARGO_HELICOPTER
|
||||
-- @function [parent=#AI_CARGO_HELICOPTER] OnBeforeDeploy
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
-- @return #boolean
|
||||
|
||||
--- Deploy Handler OnAfter for AI_CARGO_HELICOPTER
|
||||
-- @function [parent=#AI_CARGO_HELICOPTER] OnAfterDeploy
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param #string From
|
||||
-- @param #string Event
|
||||
-- @param #string To
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
|
||||
--- Deploy Trigger for AI_CARGO_HELICOPTER
|
||||
-- @function [parent=#AI_CARGO_HELICOPTER] Deploy
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
|
||||
--- Deploy Asynchronous Trigger for AI_CARGO_HELICOPTER
|
||||
-- @function [parent=#AI_CARGO_HELICOPTER] __Deploy
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
-- @param #number Delay
|
||||
|
||||
|
||||
|
||||
self:SetCarrier( Helicopter )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Set the Carrier.
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
-- @return #AI_CARGO_HELICOPTER
|
||||
function AI_CARGO_HELICOPTER:SetCarrier( Helicopter )
|
||||
|
||||
local AICargo = self
|
||||
|
||||
self.Helicopter = Helicopter -- Wrapper.Unit#UNIT
|
||||
self.Helicopter:SetState( self.Helicopter, "AI_CARGO_HELICOPTER", self )
|
||||
|
||||
self.RoutePickup = false
|
||||
self.RouteDeploy = false
|
||||
|
||||
Helicopter:HandleEvent( EVENTS.Dead )
|
||||
Helicopter:HandleEvent( EVENTS.Hit )
|
||||
Helicopter:HandleEvent( EVENTS.Land )
|
||||
|
||||
function Helicopter:OnEventDead( EventData )
|
||||
local AICargoTroops = self:GetState( self, "AI_CARGO_HELICOPTER" )
|
||||
self:F({AICargoTroops=AICargoTroops})
|
||||
if AICargoTroops then
|
||||
self:F({})
|
||||
if not AICargoTroops:Is( "Loaded" ) then
|
||||
-- There are enemies within combat range. Unload the Helicopter.
|
||||
AICargoTroops:Destroyed()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Helicopter:OnEventHit( EventData )
|
||||
local AICargoTroops = self:GetState( self, "AI_CARGO_HELICOPTER" )
|
||||
if AICargoTroops then
|
||||
self:F( { OnHitLoaded = AICargoTroops:Is( "Loaded" ) } )
|
||||
if AICargoTroops:Is( "Loaded" ) or AICargoTroops:Is( "Boarding" ) then
|
||||
-- There are enemies within combat range. Unload the Helicopter.
|
||||
AICargoTroops:Unload()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function Helicopter:OnEventLand( EventData )
|
||||
AICargo:Landed()
|
||||
end
|
||||
|
||||
self.Coalition = self.Helicopter:GetCoalition()
|
||||
|
||||
self:SetControllable( Helicopter )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Find a free Carrier within a range.
|
||||
-- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
-- @param #number Radius
|
||||
-- @return Wrapper.Unit#UNIT NewCarrier
|
||||
function AI_CARGO_HELICOPTER:FindCarrier( Coordinate, Radius )
|
||||
|
||||
local CoordinateZone = ZONE_RADIUS:New( "Zone" , Coordinate:GetVec2(), Radius )
|
||||
CoordinateZone:Scan( { Object.Category.UNIT } )
|
||||
for _, DCSUnit in pairs( CoordinateZone:GetScannedUnits() ) do
|
||||
local NearUnit = UNIT:Find( DCSUnit )
|
||||
self:F({NearUnit=NearUnit})
|
||||
if not NearUnit:GetState( NearUnit, "AI_CARGO_HELICOPTER" ) then
|
||||
local Attributes = NearUnit:GetDesc()
|
||||
self:F({Desc=Attributes})
|
||||
if NearUnit:HasAttribute( "Trucks" ) then
|
||||
self:SetCarrier( NearUnit )
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
-- @param #number Speed
|
||||
function AI_CARGO_HELICOPTER:onafterLanded( Helicopter, From, Event, To )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
|
||||
if self.RoutePickup == true then
|
||||
self:Load( Helicopter:GetPointVec2() )
|
||||
self.RoutePickup = false
|
||||
end
|
||||
|
||||
if self.RouteDeploy == true then
|
||||
self:Unload()
|
||||
self.RouteDeploy = false
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
-- @param #number Speed
|
||||
function AI_CARGO_HELICOPTER:onafterPickup( Helicopter, From, Event, To, Coordinate, Speed )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
|
||||
self.RoutePickup = true
|
||||
|
||||
local Route = {}
|
||||
|
||||
--- Calculate the target route point.
|
||||
local CoordinateFrom = Helicopter:GetCoordinate()
|
||||
local CoordinateTo = Coordinate
|
||||
|
||||
--- Create a route point of type air.
|
||||
local WaypointFrom = CoordinateFrom:WaypointAir(
|
||||
"RADIO",
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
Speed,
|
||||
true
|
||||
)
|
||||
|
||||
--- Create a route point of type air.
|
||||
local WaypointTo = CoordinateTo:WaypointAir(
|
||||
"RADIO",
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
Speed,
|
||||
true
|
||||
)
|
||||
|
||||
Route[#Route+1] = WaypointFrom
|
||||
Route[#Route+1] = WaypointTo
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
Helicopter:WayPointInitialize( Route )
|
||||
|
||||
local Tasks = {}
|
||||
|
||||
Tasks[#Tasks+1] = Helicopter:TaskLandAtVec2( CoordinateTo:GetVec2() )
|
||||
Route[#Route].task = Helicopter:TaskCombo( Tasks )
|
||||
|
||||
-- Now route the helicopter
|
||||
Helicopter:Route( Route, 0.5 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
-- @param From
|
||||
-- @param Event
|
||||
-- @param To
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
-- @param #number Speed
|
||||
function AI_CARGO_HELICOPTER:onafterDeploy( Helicopter, From, Event, To, Coordinate, Speed )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
|
||||
self.RouteDeploy = true
|
||||
|
||||
local Route = {}
|
||||
|
||||
--- Calculate the target route point.
|
||||
local CoordinateFrom = Helicopter:GetCoordinate()
|
||||
local CoordinateTo = Coordinate
|
||||
|
||||
--- Create a route point of type air.
|
||||
local WaypointFrom = CoordinateFrom:WaypointAir(
|
||||
"RADIO",
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
Speed,
|
||||
true
|
||||
)
|
||||
|
||||
--- Create a route point of type air.
|
||||
local WaypointTo = CoordinateTo:WaypointAir(
|
||||
"RADIO",
|
||||
POINT_VEC3.RoutePointType.TurningPoint,
|
||||
POINT_VEC3.RoutePointAction.TurningPoint,
|
||||
Speed,
|
||||
true
|
||||
)
|
||||
|
||||
Route[#Route+1] = WaypointFrom
|
||||
Route[#Route+1] = WaypointTo
|
||||
|
||||
--- Now we're going to do something special, we're going to call a function from a waypoint action at the AIControllable...
|
||||
Helicopter:WayPointInitialize( Route )
|
||||
|
||||
local Tasks = {}
|
||||
|
||||
Tasks[#Tasks+1] = Helicopter:TaskLandAtVec2( CoordinateTo:GetVec2() )
|
||||
Route[#Route].task = Helicopter:TaskCombo( Tasks )
|
||||
|
||||
-- Now route the helicopter
|
||||
Helicopter:Route( Route, 0.5 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
function AI_CARGO_HELICOPTER:onafterLoad( Helicopter, From, Event, To, Coordinate )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
|
||||
for _, Cargo in pairs( self.CargoSet:GetSet() ) do
|
||||
if Cargo:IsInLoadRadius( Coordinate ) then
|
||||
self:__Board( 5 )
|
||||
Cargo:Board( Helicopter, 25 )
|
||||
self.Cargo = Cargo
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
function AI_CARGO_HELICOPTER:onafterBoard( Helicopter, From, Event, To )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
self:F({ IsLoaded = self.Cargo:IsLoaded() } )
|
||||
if not self.Cargo:IsLoaded() then
|
||||
self:__Board( 10 )
|
||||
else
|
||||
self:__Loaded( 1 )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
function AI_CARGO_HELICOPTER:onafterLoaded( Helicopter, From, Event, To )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
function AI_CARGO_HELICOPTER:onafterUnload( Helicopter, From, Event, To )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
self.Cargo:UnBoard()
|
||||
self:__Unboard( 10 )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
function AI_CARGO_HELICOPTER:onafterUnboard( Helicopter, From, Event, To )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
if not self.Cargo:IsUnLoaded() then
|
||||
self:__Unboard( 10 )
|
||||
else
|
||||
self:__Unloaded( 1 )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- @param #AI_CARGO_HELICOPTER self
|
||||
-- @param Wrapper.Unit#UNIT Helicopter
|
||||
function AI_CARGO_HELICOPTER:onafterUnloaded( Helicopter, From, Event, To )
|
||||
|
||||
if Helicopter and Helicopter:IsAlive() then
|
||||
self.Helicopter = Helicopter
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -155,8 +155,7 @@ do -- ACT_ASSIGN_ACCEPT
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_ACCEPT:onafterStart( ProcessUnit, From, Event, To )
|
||||
self:F( { ProcessUnit, From, Event, To } )
|
||||
function ACT_ASSIGN_ACCEPT:onafterStart( ProcessUnit, Task, From, Event, To )
|
||||
|
||||
self:__Assign( 1 )
|
||||
end
|
||||
@ -167,11 +166,8 @@ do -- ACT_ASSIGN_ACCEPT
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_ACCEPT:onenterAssigned( ProcessUnit, From, Event, To )
|
||||
self:F( { ProcessUnit, From, Event, To } )
|
||||
function ACT_ASSIGN_ACCEPT:onenterAssigned( ProcessUnit, Task, From, Event, To )
|
||||
|
||||
local ProcessGroup = ProcessUnit:GetGroup()
|
||||
|
||||
self.Task:Assign( ProcessUnit, ProcessUnit:GetPlayerName() )
|
||||
end
|
||||
|
||||
@ -192,36 +188,26 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
||||
|
||||
--- Init.
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
-- @param #string TaskName
|
||||
-- @param #string TaskBriefing
|
||||
-- @return #ACT_ASSIGN_MENU_ACCEPT self
|
||||
function ACT_ASSIGN_MENU_ACCEPT:New( TaskName, TaskBriefing )
|
||||
function ACT_ASSIGN_MENU_ACCEPT:New( TaskBriefing )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, ACT_ASSIGN:New() ) -- #ACT_ASSIGN_MENU_ACCEPT
|
||||
|
||||
self.TaskName = TaskName
|
||||
self.TaskBriefing = TaskBriefing
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function ACT_ASSIGN_MENU_ACCEPT:Init( FsmAssign )
|
||||
|
||||
self.TaskName = FsmAssign.TaskName
|
||||
self.TaskBriefing = FsmAssign.TaskBriefing
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Creates a new task assignment state machine. The process will request from the menu if it accepts the task, if not, the unit is removed from the simulator.
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
-- @param #string TaskName
|
||||
-- @param #string TaskBriefing
|
||||
-- @return #ACT_ASSIGN_MENU_ACCEPT self
|
||||
function ACT_ASSIGN_MENU_ACCEPT:Init( TaskName, TaskBriefing )
|
||||
function ACT_ASSIGN_MENU_ACCEPT:Init( TaskBriefing )
|
||||
|
||||
self.TaskBriefing = TaskBriefing
|
||||
self.TaskName = TaskName
|
||||
|
||||
return self
|
||||
end
|
||||
@ -232,30 +218,31 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterStart( ProcessUnit, From, Event, To )
|
||||
self:F( { ProcessUnit, From, Event, To } )
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterStart( ProcessUnit, Task, From, Event, To )
|
||||
|
||||
self:GetCommandCenter():MessageTypeToGroup( "Access the radio menu to accept the task. You have 30 seconds or the assignment will be cancelled.", ProcessUnit:GetGroup(), MESSAGE.Type.Information )
|
||||
self:GetCommandCenter():MessageToGroup( "Task " .. self.Task:GetName() .. " has been assigned to you and your group!\nRead the briefing and use the Radio Menu (F10) / Task ... CONFIRMATION menu to accept or reject the task.\nYou have 2 minutes to accept, or the task assignment will be cancelled!", ProcessUnit:GetGroup(), 120 )
|
||||
|
||||
local ProcessGroup = ProcessUnit:GetGroup()
|
||||
local TaskGroup = ProcessUnit:GetGroup()
|
||||
|
||||
self.Menu = MENU_GROUP:New( TaskGroup, "Task " .. self.Task:GetName() .. " CONFIRMATION" )
|
||||
self.MenuAcceptTask = MENU_GROUP_COMMAND:New( TaskGroup, "Accept task " .. self.Task:GetName(), self.Menu, self.MenuAssign, self, TaskGroup )
|
||||
self.MenuRejectTask = MENU_GROUP_COMMAND:New( TaskGroup, "Reject task " .. self.Task:GetName(), self.Menu, self.MenuReject, self, TaskGroup )
|
||||
|
||||
self.Menu = MENU_GROUP:New( ProcessGroup, "Task " .. self.TaskName .. " acceptance" )
|
||||
self.MenuAcceptTask = MENU_GROUP_COMMAND:New( ProcessGroup, "Accept task " .. self.TaskName, self.Menu, self.MenuAssign, self )
|
||||
self.MenuRejectTask = MENU_GROUP_COMMAND:New( ProcessGroup, "Reject task " .. self.TaskName, self.Menu, self.MenuReject, self )
|
||||
self:__Reject( 120, TaskGroup )
|
||||
end
|
||||
|
||||
--- Menu function.
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
function ACT_ASSIGN_MENU_ACCEPT:MenuAssign()
|
||||
function ACT_ASSIGN_MENU_ACCEPT:MenuAssign( TaskGroup )
|
||||
|
||||
self:__Assign( 1 )
|
||||
self:__Assign( -1, TaskGroup )
|
||||
end
|
||||
|
||||
--- Menu function.
|
||||
-- @param #ACT_ASSIGN_MENU_ACCEPT self
|
||||
function ACT_ASSIGN_MENU_ACCEPT:MenuReject()
|
||||
function ACT_ASSIGN_MENU_ACCEPT:MenuReject( TaskGroup )
|
||||
|
||||
self:__Reject( 1 )
|
||||
self:__Reject( -1, TaskGroup )
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
@ -264,8 +251,7 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterAssign( ProcessUnit, From, Event, To )
|
||||
self:F( { ProcessUnit.UnitNameFrom, Event, To } )
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterAssign( ProcessUnit, Task, From, Event, To, TaskGroup )
|
||||
|
||||
self.Menu:Remove()
|
||||
end
|
||||
@ -276,13 +262,25 @@ do -- ACT_ASSIGN_MENU_ACCEPT
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterReject( ProcessUnit, From, Event, To )
|
||||
self:F( { ProcessUnit.UnitName, From, Event, To } )
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onafterReject( ProcessUnit, Task, From, Event, To, TaskGroup )
|
||||
self:F( { TaskGroup = TaskGroup } )
|
||||
|
||||
self.Menu:Remove()
|
||||
--TODO: need to resolve this problem ... it has to do with the events ...
|
||||
--self.Task:UnAssignFromUnit( ProcessUnit )needs to become a callback funtion call upon the event
|
||||
ProcessUnit:Destroy()
|
||||
self.Task:RejectGroup( TaskGroup )
|
||||
end
|
||||
|
||||
--- StateMachine callback function
|
||||
-- @param #ACT_ASSIGN_ACCEPT self
|
||||
-- @param Wrapper.Unit#UNIT ProcessUnit
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ASSIGN_MENU_ACCEPT:onenterAssigned( ProcessUnit, Task, From, Event, To, TaskGroup )
|
||||
|
||||
--self.Task:AssignToGroup( TaskGroup )
|
||||
self.Task:Assign( ProcessUnit, ProcessUnit:GetPlayerName() )
|
||||
end
|
||||
|
||||
end -- ACT_ASSIGN_MENU_ACCEPT
|
||||
|
||||
@ -123,9 +123,7 @@ do -- ACT_ROUTE
|
||||
--- Set a Cancel Menu item.
|
||||
-- @param #ACT_ROUTE self
|
||||
-- @return #ACT_ROUTE
|
||||
function ACT_ROUTE:SetMenuCancel( MenuGroup, MenuText, ParentMenu )
|
||||
|
||||
local MenuTime = timer.getTime() + 1
|
||||
function ACT_ROUTE:SetMenuCancel( MenuGroup, MenuText, ParentMenu, MenuTime, MenuTag )
|
||||
|
||||
self.CancelMenuGroupCommand = MENU_GROUP_COMMAND:New(
|
||||
MenuGroup,
|
||||
@ -133,10 +131,11 @@ do -- ACT_ROUTE
|
||||
ParentMenu,
|
||||
self.MenuCancel,
|
||||
self
|
||||
):SetTime( MenuTime )
|
||||
):SetTime( MenuTime ):SetTag( MenuTag )
|
||||
|
||||
ParentMenu:SetTime( MenuTime )
|
||||
ParentMenu:Remove( MenuTime )
|
||||
|
||||
ParentMenu:Remove( MenuTime, MenuTag )
|
||||
|
||||
return self
|
||||
end
|
||||
@ -245,10 +244,8 @@ do -- ACT_ROUTE
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function ACT_ROUTE:onbeforeRoute( ProcessUnit, From, Event, To )
|
||||
self:F( { "BeforeRoute 1", self.DisplayCount, self.DisplayInterval } )
|
||||
|
||||
if ProcessUnit:IsAlive() then
|
||||
self:F( "BeforeRoute 2" )
|
||||
local HasArrived = self:onfuncHasArrived( ProcessUnit ) -- Polymorphic
|
||||
if self.DisplayCount >= self.DisplayInterval then
|
||||
self:T( { HasArrived = HasArrived } )
|
||||
@ -260,8 +257,6 @@ do -- ACT_ROUTE
|
||||
self.DisplayCount = self.DisplayCount + 1
|
||||
end
|
||||
|
||||
self:T( { DisplayCount = self.DisplayCount } )
|
||||
|
||||
if HasArrived then
|
||||
self:__Arrive( 1 )
|
||||
else
|
||||
@ -344,7 +339,7 @@ do -- ACT_ROUTE_POINT
|
||||
-- @param #ACT_ROUTE_POINT self
|
||||
-- @param #number Range The Range to consider the arrival. Default is 10000 meters.
|
||||
function ACT_ROUTE_POINT:SetRange( Range )
|
||||
self:F2( { self.Range } )
|
||||
self:F2( { Range } )
|
||||
self.Range = Range or 10000
|
||||
end
|
||||
|
||||
@ -352,6 +347,7 @@ do -- ACT_ROUTE_POINT
|
||||
-- @param #ACT_ROUTE_POINT self
|
||||
-- @return #number The Range to consider the arrival. Default is 10000 meters.
|
||||
function ACT_ROUTE_POINT:GetRange()
|
||||
self:F2( { self.Range } )
|
||||
return self.Range
|
||||
end
|
||||
|
||||
|
||||
@ -257,6 +257,7 @@ do -- CARGO
|
||||
self:AddTransition( "*", "Damaged", "Damaged" )
|
||||
self:AddTransition( "*", "Destroyed", "Destroyed" )
|
||||
self:AddTransition( "*", "Respawn", "UnLoaded" )
|
||||
self:AddTransition( "*", "Reset", "UnLoaded" )
|
||||
|
||||
self.Type = Type
|
||||
self.Name = Name
|
||||
@ -267,8 +268,7 @@ do -- CARGO
|
||||
self.Slingloadable = false
|
||||
self.Moveable = false
|
||||
self.Containable = false
|
||||
self.LoadAction = ""
|
||||
|
||||
|
||||
self.CargoLimit = 0
|
||||
|
||||
self.LoadRadius = LoadRadius or 500
|
||||
@ -368,6 +368,14 @@ do -- CARGO
|
||||
end
|
||||
|
||||
|
||||
--- Get the transportation method of the Cargo.
|
||||
-- @param #CARGO self
|
||||
-- @return #string The transportation method of the Cargo.
|
||||
function CARGO:GetTransportationMethod()
|
||||
return self.TransportationMethod
|
||||
end
|
||||
|
||||
|
||||
--- Get the coalition of the Cargo.
|
||||
-- @param #CARGO self
|
||||
-- @return Coalition
|
||||
@ -602,7 +610,7 @@ do -- CARGO
|
||||
-- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision).
|
||||
-- @return #boolean
|
||||
function CARGO:IsNear( PointVec2, NearRadius )
|
||||
self:F2( { PointVec2 = PointVec2, NearRadius = NearRadius } )
|
||||
--self:F2( { PointVec2 = PointVec2, NearRadius = NearRadius } )
|
||||
|
||||
if self.CargoObject:IsAlive() then
|
||||
--local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
|
||||
@ -613,12 +621,12 @@ do -- CARGO
|
||||
--self:F( Distance )
|
||||
|
||||
if Distance <= NearRadius then
|
||||
self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = true } )
|
||||
--self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = true } )
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = false } )
|
||||
--self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = false } )
|
||||
return false
|
||||
end
|
||||
|
||||
@ -629,12 +637,12 @@ do -- CARGO
|
||||
-- @param Core.Zone#ZONE_BASE Zone
|
||||
-- @return #boolean **true** if cargo is in the Zone, **false** if cargo is not in the Zone.
|
||||
function CARGO:IsInZone( Zone )
|
||||
self:F( { Zone } )
|
||||
--self:F( { Zone } )
|
||||
|
||||
if self:IsLoaded() then
|
||||
return Zone:IsPointVec2InZone( self.CargoCarrier:GetPointVec2() )
|
||||
else
|
||||
self:F( { Size = self.CargoObject:GetSize(), Units = self.CargoObject:GetUnits() } )
|
||||
--self:F( { Size = self.CargoObject:GetSize(), Units = self.CargoObject:GetUnits() } )
|
||||
if self.CargoObject:GetSize() ~= 0 then
|
||||
return Zone:IsPointVec2InZone( self.CargoObject:GetPointVec2() )
|
||||
else
|
||||
@ -747,6 +755,22 @@ do -- CARGO
|
||||
self.Reported[CarrierGroup] = nil
|
||||
end
|
||||
|
||||
--- Respawn the cargo when destroyed
|
||||
-- @param #CARGO self
|
||||
-- @param #boolean RespawnDestroyed
|
||||
function CARGO:RespawnOnDestroyed( RespawnDestroyed )
|
||||
|
||||
if RespawnDestroyed then
|
||||
self.onenterDestroyed = function( self )
|
||||
self:Respawn()
|
||||
end
|
||||
else
|
||||
self.onenterDestroyed = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
end -- CARGO
|
||||
@ -785,7 +809,7 @@ do -- CARGO_REPRESENTABLE
|
||||
|
||||
-- Cargo objects are deleted from the _DATABASE and SET_CARGO objects.
|
||||
self:F( { CargoName = self:GetName() } )
|
||||
_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
||||
--_EVENTDISPATCHER:CreateEventDeleteCargo( self )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -49,10 +49,8 @@ do -- CARGO_CRATE
|
||||
local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_CRATE
|
||||
self:F( { Type, Name, NearRadius } )
|
||||
|
||||
self.CargoObject = CargoStatic
|
||||
self.CargoObject = CargoStatic -- Wrapper.Static#STATIC
|
||||
|
||||
self:T( self.ClassName )
|
||||
|
||||
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
|
||||
_EVENTDISPATCHER:CreateEventNewCargo( self )
|
||||
|
||||
@ -65,6 +63,35 @@ do -- CARGO_CRATE
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #CARGO_CRATE self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function CARGO_CRATE:OnEventCargoDead( EventData )
|
||||
|
||||
local Destroyed = false
|
||||
|
||||
if self:IsDestroyed() or self:IsUnLoaded() or self:IsBoarding() then
|
||||
if self.CargoObject:GetName() == EventData.IniUnitName then
|
||||
if not self.NoDestroy then
|
||||
Destroyed = true
|
||||
end
|
||||
end
|
||||
else
|
||||
if self:IsLoaded() then
|
||||
local CarrierName = self.CargoCarrier:GetName()
|
||||
if CarrierName == EventData.IniDCSUnitName then
|
||||
MESSAGE:New( "Cargo is lost from carrier " .. CarrierName, 15 ):ToAll()
|
||||
Destroyed = true
|
||||
self.CargoCarrier:ClearCargo()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Destroyed then
|
||||
self:I( { "Cargo crate destroyed: " .. self.CargoObject:GetName() } )
|
||||
self:Destroyed()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Enter UnLoaded State.
|
||||
@ -74,7 +101,7 @@ do -- CARGO_CRATE
|
||||
-- @param #string To
|
||||
-- @param Core.Point#POINT_VEC2
|
||||
function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 )
|
||||
self:F( { ToPointVec2, From, Event, To } )
|
||||
--self:F( { ToPointVec2, From, Event, To } )
|
||||
|
||||
local Angle = 180
|
||||
local Speed = 10
|
||||
@ -90,7 +117,7 @@ do -- CARGO_CRATE
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn( ToPointVec2, 0 )
|
||||
self.CargoObject:ReSpawnAt( ToPointVec2, 0 )
|
||||
self.CargoCarrier = nil
|
||||
end
|
||||
|
||||
@ -111,14 +138,17 @@ do -- CARGO_CRATE
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function CARGO_CRATE:onenterLoaded( From, Event, To, CargoCarrier )
|
||||
self:F( { From, Event, To, CargoCarrier } )
|
||||
--self:F( { From, Event, To, CargoCarrier } )
|
||||
|
||||
self.CargoCarrier = CargoCarrier
|
||||
|
||||
-- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects).
|
||||
if self.CargoObject then
|
||||
self:T("Destroying")
|
||||
self.NoDestroy = true
|
||||
self.CargoObject:Destroy()
|
||||
--local Coordinate = self.CargoObject:GetCoordinate():GetRandomCoordinateInRadius( 50, 20 )
|
||||
--self.CargoObject:ReSpawnAt( Coordinate, 0 )
|
||||
end
|
||||
end
|
||||
|
||||
@ -139,12 +169,12 @@ do -- CARGO_CRATE
|
||||
-- @param Core.Point#Coordinate Coordinate
|
||||
-- @return #boolean true if the Cargo Crate is within the report radius.
|
||||
function CARGO_CRATE:IsInReportRadius( Coordinate )
|
||||
self:F( { Coordinate, LoadRadius = self.LoadRadius } )
|
||||
--self:F( { Coordinate, LoadRadius = self.LoadRadius } )
|
||||
|
||||
local Distance = 0
|
||||
if self:IsUnLoaded() then
|
||||
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
|
||||
self:T( Distance )
|
||||
--self:T( Distance )
|
||||
if Distance <= self.LoadRadius then
|
||||
return true
|
||||
end
|
||||
@ -159,12 +189,12 @@ do -- CARGO_CRATE
|
||||
-- @param Core.Point#Coordinate Coordinate
|
||||
-- @return #boolean true if the Cargo Crate is within the loading radius.
|
||||
function CARGO_CRATE:IsInLoadRadius( Coordinate )
|
||||
self:F( { Coordinate, LoadRadius = self.NearRadius } )
|
||||
--self:F( { Coordinate, LoadRadius = self.NearRadius } )
|
||||
|
||||
local Distance = 0
|
||||
if self:IsUnLoaded() then
|
||||
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
|
||||
self:T( Distance )
|
||||
--self:T( Distance )
|
||||
if Distance <= self.NearRadius then
|
||||
return true
|
||||
end
|
||||
@ -180,7 +210,7 @@ do -- CARGO_CRATE
|
||||
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
|
||||
-- @return #nil There is no valid Cargo in the CargoGroup.
|
||||
function CARGO_CRATE:GetCoordinate()
|
||||
self:F()
|
||||
--self:F()
|
||||
|
||||
return self.CargoObject:GetCoordinate()
|
||||
end
|
||||
@ -228,17 +258,59 @@ do -- CARGO_CRATE
|
||||
return self:IsNear( CargoCarrier:GetCoordinate(), NearRadius )
|
||||
end
|
||||
|
||||
|
||||
--- Respawn the CargoGroup.
|
||||
-- @param #CARGO_CRATE self
|
||||
function CARGO_CRATE:Respawn()
|
||||
|
||||
self:F( { "Respawning" } )
|
||||
self:F( { "Respawning crate " .. self:GetName() } )
|
||||
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn() -- A cargo destroy crates a DEAD event.
|
||||
self:__Reset( -0.1 )
|
||||
end
|
||||
|
||||
self:SetDeployed( false )
|
||||
self:SetStartState( "UnLoaded" )
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Respawn the CargoGroup.
|
||||
-- @param #CARGO_CRATE self
|
||||
function CARGO_CRATE:onafterReset()
|
||||
|
||||
self:F( { "Reset crate " .. self:GetName() } )
|
||||
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self:SetDeployed( false )
|
||||
self:SetStartState( "UnLoaded" )
|
||||
self.CargoCarrier = nil
|
||||
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
|
||||
_EVENTDISPATCHER:CreateEventNewCargo( self )
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- Get the transportation method of the Cargo.
|
||||
-- @param #CARGO_CRATE self
|
||||
-- @return #string The transportation method of the Cargo.
|
||||
function CARGO_CRATE:GetTransportationMethod()
|
||||
if self:IsLoaded() then
|
||||
return "for unloading"
|
||||
else
|
||||
if self:IsUnLoaded() then
|
||||
return "for loading"
|
||||
else
|
||||
if self:IsDeployed() then
|
||||
return "delivered"
|
||||
end
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -38,82 +38,82 @@ do -- CARGO_GROUP
|
||||
ClassName = "CARGO_GROUP",
|
||||
}
|
||||
|
||||
--- CARGO_GROUP constructor.
|
||||
-- This make a new CARGO_GROUP from a @{Group} object.
|
||||
-- It will "ungroup" the group object within the sim, and will create a @{Set} of individual Unit objects.
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @param Wrapper.Group#GROUP CargoGroup
|
||||
-- @param #string Type
|
||||
-- @param #string Name
|
||||
-- @param #number LoadRadius (optional)
|
||||
-- @param #number NearRadius (optional)
|
||||
-- @return #CARGO_GROUP
|
||||
function CARGO_GROUP:New( CargoGroup, Type, Name, LoadRadius )
|
||||
local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, LoadRadius ) ) -- #CARGO_GROUP
|
||||
self:F( { Type, Name, LoadRadius } )
|
||||
|
||||
self.CargoSet = SET_CARGO:New()
|
||||
--- CARGO_GROUP constructor.
|
||||
-- This make a new CARGO_GROUP from a @{Group} object.
|
||||
-- It will "ungroup" the group object within the sim, and will create a @{Set} of individual Unit objects.
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @param Wrapper.Group#GROUP CargoGroup
|
||||
-- @param #string Type
|
||||
-- @param #string Name
|
||||
-- @param #number LoadRadius (optional)
|
||||
-- @param #number NearRadius (optional)
|
||||
-- @return #CARGO_GROUP
|
||||
function CARGO_GROUP:New( CargoGroup, Type, Name, LoadRadius )
|
||||
local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, LoadRadius ) ) -- #CARGO_GROUP
|
||||
self:F( { Type, Name, LoadRadius } )
|
||||
|
||||
self:SetDeployed( false )
|
||||
|
||||
local WeightGroup = 0
|
||||
|
||||
self.GroupName = CargoGroup:GetName()
|
||||
self.CargoTemplate = UTILS.DeepCopy( _DATABASE:GetGroupTemplate( self.GroupName ) )
|
||||
|
||||
CargoGroup:Destroy()
|
||||
|
||||
-- We iterate through the group template and for each unit in the template, we create a new group with one unit.
|
||||
for UnitID, UnitTemplate in pairs( self.CargoTemplate.units ) do
|
||||
self.CargoSet = SET_CARGO:New()
|
||||
|
||||
local GroupTemplate = UTILS.DeepCopy( self.CargoTemplate )
|
||||
local GroupName = env.getValueDictByKey( GroupTemplate.name )
|
||||
self:SetDeployed( false )
|
||||
|
||||
-- We create a new group object with one unit...
|
||||
-- First we prepare the template...
|
||||
GroupTemplate.name = GroupName .. "#CARGO#" .. UnitID
|
||||
GroupTemplate.groupId = nil
|
||||
GroupTemplate.units = {}
|
||||
GroupTemplate.units[1] = UnitTemplate
|
||||
local UnitName = UnitTemplate.name .. "#CARGO"
|
||||
GroupTemplate.units[1].name = UnitTemplate.name .. "#CARGO"
|
||||
|
||||
|
||||
-- Then we register the new group in the database
|
||||
local CargoGroup = GROUP:NewTemplate( GroupTemplate, GroupTemplate.CoalitionID, GroupTemplate.CategoryID, GroupTemplate.CountryID)
|
||||
local WeightGroup = 0
|
||||
|
||||
-- Now we spawn the new group based on the template created.
|
||||
_DATABASE:Spawn( GroupTemplate )
|
||||
self.GroupName = CargoGroup:GetName()
|
||||
self.CargoTemplate = UTILS.DeepCopy( _DATABASE:GetGroupTemplate( self.GroupName ) )
|
||||
|
||||
-- And we register the spawned unit as part of the CargoSet.
|
||||
local Unit = UNIT:FindByName( UnitName )
|
||||
--local WeightUnit = Unit:GetDesc().massEmpty
|
||||
--WeightGroup = WeightGroup + WeightUnit
|
||||
local CargoUnit = CARGO_UNIT:New( Unit, Type, UnitName, 10 )
|
||||
self.CargoSet:Add( UnitName, CargoUnit )
|
||||
CargoGroup:Destroy()
|
||||
|
||||
-- We iterate through the group template and for each unit in the template, we create a new group with one unit.
|
||||
for UnitID, UnitTemplate in pairs( self.CargoTemplate.units ) do
|
||||
|
||||
local GroupTemplate = UTILS.DeepCopy( self.CargoTemplate )
|
||||
local GroupName = env.getValueDictByKey( GroupTemplate.name )
|
||||
|
||||
-- We create a new group object with one unit...
|
||||
-- First we prepare the template...
|
||||
GroupTemplate.name = GroupName .. "#CARGO#" .. UnitID
|
||||
GroupTemplate.groupId = nil
|
||||
GroupTemplate.units = {}
|
||||
GroupTemplate.units[1] = UnitTemplate
|
||||
local UnitName = UnitTemplate.name .. "#CARGO"
|
||||
GroupTemplate.units[1].name = UnitTemplate.name .. "#CARGO"
|
||||
|
||||
|
||||
-- Then we register the new group in the database
|
||||
local CargoGroup = GROUP:NewTemplate( GroupTemplate, GroupTemplate.CoalitionID, GroupTemplate.CategoryID, GroupTemplate.CountryID)
|
||||
|
||||
-- Now we spawn the new group based on the template created.
|
||||
_DATABASE:Spawn( GroupTemplate )
|
||||
|
||||
-- And we register the spawned unit as part of the CargoSet.
|
||||
local Unit = UNIT:FindByName( UnitName )
|
||||
--local WeightUnit = Unit:GetDesc().massEmpty
|
||||
--WeightGroup = WeightGroup + WeightUnit
|
||||
local CargoUnit = CARGO_UNIT:New( Unit, Type, UnitName, 10 )
|
||||
self.CargoSet:Add( UnitName, CargoUnit )
|
||||
end
|
||||
|
||||
|
||||
self:SetWeight( WeightGroup )
|
||||
self.CargoLimit = 10
|
||||
|
||||
self:T( { "Weight Cargo", WeightGroup } )
|
||||
|
||||
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
|
||||
_EVENTDISPATCHER:CreateEventNewCargo( self )
|
||||
|
||||
self:HandleEvent( EVENTS.Dead, self.OnEventCargoDead )
|
||||
self:HandleEvent( EVENTS.Crash, self.OnEventCargoDead )
|
||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self.OnEventCargoDead )
|
||||
|
||||
self:SetEventPriority( 4 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
self:SetWeight( WeightGroup )
|
||||
self.CargoLimit = 10
|
||||
|
||||
self:T( { "Weight Cargo", WeightGroup } )
|
||||
|
||||
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
|
||||
_EVENTDISPATCHER:CreateEventNewCargo( self )
|
||||
|
||||
self:HandleEvent( EVENTS.Dead, self.OnEventCargoDead )
|
||||
self:HandleEvent( EVENTS.Crash, self.OnEventCargoDead )
|
||||
self:HandleEvent( EVENTS.PlayerLeaveUnit, self.OnEventCargoDead )
|
||||
|
||||
self:SetEventPriority( 4 )
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
--- @param #CARGO_GROUP self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
--- @param #CARGO_GROUP self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
|
||||
local Destroyed = false
|
||||
|
||||
@ -150,7 +150,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_GROUP:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { CargoCarrier.UnitName, From, Event, To } )
|
||||
--self:F( { CargoCarrier.UnitName, From, Event, To } )
|
||||
|
||||
local NearRadius = NearRadius or 25
|
||||
|
||||
@ -175,7 +175,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_GROUP:onenterLoaded( From, Event, To, CargoCarrier, ... )
|
||||
self:F( { From, Event, To, CargoCarrier, ...} )
|
||||
--self:F( { From, Event, To, CargoCarrier, ...} )
|
||||
|
||||
if From == "UnLoaded" then
|
||||
-- For each Cargo object within the CARGO_GROUP, load each cargo to the CargoCarrier.
|
||||
@ -196,7 +196,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_GROUP:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { CargoCarrier.UnitName, From, Event, To } )
|
||||
--self:F( { CargoCarrier.UnitName, From, Event, To } )
|
||||
|
||||
local NearRadius = NearRadius or 100
|
||||
|
||||
@ -259,7 +259,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_GROUP:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
|
||||
self:F( {From, Event, To, ToPointVec2, NearRadius } )
|
||||
--self:F( {From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
NearRadius = NearRadius or 25
|
||||
|
||||
@ -293,7 +293,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_GROUP:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
|
||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
--self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
--local NearRadius = NearRadius or 25
|
||||
|
||||
@ -330,7 +330,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_GROUP:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius, ... )
|
||||
self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
--self:F( { From, Event, To, ToPointVec2, NearRadius } )
|
||||
|
||||
--local NearRadius = NearRadius or 25
|
||||
|
||||
@ -346,7 +346,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function CARGO_GROUP:onenterUnLoaded( From, Event, To, ToPointVec2, ... )
|
||||
self:F( { From, Event, To, ToPointVec2 } )
|
||||
--self:F( { From, Event, To, ToPointVec2 } )
|
||||
|
||||
if From == "Loaded" then
|
||||
|
||||
@ -364,22 +364,6 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
end
|
||||
|
||||
|
||||
--- Respawn the cargo when destroyed
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @param #boolean RespawnDestroyed
|
||||
function CARGO_GROUP:RespawnOnDestroyed( RespawnDestroyed )
|
||||
self:F({"In function RespawnOnDestroyed"})
|
||||
if RespawnDestroyed then
|
||||
self.onenterDestroyed = function( self )
|
||||
self:F("IN FUNCTION")
|
||||
self:Respawn()
|
||||
end
|
||||
else
|
||||
self.onenterDestroyed = nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Get the current Coordinate of the CargoGroup.
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
|
||||
@ -426,7 +410,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
function CARGO_GROUP:RouteTo( Coordinate )
|
||||
self:F( {Coordinate = Coordinate } )
|
||||
--self:F( {Coordinate = Coordinate } )
|
||||
|
||||
-- For each Cargo within the CargoSet, route each object to the Coordinate
|
||||
self.CargoSet:ForEach(
|
||||
@ -445,7 +429,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @return #boolean The Cargo is near to the Carrier.
|
||||
-- @return #nil The Cargo is not near to the Carrier.
|
||||
function CARGO_GROUP:IsNear( CargoCarrier, NearRadius )
|
||||
self:F( {NearRadius = NearRadius } )
|
||||
--self:F( {NearRadius = NearRadius } )
|
||||
|
||||
local Cargo = self.CargoSet:GetFirst() -- #CARGO
|
||||
|
||||
@ -461,7 +445,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param Core.Point#Coordinate Coordinate
|
||||
-- @return #boolean true if the Cargo Group is within the load radius.
|
||||
function CARGO_GROUP:IsInLoadRadius( Coordinate )
|
||||
self:F( { Coordinate } )
|
||||
--self:F( { Coordinate } )
|
||||
|
||||
local Cargo = self.CargoSet:GetFirst() -- #CARGO
|
||||
|
||||
@ -472,7 +456,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
else
|
||||
Distance = Coordinate:DistanceFromPointVec2( Cargo.CargoObject:GetPointVec2() )
|
||||
end
|
||||
self:T( Distance )
|
||||
--self:T( Distance )
|
||||
|
||||
if Distance <= self.LoadRadius then
|
||||
return true
|
||||
@ -491,7 +475,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @param Core.Point#Coordinate Coordinate
|
||||
-- @return #boolean true if the Cargo Group is within the report radius.
|
||||
function CARGO_GROUP:IsInReportRadius( Coordinate )
|
||||
self:F( { Coordinate } )
|
||||
--self:F( { Coordinate } )
|
||||
|
||||
local Cargo = self.CargoSet:GetFirst() -- #CARGO
|
||||
|
||||
@ -499,7 +483,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
local Distance = 0
|
||||
if Cargo:IsUnLoaded() then
|
||||
Distance = Coordinate:DistanceFromPointVec2( Cargo.CargoObject:GetPointVec2() )
|
||||
self:T( Distance )
|
||||
--self:T( Distance )
|
||||
if Distance <= self.LoadRadius then
|
||||
return true
|
||||
end
|
||||
@ -588,7 +572,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
-- @return #boolean **true** if the first element of the CargoGroup is in the Zone
|
||||
-- @return #boolean **false** if there is no element of the CargoGroup in the Zone.
|
||||
function CARGO_GROUP:IsInZone( Zone )
|
||||
self:F( { Zone } )
|
||||
--self:F( { Zone } )
|
||||
|
||||
local Cargo = self.CargoSet:GetFirst() -- #CARGO
|
||||
|
||||
@ -600,4 +584,24 @@ function CARGO_GROUP:OnEventCargoDead( EventData )
|
||||
|
||||
end
|
||||
|
||||
--- Get the transportation method of the Cargo.
|
||||
-- @param #CARGO_GROUP self
|
||||
-- @return #string The transportation method of the Cargo.
|
||||
function CARGO_GROUP:GetTransportationMethod()
|
||||
if self:IsLoaded() then
|
||||
return "for unboarding"
|
||||
else
|
||||
if self:IsUnLoaded() then
|
||||
return "for boarding"
|
||||
else
|
||||
if self:IsDeployed() then
|
||||
return "delivered"
|
||||
end
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
|
||||
|
||||
end -- CARGO_GROUP
|
||||
|
||||
@ -51,8 +51,6 @@ do -- CARGO_SLINGLOAD
|
||||
|
||||
self.CargoObject = CargoStatic
|
||||
|
||||
self:T( self.ClassName )
|
||||
|
||||
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
|
||||
_EVENTDISPATCHER:CreateEventNewCargo( self )
|
||||
|
||||
@ -64,6 +62,28 @@ do -- CARGO_SLINGLOAD
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- @param #CARGO_SLINGLOAD self
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function CARGO_SLINGLOAD:OnEventCargoDead( EventData )
|
||||
|
||||
local Destroyed = false
|
||||
|
||||
if self:IsDestroyed() or self:IsUnLoaded() then
|
||||
if self.CargoObject:GetName() == EventData.IniUnitName then
|
||||
if not self.NoDestroy then
|
||||
Destroyed = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if Destroyed then
|
||||
self:I( { "Cargo crate destroyed: " .. self.CargoObject:GetName() } )
|
||||
self:Destroyed()
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Check if the cargo can be Slingloaded.
|
||||
@ -102,12 +122,11 @@ do -- CARGO_SLINGLOAD
|
||||
-- @param Core.Point#Coordinate Coordinate
|
||||
-- @return #boolean true if the Cargo Crate is within the report radius.
|
||||
function CARGO_SLINGLOAD:IsInReportRadius( Coordinate )
|
||||
self:F( { Coordinate, LoadRadius = self.LoadRadius } )
|
||||
--self:F( { Coordinate, LoadRadius = self.LoadRadius } )
|
||||
|
||||
local Distance = 0
|
||||
if self:IsUnLoaded() then
|
||||
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
|
||||
self:T( Distance )
|
||||
if Distance <= self.LoadRadius then
|
||||
return true
|
||||
end
|
||||
@ -122,12 +141,11 @@ do -- CARGO_SLINGLOAD
|
||||
-- @param Core.Point#Coordinate Coordinate
|
||||
-- @return #boolean true if the Cargo Slingload is within the loading radius.
|
||||
function CARGO_SLINGLOAD:IsInLoadRadius( Coordinate )
|
||||
self:F( { Coordinate } )
|
||||
--self:F( { Coordinate } )
|
||||
|
||||
local Distance = 0
|
||||
if self:IsUnLoaded() then
|
||||
Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() )
|
||||
self:T( Distance )
|
||||
if Distance <= self.NearRadius then
|
||||
return true
|
||||
end
|
||||
@ -143,7 +161,7 @@ do -- CARGO_SLINGLOAD
|
||||
-- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup.
|
||||
-- @return #nil There is no valid Cargo in the CargoGroup.
|
||||
function CARGO_SLINGLOAD:GetCoordinate()
|
||||
self:F()
|
||||
--self:F()
|
||||
|
||||
return self.CargoObject:GetCoordinate()
|
||||
end
|
||||
@ -173,7 +191,7 @@ do -- CARGO_SLINGLOAD
|
||||
-- @param #CARGO_SLINGLOAD self
|
||||
-- @param Core.Point#COORDINATE Coordinate
|
||||
function CARGO_SLINGLOAD:RouteTo( Coordinate )
|
||||
self:F( {Coordinate = Coordinate } )
|
||||
--self:F( {Coordinate = Coordinate } )
|
||||
|
||||
end
|
||||
|
||||
@ -186,7 +204,7 @@ do -- CARGO_SLINGLOAD
|
||||
-- @return #boolean The Cargo is near to the Carrier.
|
||||
-- @return #nil The Cargo is not near to the Carrier.
|
||||
function CARGO_SLINGLOAD:IsNear( CargoCarrier, NearRadius )
|
||||
self:F( {NearRadius = NearRadius } )
|
||||
--self:F( {NearRadius = NearRadius } )
|
||||
|
||||
return self:IsNear( CargoCarrier:GetCoordinate(), NearRadius )
|
||||
end
|
||||
@ -196,11 +214,54 @@ do -- CARGO_SLINGLOAD
|
||||
-- @param #CARGO_SLINGLOAD self
|
||||
function CARGO_SLINGLOAD:Respawn()
|
||||
|
||||
self:F( { "Respawning" } )
|
||||
--self:F( { "Respawning slingload " .. self:GetName() } )
|
||||
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn() -- A cargo destroy crates a DEAD event.
|
||||
self:__Reset( -0.1 )
|
||||
end
|
||||
|
||||
self:SetDeployed( false )
|
||||
self:SetStartState( "UnLoaded" )
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- Respawn the CargoGroup.
|
||||
-- @param #CARGO_SLINGLOAD self
|
||||
function CARGO_SLINGLOAD:onafterReset()
|
||||
|
||||
--self:F( { "Reset slingload " .. self:GetName() } )
|
||||
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self:SetDeployed( false )
|
||||
self:SetStartState( "UnLoaded" )
|
||||
self.CargoCarrier = nil
|
||||
-- Cargo objects are added to the _DATABASE and SET_CARGO objects.
|
||||
_EVENTDISPATCHER:CreateEventNewCargo( self )
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
--- Get the transportation method of the Cargo.
|
||||
-- @param #CARGO_SLINGLOAD self
|
||||
-- @return #string The transportation method of the Cargo.
|
||||
function CARGO_SLINGLOAD:GetTransportationMethod()
|
||||
if self:IsLoaded() then
|
||||
return "for sling loading"
|
||||
else
|
||||
if self:IsUnLoaded() then
|
||||
return "for sling loading"
|
||||
else
|
||||
if self:IsDeployed() then
|
||||
return "delivered"
|
||||
end
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -103,7 +103,7 @@ do -- CARGO_UNIT
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn( FromPointVec2:GetVec3(), CargoDeployHeading )
|
||||
self.CargoObject:ReSpawnAt( FromPointVec2, CargoDeployHeading )
|
||||
self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } )
|
||||
self.CargoCarrier = nil
|
||||
|
||||
@ -207,7 +207,7 @@ do -- CARGO_UNIT
|
||||
|
||||
-- Respawn the group...
|
||||
if self.CargoObject then
|
||||
self.CargoObject:ReSpawn( ToPointVec2:GetVec3(), 0 )
|
||||
self.CargoObject:ReSpawnAt( ToPointVec2, 0 )
|
||||
self.CargoCarrier = nil
|
||||
end
|
||||
|
||||
@ -285,7 +285,7 @@ do -- CARGO_UNIT
|
||||
-- @param Wrapper.Client#CLIENT CargoCarrier
|
||||
-- @param #number NearRadius
|
||||
function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||
--self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||
|
||||
|
||||
if CargoCarrier and CargoCarrier:IsAlive() and self.CargoObject and self.CargoObject:IsAlive() then
|
||||
@ -338,7 +338,7 @@ do -- CARGO_UNIT
|
||||
-- @param #string To
|
||||
-- @param Wrapper.Unit#UNIT CargoCarrier
|
||||
function CARGO_UNIT:onenterBoarding( From, Event, To, CargoCarrier, NearRadius, ... )
|
||||
self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||
--self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } )
|
||||
|
||||
local Speed = 90
|
||||
local Angle = 180
|
||||
@ -370,4 +370,22 @@ do -- CARGO_UNIT
|
||||
end
|
||||
end
|
||||
|
||||
--- Get the transportation method of the Cargo.
|
||||
-- @param #CARGO_UNIT self
|
||||
-- @return #string The transportation method of the Cargo.
|
||||
function CARGO_UNIT:GetTransportationMethod()
|
||||
if self:IsLoaded() then
|
||||
return "for unboarding"
|
||||
else
|
||||
if self:IsUnLoaded() then
|
||||
return "for boarding"
|
||||
else
|
||||
if self:IsDeployed() then
|
||||
return "delivered"
|
||||
end
|
||||
end
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
end -- CARGO_UNIT
|
||||
|
||||
@ -688,7 +688,7 @@ function DATABASE:_RegisterAirbases()
|
||||
|
||||
local DCSAirbaseName = DCSAirbase:getName()
|
||||
|
||||
self:E( { "Register Airbase:", DCSAirbaseName } )
|
||||
self:E( { "Register Airbase:", DCSAirbaseName, DCSAirbase:getID() } )
|
||||
self:AddAirbase( DCSAirbaseName )
|
||||
end
|
||||
end
|
||||
@ -719,7 +719,7 @@ function DATABASE:_EventOnBirth( Event )
|
||||
Event.IniGroup = self:FindGroup( Event.IniDCSGroupName )
|
||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||
self:E( { "PlayerName:", PlayerName } )
|
||||
if PlayerName ~= "" then
|
||||
if PlayerName then
|
||||
self:E( { "Player Joined:", PlayerName } )
|
||||
if not self.PLAYERS[PlayerName] then
|
||||
self:AddPlayer( Event.IniUnitName, PlayerName )
|
||||
@ -788,7 +788,7 @@ function DATABASE:_EventOnPlayerLeaveUnit( Event )
|
||||
if Event.IniUnit then
|
||||
if Event.IniObjectCategory == 1 then
|
||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||
if self.PLAYERS[PlayerName] then
|
||||
if PlayerName and self.PLAYERS[PlayerName] then
|
||||
self:E( { "Player Left:", PlayerName } )
|
||||
local Settings = SETTINGS:Set( PlayerName )
|
||||
Settings:RemovePlayerMenu( Event.IniUnit )
|
||||
|
||||
@ -794,6 +794,16 @@ function EVENT:onEvent( Event )
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.CARGO then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
Event.IniUnitName = Event.IniDCSUnitName
|
||||
Event.IniUnit = CARGO:FindByName( Event.IniDCSUnitName )
|
||||
Event.IniCoalition = Event.IniDCSUnit:getCoalition()
|
||||
Event.IniCategory = Event.IniDCSUnit:getDesc().category
|
||||
Event.IniTypeName = Event.IniDCSUnit:getTypeName()
|
||||
end
|
||||
|
||||
if Event.IniObjectCategory == Object.Category.SCENERY then
|
||||
Event.IniDCSUnit = Event.initiator
|
||||
Event.IniDCSUnitName = Event.IniDCSUnit:getName()
|
||||
@ -878,7 +888,7 @@ function EVENT:onEvent( Event )
|
||||
|
||||
-- Okay, we got the event from DCS. Now loop the SORTED self.EventSorted[] table for the received Event.id, and for each EventData registered, check if a function needs to be called.
|
||||
for EventClass, EventData in pairs( self.Events[Event.id][EventPriority] ) do
|
||||
|
||||
|
||||
--if Event.IniObjectCategory ~= Object.Category.STATIC then
|
||||
-- self:E( { "Evaluating: ", EventClass:GetClassNameAndID() } )
|
||||
--end
|
||||
@ -1027,6 +1037,16 @@ function EVENT:onEvent( Event )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- When cargo was deleted, it may probably be because of an S_EVENT_DEAD.
|
||||
-- However, in the loading logic, an S_EVENT_DEAD is also generated after a Destroy() call.
|
||||
-- And this is a problem because it will remove all entries from the SET_CARGOs.
|
||||
-- To prevent this from happening, the Cargo object has a flag NoDestroy.
|
||||
-- When true, the SET_CARGO won't Remove the Cargo object from the set.
|
||||
-- But we need to switch that flag off after the event handlers have been called.
|
||||
if Event.id == EVENTS.DeleteCargo then
|
||||
Event.Cargo.NoDestroy = nil
|
||||
end
|
||||
else
|
||||
self:T( { EventMeta.Text, Event } )
|
||||
end
|
||||
|
||||
@ -337,7 +337,7 @@ do -- FSM
|
||||
--- Creates a new FSM object.
|
||||
-- @param #FSM self
|
||||
-- @return #FSM
|
||||
function FSM:New( FsmT )
|
||||
function FSM:New()
|
||||
|
||||
-- Inherits from BASE
|
||||
self = BASE:Inherit( self, BASE:New() )
|
||||
@ -441,6 +441,8 @@ do -- FSM
|
||||
-- @return #table
|
||||
function FSM:GetProcesses()
|
||||
|
||||
self:F( { Processes = self._Processes } )
|
||||
|
||||
return self._Processes or {}
|
||||
end
|
||||
|
||||
@ -455,6 +457,18 @@ do -- FSM
|
||||
error( "Sub-Process from state " .. From .. " with event " .. Event .. " not found!" )
|
||||
end
|
||||
|
||||
function FSM:SetProcess( From, Event, Fsm )
|
||||
|
||||
for ProcessID, Process in pairs( self:GetProcesses() ) do
|
||||
if Process.From == From and Process.Event == Event then
|
||||
Process.fsm = Fsm
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
error( "Sub-Process from state " .. From .. " with event " .. Event .. " not found!" )
|
||||
end
|
||||
|
||||
--- Adds an End state.
|
||||
function FSM:AddEndState( State )
|
||||
|
||||
@ -557,8 +571,9 @@ do -- FSM
|
||||
end
|
||||
|
||||
|
||||
function FSM:_call_handler( handler, params, EventName )
|
||||
function FSM:_call_handler( step, trigger, params, EventName )
|
||||
|
||||
local handler = step .. trigger
|
||||
local ErrorHandler = function( errmsg )
|
||||
|
||||
env.info( "Error in SCHEDULER function:" .. errmsg )
|
||||
@ -569,64 +584,99 @@ do -- FSM
|
||||
return errmsg
|
||||
end
|
||||
if self[handler] then
|
||||
self:T2( "Calling " .. handler )
|
||||
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] )
|
||||
self._EventSchedules[EventName] = nil
|
||||
local Result, Value = xpcall( function() return self[handler]( self, unpack( params ) ) end, ErrorHandler )
|
||||
return Value
|
||||
end
|
||||
end
|
||||
|
||||
--- @param #FSM self
|
||||
function FSM._handler( self, EventName, ... )
|
||||
|
||||
local Can, to = self:can( EventName )
|
||||
local Can, To = self:can( EventName )
|
||||
|
||||
if to == "*" then
|
||||
to = self.current
|
||||
if To == "*" then
|
||||
To = self.current
|
||||
end
|
||||
|
||||
if Can then
|
||||
local from = self.current
|
||||
local params = { from, EventName, to, ... }
|
||||
local From = self.current
|
||||
local Params = { From, EventName, To, ... }
|
||||
|
||||
if self.Controllable then
|
||||
self:T( "FSM Transition for " .. self.Controllable.ControllableName .. " :" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
|
||||
if self["onleave".. From] or
|
||||
self["OnLeave".. From] or
|
||||
self["onbefore".. EventName] or
|
||||
self["OnBefore".. EventName] or
|
||||
self["onafter".. EventName] or
|
||||
self["OnAfter".. EventName] or
|
||||
self["onenter".. To] or
|
||||
self["OnEnter".. To]
|
||||
then
|
||||
if self:_call_handler( "onbefore", EventName, Params, EventName ) == false then
|
||||
self:T( "*** FSM *** Cancel" .. " *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** onbefore" .. EventName )
|
||||
return false
|
||||
else
|
||||
if self:_call_handler( "OnBefore", EventName, Params, EventName ) == false then
|
||||
self:T( "*** FSM *** Cancel" .. " *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** OnBefore" .. EventName )
|
||||
return false
|
||||
else
|
||||
if self:_call_handler( "onleave", From, Params, EventName ) == false then
|
||||
self:T( "*** FSM *** Cancel" .. " *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** onleave" .. From )
|
||||
return false
|
||||
else
|
||||
if self:_call_handler( "OnLeave", From, Params, EventName ) == false then
|
||||
self:T( "*** FSM *** Cancel" .. " *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** OnLeave" .. From )
|
||||
return false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
self:T( "FSM Transition:" .. self.current .. " --> " .. EventName .. " --> " .. to )
|
||||
end
|
||||
local ClassName = self:GetClassName()
|
||||
if ClassName == "FSM" then
|
||||
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To )
|
||||
end
|
||||
|
||||
if ( self:_call_handler("onbefore" .. EventName, params, EventName ) == false )
|
||||
or ( self:_call_handler("OnBefore" .. EventName, params, EventName ) == false )
|
||||
or ( self:_call_handler("onleave" .. from, params, EventName ) == false )
|
||||
or ( self:_call_handler("OnLeave" .. from, params, EventName ) == false ) then
|
||||
self:T( "Cancel Transition" )
|
||||
return false
|
||||
if ClassName == "FSM_TASK" then
|
||||
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** Task: " .. self.TaskName )
|
||||
end
|
||||
|
||||
if ClassName == "FSM_CONTROLLABLE" then
|
||||
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** TaskUnit: " .. self.Controllable.ControllableName .. " *** " )
|
||||
end
|
||||
|
||||
if ClassName == "FSM_PROCESS" then
|
||||
self:T( "*** FSM *** Transit *** " .. self.current .. " --> " .. EventName .. " --> " .. To .. " *** Task: " .. self.Task:GetName() .. ", TaskUnit: " .. self.Controllable.ControllableName .. " *** " )
|
||||
end
|
||||
end
|
||||
|
||||
self.current = to
|
||||
self.current = To
|
||||
|
||||
local execute = true
|
||||
|
||||
local subtable = self:_gosub( from, EventName )
|
||||
local subtable = self:_gosub( From, EventName )
|
||||
for _, sub in pairs( subtable ) do
|
||||
--if sub.nextevent then
|
||||
-- self:F2( "nextevent = " .. sub.nextevent )
|
||||
-- self[sub.nextevent]( self )
|
||||
--end
|
||||
self:T( "calling sub start event: " .. sub.StartEvent )
|
||||
self:T( "*** FSM *** Sub *** " .. sub.StartEvent )
|
||||
sub.fsm.fsmparent = self
|
||||
sub.fsm.ReturnEvents = sub.ReturnEvents
|
||||
sub.fsm[sub.StartEvent]( sub.fsm )
|
||||
execute = false
|
||||
end
|
||||
|
||||
local fsmparent, Event = self:_isendstate( to )
|
||||
local fsmparent, Event = self:_isendstate( To )
|
||||
if fsmparent and Event then
|
||||
self:F2( { "end state: ", fsmparent, Event } )
|
||||
self:_call_handler("onenter" .. to, params, EventName )
|
||||
self:_call_handler("OnEnter" .. to, params, EventName )
|
||||
self:_call_handler("onafter" .. EventName, params, EventName )
|
||||
self:_call_handler("OnAfter" .. EventName, params, EventName )
|
||||
self:_call_handler("onstatechange", params, EventName )
|
||||
self:T( "*** FSM *** End *** " .. Event )
|
||||
self:_call_handler("onenter", To, Params, EventName )
|
||||
self:_call_handler("OnEnter", To, Params, EventName )
|
||||
self:_call_handler("onafter", EventName, Params, EventName )
|
||||
self:_call_handler("OnAfter", EventName, Params, EventName )
|
||||
self:_call_handler("onstate", "change", Params, EventName )
|
||||
fsmparent[Event]( fsmparent )
|
||||
execute = false
|
||||
end
|
||||
@ -634,18 +684,17 @@ do -- FSM
|
||||
if execute then
|
||||
-- only execute the call if the From state is not equal to the To state! Otherwise this function should never execute!
|
||||
--if from ~= to then
|
||||
self:_call_handler("onenter" .. to, params, EventName )
|
||||
self:_call_handler("OnEnter" .. to, params, EventName )
|
||||
self:_call_handler("onenter", To, Params, EventName )
|
||||
self:_call_handler("OnEnter", To, Params, EventName )
|
||||
--end
|
||||
|
||||
self:_call_handler("onafter" .. EventName, params, EventName )
|
||||
self:_call_handler("OnAfter" .. EventName, params, EventName )
|
||||
self:_call_handler("onafter", EventName, Params, EventName )
|
||||
self:_call_handler("OnAfter", EventName, Params, EventName )
|
||||
|
||||
self:_call_handler("onstatechange", params, EventName )
|
||||
self:_call_handler("onstate", "change", Params, EventName )
|
||||
end
|
||||
else
|
||||
self:T( "Cannot execute transition." )
|
||||
self:T( { From = self.current, Event = EventName, To = to, Can = Can } )
|
||||
self:T( "*** FSM *** NO Transition *** " .. self.current .. " --> " .. EventName .. " --> ? " )
|
||||
end
|
||||
|
||||
return nil
|
||||
@ -691,17 +740,16 @@ do -- FSM
|
||||
function FSM:_isendstate( Current )
|
||||
local FSMParent = self.fsmparent
|
||||
if FSMParent and self.endstates[Current] then
|
||||
self:T( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||
--self:T( { state = Current, endstates = self.endstates, endstate = self.endstates[Current] } )
|
||||
FSMParent.current = Current
|
||||
local ParentFrom = FSMParent.current
|
||||
self:T( ParentFrom )
|
||||
self:T( self.ReturnEvents )
|
||||
--self:T( { ParentFrom, self.ReturnEvents } )
|
||||
local Event = self.ReturnEvents[Current]
|
||||
self:T( { ParentFrom, Event, self.ReturnEvents } )
|
||||
--self:T( { Event } )
|
||||
if Event then
|
||||
return FSMParent, Event
|
||||
else
|
||||
self:T( { "Could not find parent event name for state ", ParentFrom } )
|
||||
--self:T( { "Could not find parent event name for state ", ParentFrom } )
|
||||
end
|
||||
end
|
||||
|
||||
@ -773,10 +821,10 @@ do -- FSM_CONTROLLABLE
|
||||
-- @param #table FSMT Finite State Machine Table
|
||||
-- @param Wrapper.Controllable#CONTROLLABLE Controllable (optional) The CONTROLLABLE object that the FSM_CONTROLLABLE governs.
|
||||
-- @return #FSM_CONTROLLABLE
|
||||
function FSM_CONTROLLABLE:New( FSMT, Controllable )
|
||||
function FSM_CONTROLLABLE:New( Controllable )
|
||||
|
||||
-- Inherits from BASE
|
||||
local self = BASE:Inherit( self, FSM:New( FSMT ) ) -- Core.Fsm#FSM_CONTROLLABLE
|
||||
local self = BASE:Inherit( self, FSM:New() ) -- Core.Fsm#FSM_CONTROLLABLE
|
||||
|
||||
if Controllable then
|
||||
self:SetControllable( Controllable )
|
||||
@ -859,7 +907,9 @@ do -- FSM_CONTROLLABLE
|
||||
return self.Controllable
|
||||
end
|
||||
|
||||
function FSM_CONTROLLABLE:_call_handler( handler, params, EventName )
|
||||
function FSM_CONTROLLABLE:_call_handler( step, trigger, params, EventName )
|
||||
|
||||
local handler = step .. trigger
|
||||
|
||||
local ErrorHandler = function( errmsg )
|
||||
|
||||
@ -872,7 +922,7 @@ do -- FSM_CONTROLLABLE
|
||||
end
|
||||
|
||||
if self[handler] then
|
||||
self:F3( "Calling " .. handler )
|
||||
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** TaskUnit: " .. self.Controllable:GetName() )
|
||||
self._EventSchedules[EventName] = nil
|
||||
local Result, Value = xpcall( function() return self[handler]( self, self.Controllable, unpack( params ) ) end, ErrorHandler )
|
||||
return Value
|
||||
@ -909,9 +959,9 @@ do -- FSM_PROCESS
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
--self:F( Controllable )
|
||||
|
||||
|
||||
self:Assign( Controllable, Task )
|
||||
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
@ -919,7 +969,9 @@ do -- FSM_PROCESS
|
||||
self:T( "No Initialisation" )
|
||||
end
|
||||
|
||||
function FSM_PROCESS:_call_handler( handler, params, EventName )
|
||||
function FSM_PROCESS:_call_handler( step, trigger, params, EventName )
|
||||
|
||||
local handler = step .. trigger
|
||||
|
||||
local ErrorHandler = function( errmsg )
|
||||
|
||||
@ -932,9 +984,13 @@ do -- FSM_PROCESS
|
||||
end
|
||||
|
||||
if self[handler] then
|
||||
self:F3( "Calling " .. handler )
|
||||
if handler ~= "onstatechange" then
|
||||
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** Task: " .. self.Task:GetName() .. ", TaskUnit: " .. self.Controllable:GetName() )
|
||||
end
|
||||
self._EventSchedules[EventName] = nil
|
||||
local Result, Value = xpcall( function() return self[handler]( self, self.Controllable, self.Task, unpack( params ) ) end, ErrorHandler )
|
||||
if self.Controllable and self.Controllable:IsAlive() == true then
|
||||
local Result, Value = xpcall( function() return self[handler]( self, self.Controllable, self.Task, unpack( params ) ) end, ErrorHandler )
|
||||
end
|
||||
return Value
|
||||
--return self[handler]( self, self.Controllable, unpack( params ) )
|
||||
end
|
||||
@ -950,7 +1006,7 @@ do -- FSM_PROCESS
|
||||
local NewFsm = self:New( Controllable, Task ) -- Core.Fsm#FSM_PROCESS
|
||||
|
||||
NewFsm:Assign( Controllable, Task )
|
||||
|
||||
|
||||
-- Polymorphic call to initialize the new FSM_PROCESS based on self FSM_PROCESS
|
||||
NewFsm:Init( self )
|
||||
|
||||
@ -1041,21 +1097,21 @@ do -- FSM_PROCESS
|
||||
-- TODO: Need to check and fix that an FSM_PROCESS is only for a UNIT. Not for a GROUP.
|
||||
|
||||
--- Send a message of the @{Task} to the Group of the Unit.
|
||||
-- @param #FSM_PROCESS self
|
||||
function FSM_PROCESS:Message( Message )
|
||||
self:F( { Message = Message } )
|
||||
|
||||
local CC = self:GetCommandCenter()
|
||||
local TaskGroup = self.Controllable:GetGroup()
|
||||
-- @param #FSM_PROCESS self
|
||||
function FSM_PROCESS:Message( Message )
|
||||
self:F( { Message = Message } )
|
||||
|
||||
local PlayerName = self.Controllable:GetPlayerName() -- Only for a unit
|
||||
PlayerName = PlayerName and " (" .. PlayerName .. ")" or "" -- If PlayerName is nil, then keep it nil, otherwise add brackets.
|
||||
local Callsign = self.Controllable:GetCallsign()
|
||||
local Prefix = Callsign and " @ " .. Callsign .. PlayerName or ""
|
||||
|
||||
Message = Prefix .. ": " .. Message
|
||||
CC:MessageToGroup( Message, TaskGroup )
|
||||
end
|
||||
local CC = self:GetCommandCenter()
|
||||
local TaskGroup = self.Controllable:GetGroup()
|
||||
|
||||
local PlayerName = self.Controllable:GetPlayerName() -- Only for a unit
|
||||
PlayerName = PlayerName and " (" .. PlayerName .. ")" or "" -- If PlayerName is nil, then keep it nil, otherwise add brackets.
|
||||
local Callsign = self.Controllable:GetCallsign()
|
||||
local Prefix = Callsign and " @ " .. Callsign .. PlayerName or ""
|
||||
|
||||
Message = Prefix .. ": " .. Message
|
||||
CC:MessageToGroup( Message, TaskGroup )
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -1076,14 +1132,16 @@ end
|
||||
return self
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterAssigned( ProcessUnit )
|
||||
self:T( "Assign" )
|
||||
-- function FSM_PROCESS:onenterAssigned( ProcessUnit, Task, From, Event, To )
|
||||
--
|
||||
-- if From( "Planned" ) then
|
||||
-- self:T( "*** FSM *** Assign *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
||||
-- self.Task:Assign()
|
||||
-- end
|
||||
-- end
|
||||
|
||||
self.Task:Assign()
|
||||
end
|
||||
|
||||
function FSM_PROCESS:onenterFailed( ProcessUnit )
|
||||
self:T( "Failed" )
|
||||
function FSM_PROCESS:onenterFailed( ProcessUnit, Task, From, Event, To )
|
||||
self:T( "*** FSM *** Failed *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
||||
|
||||
self.Task:Fail()
|
||||
end
|
||||
@ -1095,14 +1153,17 @@ end
|
||||
-- @param #string Event
|
||||
-- @param #string From
|
||||
-- @param #string To
|
||||
function FSM_PROCESS:onstatechange( ProcessUnit, Task, From, Event, To, Dummy )
|
||||
self:T( { ProcessUnit:GetName(), From, Event, To, Dummy, self:IsTrace() } )
|
||||
function FSM_PROCESS:onstatechange( ProcessUnit, Task, From, Event, To )
|
||||
|
||||
if self:IsTrace() then
|
||||
--MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
|
||||
if From ~= To then
|
||||
self:T( "*** FSM *** Change *** " .. Task:GetName() .. "/" .. ProcessUnit:GetName() .. " *** " .. From .. " --> " .. Event .. " --> " .. To )
|
||||
end
|
||||
|
||||
self:T( { Scores = self._Scores, To = To } )
|
||||
-- if self:IsTrace() then
|
||||
-- MESSAGE:New( "@ Process " .. self:GetClassNameAndID() .. " : " .. Event .. " changed to state " .. To, 2 ):ToAll()
|
||||
-- self:F2( { Scores = self._Scores, To = To } )
|
||||
-- end
|
||||
|
||||
-- TODO: This needs to be reworked with a callback functions allocated within Task, and set within the mission script from the Task Objects...
|
||||
if self._Scores[To] then
|
||||
|
||||
@ -1137,22 +1198,23 @@ do -- FSM_TASK
|
||||
|
||||
--- Creates a new FSM_TASK object.
|
||||
-- @param #FSM_TASK self
|
||||
-- @param #table FSMT
|
||||
-- @param Tasking.Task#TASK Task
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param #string TaskName The name of the task.
|
||||
-- @return #FSM_TASK
|
||||
function FSM_TASK:New( FSMT )
|
||||
function FSM_TASK:New( TaskName )
|
||||
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New( FSMT ) ) -- Core.Fsm#FSM_TASK
|
||||
local self = BASE:Inherit( self, FSM_CONTROLLABLE:New() ) -- Core.Fsm#FSM_TASK
|
||||
|
||||
self["onstatechange"] = self.OnStateChange
|
||||
self.TaskName = TaskName
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
function FSM_TASK:_call_handler( handler, params, EventName )
|
||||
function FSM_TASK:_call_handler( step, trigger, params, EventName )
|
||||
local handler = step .. trigger
|
||||
|
||||
if self[handler] then
|
||||
self:T( "Calling " .. handler )
|
||||
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] .. " *** Task: " .. self.TaskName )
|
||||
self._EventSchedules[EventName] = nil
|
||||
return self[handler]( self, unpack( params ) )
|
||||
end
|
||||
@ -1214,9 +1276,10 @@ do -- FSM_SET
|
||||
return self.Controllable
|
||||
end
|
||||
|
||||
function FSM_SET:_call_handler( handler, params, EventName )
|
||||
function FSM_SET:_call_handler( step, trigger, params, EventName )
|
||||
local handler = step .. trigger
|
||||
if self[handler] then
|
||||
self:T( "Calling " .. handler )
|
||||
self:T( "*** FSM *** " .. step .. " *** " .. params[1] .. " --> " .. params[2] .. " --> " .. params[3] )
|
||||
self._EventSchedules[EventName] = nil
|
||||
return self[handler]( self, self.Set, unpack( params ) )
|
||||
end
|
||||
|
||||
@ -213,6 +213,7 @@ do -- MENU_BASE
|
||||
self.Menus = {}
|
||||
self.MenuCount = 0
|
||||
self.MenuTime = timer.getTime()
|
||||
self.MenuRemoveParent = false
|
||||
|
||||
if self.ParentMenu then
|
||||
self.ParentMenu.Menus = self.ParentMenu.Menus or {}
|
||||
@ -226,14 +227,30 @@ do -- MENU_BASE
|
||||
if self.ParentMenu then
|
||||
self.ParentMenu.Menus = self.ParentMenu.Menus or {}
|
||||
self.ParentMenu.Menus[MenuText] = Menu
|
||||
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
function MENU_BASE:ClearParentMenu( MenuText )
|
||||
if self.ParentMenu and self.ParentMenu.Menus[MenuText] then
|
||||
self.ParentMenu.Menus[MenuText] = nil
|
||||
self.ParentMenu.MenuCount = self.ParentMenu.MenuCount - 1
|
||||
if self.ParentMenu.MenuCount == 0 then
|
||||
--self.ParentMenu:Remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--- Sets a @{Menu} to remove automatically the parent menu when the menu removed is the last child menu of that parent @{Menu}.
|
||||
-- @param #MENU_BASE self
|
||||
-- @param #boolean RemoveParent If true, the parent menu is automatically removed when this menu is the last child menu of that parent @{Menu}.
|
||||
-- @return #MENU_BASE
|
||||
function MENU_BASE:SetRemoveParent( RemoveParent )
|
||||
--self:F( { RemoveParent } )
|
||||
self.MenuRemoveParent = RemoveParent
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Gets a @{Menu} from a parent @{Menu}
|
||||
-- @param #MENU_BASE self
|
||||
@ -900,8 +917,8 @@ do
|
||||
self:RemoveSubMenus( MenuTime, MenuTag )
|
||||
if not MenuTime or self.MenuTime ~= MenuTime then
|
||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||
if self.MenuPath ~= nil then
|
||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
||||
end
|
||||
MENU_INDEX:ClearGroupMenu( self.Group, Path )
|
||||
@ -992,8 +1009,8 @@ do
|
||||
if GroupMenu == self then
|
||||
if not MenuTime or self.MenuTime ~= MenuTime then
|
||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||
if self.MenuPath ~= nil then
|
||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
||||
end
|
||||
MENU_INDEX:ClearGroupMenu( self.Group, Path )
|
||||
@ -1133,8 +1150,8 @@ do
|
||||
self:RemoveSubMenus( MenuTime, MenuTag )
|
||||
if not MenuTime or self.MenuTime ~= MenuTime then
|
||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||
if self.MenuPath ~= nil then
|
||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
||||
end
|
||||
MENU_INDEX:ClearGroupMenu( self.Group, Path )
|
||||
@ -1244,8 +1261,8 @@ do
|
||||
if GroupMenu == self then
|
||||
if not MenuTime or self.MenuTime ~= MenuTime then
|
||||
if ( not MenuTag ) or ( MenuTag and self.MenuTag and MenuTag == self.MenuTag ) then
|
||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||
if self.MenuPath ~= nil then
|
||||
self:F( { Group = self.GroupID, Text = self.MenuText, Path = self.MenuPath } )
|
||||
missionCommands.removeItemForGroup( self.GroupID, self.MenuPath )
|
||||
end
|
||||
MENU_INDEX:ClearGroupMenu( self.Group, Path )
|
||||
|
||||
@ -1289,7 +1289,7 @@ do -- COORDINATE
|
||||
-- @return #string The coordinate Text in the configured coordinate system.
|
||||
function COORDINATE:ToStringFromRP( ReferenceCoord, ReferenceName, Controllable, Settings ) -- R2.2
|
||||
|
||||
self:F( { ReferenceCoord = ReferenceCoord, ReferenceName = ReferenceName } )
|
||||
self:F2( { ReferenceCoord = ReferenceCoord, ReferenceName = ReferenceName } )
|
||||
|
||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||
|
||||
@ -1318,7 +1318,7 @@ do -- COORDINATE
|
||||
-- @return #string The coordinate Text in the configured coordinate system.
|
||||
function COORDINATE:ToStringA2G( Controllable, Settings ) -- R2.2
|
||||
|
||||
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||
self:F2( { Controllable = Controllable and Controllable:GetName() } )
|
||||
|
||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||
|
||||
@ -1353,7 +1353,7 @@ do -- COORDINATE
|
||||
-- @return #string The coordinate Text in the configured coordinate system.
|
||||
function COORDINATE:ToStringA2A( Controllable, Settings ) -- R2.2
|
||||
|
||||
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||
self:F2( { Controllable = Controllable and Controllable:GetName() } )
|
||||
|
||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||
|
||||
@ -1393,7 +1393,7 @@ do -- COORDINATE
|
||||
-- @return #string The coordinate Text in the configured coordinate system.
|
||||
function COORDINATE:ToString( Controllable, Settings, Task ) -- R2.2
|
||||
|
||||
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||
self:F2( { Controllable = Controllable and Controllable:GetName() } )
|
||||
|
||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||
|
||||
@ -1442,7 +1442,7 @@ do -- COORDINATE
|
||||
-- @return #string The pressure text in the configured measurement system.
|
||||
function COORDINATE:ToStringPressure( Controllable, Settings ) -- R2.3
|
||||
|
||||
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||
self:F2( { Controllable = Controllable and Controllable:GetName() } )
|
||||
|
||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||
|
||||
@ -1458,7 +1458,7 @@ do -- COORDINATE
|
||||
-- @return #string The wind text in the configured measurement system.
|
||||
function COORDINATE:ToStringWind( Controllable, Settings ) -- R2.3
|
||||
|
||||
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||
self:F2( { Controllable = Controllable and Controllable:GetName() } )
|
||||
|
||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||
|
||||
@ -1474,7 +1474,7 @@ do -- COORDINATE
|
||||
-- @return #string The temperature text in the configured measurement system.
|
||||
function COORDINATE:ToStringTemperature( Controllable, Settings ) -- R2.3
|
||||
|
||||
self:F( { Controllable = Controllable and Controllable:GetName() } )
|
||||
self:F2( { Controllable = Controllable and Controllable:GetName() } )
|
||||
|
||||
local Settings = Settings or ( Controllable and _DATABASE:GetPlayerSettings( Controllable:GetPlayerName() ) ) or _SETTINGS
|
||||
|
||||
|
||||
@ -149,6 +149,7 @@ end
|
||||
-- @param #SET_BASE self
|
||||
-- @param #string ObjectName
|
||||
function SET_BASE:Remove( ObjectName )
|
||||
self:F2( { ObjectName = ObjectName } )
|
||||
|
||||
local Object = self.Set[ObjectName]
|
||||
|
||||
@ -157,7 +158,6 @@ function SET_BASE:Remove( ObjectName )
|
||||
if Key == ObjectName then
|
||||
table.remove( self.Index, Index )
|
||||
self.Set[ObjectName] = nil
|
||||
self:Flush(self)
|
||||
break
|
||||
end
|
||||
end
|
||||
@ -173,7 +173,7 @@ end
|
||||
-- @param Core.Base#BASE Object
|
||||
-- @return Core.Base#BASE The added BASE Object.
|
||||
function SET_BASE:Add( ObjectName, Object )
|
||||
self:F3( { ObjectName = ObjectName, Object = Object } )
|
||||
self:F2( { ObjectName = ObjectName, Object = Object } )
|
||||
|
||||
-- Ensure that the existing element is removed from the Set before a new one is inserted to the Set
|
||||
if self.Set[ObjectName] then
|
||||
@ -313,10 +313,6 @@ function SET_BASE:_FilterStart()
|
||||
end
|
||||
end
|
||||
|
||||
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||
|
||||
-- Follow alive players and clients
|
||||
--self:HandleEvent( EVENTS.PlayerEnterUnit, self._EventOnPlayerEnterUnit )
|
||||
--self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnPlayerLeaveUnit )
|
||||
@ -935,6 +931,9 @@ function SET_GROUP:FilterStart()
|
||||
|
||||
if _DATABASE then
|
||||
self:_FilterStart()
|
||||
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||
end
|
||||
|
||||
|
||||
@ -1643,6 +1642,9 @@ do -- SET_UNIT
|
||||
|
||||
if _DATABASE then
|
||||
self:_FilterStart()
|
||||
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||
end
|
||||
|
||||
return self
|
||||
@ -2559,6 +2561,9 @@ do -- SET_STATIC
|
||||
|
||||
if _DATABASE then
|
||||
self:_FilterStart()
|
||||
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||
end
|
||||
|
||||
return self
|
||||
@ -3200,6 +3205,9 @@ function SET_CLIENT:FilterStart()
|
||||
|
||||
if _DATABASE then
|
||||
self:_FilterStart()
|
||||
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||
end
|
||||
|
||||
return self
|
||||
@ -3599,6 +3607,9 @@ function SET_PLAYER:FilterStart()
|
||||
|
||||
if _DATABASE then
|
||||
self:_FilterStart()
|
||||
self:HandleEvent( EVENTS.Birth, self._EventOnBirth )
|
||||
self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash )
|
||||
self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash )
|
||||
end
|
||||
|
||||
return self
|
||||
@ -4270,10 +4281,9 @@ function SET_CARGO:FilterStart() --R2.1
|
||||
|
||||
if _DATABASE then
|
||||
self:_FilterStart()
|
||||
self:HandleEvent( EVENTS.NewCargo )
|
||||
self:HandleEvent( EVENTS.DeleteCargo )
|
||||
end
|
||||
|
||||
self:HandleEvent( EVENTS.NewCargo )
|
||||
self:HandleEvent( EVENTS.DeleteCargo )
|
||||
|
||||
return self
|
||||
end
|
||||
@ -4349,7 +4359,7 @@ function SET_CARGO:IsIncludeObject( MCargo ) --R2.1
|
||||
MCargoCoalition = true
|
||||
end
|
||||
end
|
||||
self:T( { "Evaluated Coalition", MCargoCoalition } )
|
||||
self:F( { "Evaluated Coalition", MCargoCoalition } )
|
||||
MCargoInclude = MCargoInclude and MCargoCoalition
|
||||
end
|
||||
|
||||
@ -4361,7 +4371,7 @@ function SET_CARGO:IsIncludeObject( MCargo ) --R2.1
|
||||
MCargoType = true
|
||||
end
|
||||
end
|
||||
self:T( { "Evaluated Type", MCargoType } )
|
||||
self:F( { "Evaluated Type", MCargoType } )
|
||||
MCargoInclude = MCargoInclude and MCargoType
|
||||
end
|
||||
|
||||
@ -4373,7 +4383,7 @@ function SET_CARGO:IsIncludeObject( MCargo ) --R2.1
|
||||
MCargoPrefix = true
|
||||
end
|
||||
end
|
||||
self:T( { "Evaluated Prefix", MCargoPrefix } )
|
||||
self:F( { "Evaluated Prefix", MCargoPrefix } )
|
||||
MCargoInclude = MCargoInclude and MCargoPrefix
|
||||
end
|
||||
end
|
||||
@ -4387,6 +4397,8 @@ end
|
||||
-- @param Core.Event#EVENTDATA EventData
|
||||
function SET_CARGO:OnEventNewCargo( EventData ) --R2.1
|
||||
|
||||
self:F( { "New Cargo", EventData } )
|
||||
|
||||
if EventData.Cargo then
|
||||
if EventData.Cargo and self:IsIncludeObject( EventData.Cargo ) then
|
||||
self:Add( EventData.Cargo.Name , EventData.Cargo )
|
||||
@ -4403,7 +4415,18 @@ function SET_CARGO:OnEventDeleteCargo( EventData ) --R2.1
|
||||
if EventData.Cargo then
|
||||
local Cargo = _DATABASE:FindCargo( EventData.Cargo.Name )
|
||||
if Cargo and Cargo.Name then
|
||||
self:Remove( Cargo.Name )
|
||||
|
||||
-- When cargo was deleted, it may probably be because of an S_EVENT_DEAD.
|
||||
-- However, in the loading logic, an S_EVENT_DEAD is also generated after a Destroy() call.
|
||||
-- And this is a problem because it will remove all entries from the SET_CARGOs.
|
||||
-- To prevent this from happening, the Cargo object has a flag NoDestroy.
|
||||
-- When true, the SET_CARGO won't Remove the Cargo object from the set.
|
||||
-- This flag is switched off after the event handlers have been called in the EVENT class.
|
||||
self:F( { CargoNoDestroy=Cargo.NoDestroy } )
|
||||
if Cargo.NoDestroy then
|
||||
else
|
||||
self:Remove( Cargo.Name )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1880,7 +1880,10 @@ function SPAWN:_GetTemplate( SpawnTemplatePrefix )
|
||||
|
||||
local SpawnTemplate = nil
|
||||
|
||||
SpawnTemplate = routines.utils.deepCopy( _DATABASE.Templates.Groups[SpawnTemplatePrefix].Template )
|
||||
local Template = _DATABASE.Templates.Groups[SpawnTemplatePrefix].Template
|
||||
self:F( { Template = Template } )
|
||||
|
||||
SpawnTemplate = UTILS.DeepCopy( _DATABASE.Templates.Groups[SpawnTemplatePrefix].Template )
|
||||
|
||||
if SpawnTemplate == nil then
|
||||
error( 'No Template returned for SpawnTemplatePrefix = ' .. SpawnTemplatePrefix )
|
||||
@ -1902,11 +1905,12 @@ end
|
||||
function SPAWN:_Prepare( SpawnTemplatePrefix, SpawnIndex ) --R2.2
|
||||
self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix } )
|
||||
|
||||
if not self.SpawnTemplate then
|
||||
self.SpawnTemplate = self:_GetTemplate( SpawnTemplatePrefix )
|
||||
end
|
||||
-- if not self.SpawnTemplate then
|
||||
-- self.SpawnTemplate = self:_GetTemplate( SpawnTemplatePrefix )
|
||||
-- end
|
||||
|
||||
local SpawnTemplate = self.SpawnTemplate
|
||||
local SpawnTemplate = self:_GetTemplate( SpawnTemplatePrefix )
|
||||
--local SpawnTemplate = self.SpawnTemplate
|
||||
SpawnTemplate.name = self:SpawnGroupName( SpawnIndex )
|
||||
|
||||
SpawnTemplate.groupId = nil
|
||||
@ -1999,7 +2003,7 @@ function SPAWN:_RandomizeTemplate( SpawnIndex )
|
||||
if self.SpawnRandomizeTemplate then
|
||||
self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix = self.SpawnTemplatePrefixTable[ math.random( 1, #self.SpawnTemplatePrefixTable ) ]
|
||||
self.SpawnGroups[SpawnIndex].SpawnTemplate = self:_Prepare( self.SpawnGroups[SpawnIndex].SpawnTemplatePrefix, SpawnIndex )
|
||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.route = routines.utils.deepCopy( self.SpawnTemplate.route )
|
||||
self.SpawnGroups[SpawnIndex].SpawnTemplate.route = UTILS.DeepCopy( self.SpawnTemplate.route )
|
||||
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
|
||||
|
||||
@ -118,6 +118,7 @@ function SPAWNSTATIC:NewFromType( SpawnTypeName, SpawnShapeName, SpawnCategory,
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- Creates a new @{Static} at the original position.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
||||
@ -192,6 +193,70 @@ function SPAWNSTATIC:SpawnFromPointVec2( PointVec2, Heading, NewName ) --R2.1
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Creates the original @{Static} at a POINT_VEC2.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param Core.Point#POINT_VEC2 PointVec2 The 2D coordinate where to spawn the static.
|
||||
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
||||
-- @param #string (optional) The name of the new static.
|
||||
-- @return #SPAWNSTATIC
|
||||
function SPAWNSTATIC:ReSpawn()
|
||||
|
||||
local StaticTemplate = _DATABASE:GetStaticUnitTemplate( self.SpawnTemplatePrefix )
|
||||
|
||||
if StaticTemplate then
|
||||
|
||||
local CountryID = self.CountryID
|
||||
local CountryName = _DATABASE.COUNTRY_NAME[CountryID]
|
||||
|
||||
StaticTemplate.units = nil
|
||||
StaticTemplate.route = nil
|
||||
StaticTemplate.groupId = nil
|
||||
|
||||
StaticTemplate.CountryID = nil
|
||||
StaticTemplate.CoalitionID = nil
|
||||
StaticTemplate.CategoryID = nil
|
||||
|
||||
local Static = coalition.addStaticObject( CountryID, StaticTemplate )
|
||||
|
||||
return Static
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Creates the original @{Static} at a POINT_VEC2.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param Core.Point#COORDINATE Coordinate The 2D coordinate where to spawn the static.
|
||||
-- @param #number Heading The heading of the static, which is a number in degrees from 0 to 360.
|
||||
-- @return #SPAWNSTATIC
|
||||
function SPAWNSTATIC:ReSpawnAt( Coordinate, Heading )
|
||||
|
||||
local StaticTemplate = _DATABASE:GetStaticUnitTemplate( self.SpawnTemplatePrefix )
|
||||
|
||||
if StaticTemplate then
|
||||
|
||||
local CountryID = self.CountryID
|
||||
|
||||
StaticTemplate.x = Coordinate.x
|
||||
StaticTemplate.y = Coordinate.z
|
||||
|
||||
StaticTemplate.heading = Heading and ( ( Heading / 180 ) * math.pi ) or StaticTemplate.heading
|
||||
|
||||
StaticTemplate.CountryID = nil
|
||||
StaticTemplate.CoalitionID = nil
|
||||
StaticTemplate.CategoryID = nil
|
||||
|
||||
local Static = coalition.addStaticObject( CountryID, StaticTemplate )
|
||||
|
||||
return Static
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Creates a new @{Static} from a @{Zone}.
|
||||
-- @param #SPAWNSTATIC self
|
||||
-- @param Core.Zone#ZONE_BASE Zone The Zone where to spawn the static.
|
||||
|
||||
@ -510,7 +510,6 @@ do -- DETECTION_BASE
|
||||
-- @param #string Event The Event string.
|
||||
-- @param #string To The To State string.
|
||||
function DETECTION_BASE:onafterDetect(From,Event,To)
|
||||
self:F( { From, Event, To } )
|
||||
|
||||
local DetectDelay = 0.1
|
||||
self.DetectionCount = 0
|
||||
@ -533,7 +532,6 @@ do -- DETECTION_BASE
|
||||
-- @param #string To The To State string.
|
||||
-- @param Wrapper.Group#GROUP DetectionGroup The Group detecting.
|
||||
function DETECTION_BASE:onafterDetectionGroup( From, Event, To, DetectionGroup, DetectionTimeStamp )
|
||||
self:F( { From, Event, To } )
|
||||
|
||||
self.DetectionRun = self.DetectionRun + 1
|
||||
|
||||
@ -541,7 +539,7 @@ do -- DETECTION_BASE
|
||||
|
||||
if DetectionGroup:IsAlive() then
|
||||
|
||||
self:T( { "DetectionGroup is Alive", DetectionGroup:GetName() } )
|
||||
--self:T( { "DetectionGroup is Alive", DetectionGroup:GetName() } )
|
||||
|
||||
local DetectionGroupName = DetectionGroup:GetName()
|
||||
local DetectionUnit = DetectionGroup:GetUnit(1)
|
||||
@ -557,7 +555,7 @@ do -- DETECTION_BASE
|
||||
self.DetectDLINK
|
||||
)
|
||||
|
||||
self:F( DetectedTargets )
|
||||
--self:F( DetectedTargets )
|
||||
|
||||
for DetectionObjectID, Detection in pairs( DetectedTargets ) do
|
||||
local DetectedObject = Detection.object -- Dcs.DCSWrapper.Object#Object
|
||||
@ -574,7 +572,7 @@ do -- DETECTION_BASE
|
||||
self.DetectDLINK
|
||||
)
|
||||
|
||||
self:T2( { TargetIsDetected = TargetIsDetected, TargetIsVisible = TargetIsVisible, TargetLastTime = TargetLastTime, TargetKnowType = TargetKnowType, TargetKnowDistance = TargetKnowDistance, TargetLastPos = TargetLastPos, TargetLastVelocity = TargetLastVelocity } )
|
||||
--self:T2( { TargetIsDetected = TargetIsDetected, TargetIsVisible = TargetIsVisible, TargetLastTime = TargetLastTime, TargetKnowType = TargetKnowType, TargetKnowDistance = TargetKnowDistance, TargetLastPos = TargetLastPos, TargetLastVelocity = TargetLastVelocity } )
|
||||
|
||||
-- Only process if the target is visible. Detection also returns invisible units.
|
||||
--if Detection.visible == true then
|
||||
@ -596,7 +594,7 @@ do -- DETECTION_BASE
|
||||
|
||||
local DetectedUnitCategory = DetectedObject:getDesc().category
|
||||
|
||||
self:F( { "Detected Target:", DetectionGroupName, DetectedObjectName, DetectedObjectType, Distance, DetectedUnitCategory } )
|
||||
--self:F( { "Detected Target:", DetectionGroupName, DetectedObjectName, DetectedObjectType, Distance, DetectedUnitCategory } )
|
||||
|
||||
-- Calculate Acceptance
|
||||
|
||||
@ -644,7 +642,7 @@ do -- DETECTION_BASE
|
||||
local DistanceProbability = 1 - DistanceProbabilityReversed
|
||||
DistanceProbability = DistanceProbability * 30 / 300
|
||||
local Probability = math.random() -- Selects a number between 0 and 1
|
||||
self:T( { Probability, DistanceProbability } )
|
||||
--self:T( { Probability, DistanceProbability } )
|
||||
if Probability > DistanceProbability then
|
||||
DetectionAccepted = false
|
||||
end
|
||||
@ -660,7 +658,7 @@ do -- DETECTION_BASE
|
||||
AlphaAngleProbability = AlphaAngleProbability * 30 / 300
|
||||
|
||||
local Probability = math.random() -- Selects a number between 0 and 1
|
||||
self:T( { Probability, AlphaAngleProbability } )
|
||||
--self:T( { Probability, AlphaAngleProbability } )
|
||||
if Probability > AlphaAngleProbability then
|
||||
DetectionAccepted = false
|
||||
end
|
||||
@ -677,7 +675,7 @@ do -- DETECTION_BASE
|
||||
|
||||
if ZoneObject:IsPointVec2InZone( DetectedObjectVec2 ) == true then
|
||||
local Probability = math.random() -- Selects a number between 0 and 1
|
||||
self:T( { Probability, ZoneProbability } )
|
||||
--self:T( { Probability, ZoneProbability } )
|
||||
if Probability > ZoneProbability then
|
||||
DetectionAccepted = false
|
||||
break
|
||||
@ -702,7 +700,7 @@ do -- DETECTION_BASE
|
||||
self.DetectedObjects[DetectedObjectName].Distance = Distance
|
||||
self.DetectedObjects[DetectedObjectName].DetectionTimeStamp = DetectionTimeStamp
|
||||
|
||||
self:F( { DetectedObject = self.DetectedObjects[DetectedObjectName] } )
|
||||
--self:F( { DetectedObject = self.DetectedObjects[DetectedObjectName] } )
|
||||
|
||||
local DetectedUnit = UNIT:FindByName( DetectedObjectName )
|
||||
|
||||
@ -716,7 +714,7 @@ do -- DETECTION_BASE
|
||||
--end
|
||||
end
|
||||
|
||||
self:T2( self.DetectedObjects )
|
||||
--self:T2( self.DetectedObjects )
|
||||
end
|
||||
|
||||
if HasDetectedObjects then
|
||||
@ -726,7 +724,6 @@ do -- DETECTION_BASE
|
||||
end
|
||||
|
||||
if self.DetectionCount > 0 and self.DetectionRun == self.DetectionCount then
|
||||
self:T( "--> Create Detection Sets" )
|
||||
|
||||
-- First check if all DetectedObjects were detected.
|
||||
-- This is important. When there are DetectedObjects in the list, but were not detected,
|
||||
@ -766,7 +763,6 @@ do -- DETECTION_BASE
|
||||
local DetectedSet = DetectedItem.Set
|
||||
|
||||
if DetectedSet:Count() == 0 then
|
||||
self:F3( { DetectedItemID = DetectedItemID } )
|
||||
self:RemoveDetectedItem( DetectedItemID )
|
||||
end
|
||||
|
||||
@ -778,8 +774,7 @@ do -- DETECTION_BASE
|
||||
-- @param #string UnitName The UnitName that needs to be forgotten from the DetectionItem Sets.
|
||||
-- @return #DETECTION_BASE
|
||||
function DETECTION_BASE:ForgetDetectedUnit( UnitName )
|
||||
self:F2()
|
||||
|
||||
|
||||
local DetectedItems = self:GetDetectedItems()
|
||||
|
||||
for DetectedItemIndex, DetectedItem in pairs( DetectedItems ) do
|
||||
@ -796,7 +791,6 @@ do -- DETECTION_BASE
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @return #DETECTION_BASE
|
||||
function DETECTION_BASE:CreateDetectionItems()
|
||||
self:F2()
|
||||
|
||||
self:F( "Error, in DETECTION_BASE class..." )
|
||||
return self
|
||||
@ -1179,8 +1173,7 @@ do -- DETECTION_BASE
|
||||
-- @param Dcs.DCSUnit#Unit.Category Category The category of the unit.
|
||||
-- @return #boolean true if there are friendlies nearby
|
||||
function DETECTION_BASE:IsFriendliesNearBy( DetectedItem, Category )
|
||||
|
||||
self:F( { "FriendliesNearBy Test", DetectedItem.FriendliesNearBy } )
|
||||
--self:F( { "FriendliesNearBy Test", DetectedItem.FriendliesNearBy } )
|
||||
return ( DetectedItem.FriendliesNearBy and DetectedItem.FriendliesNearBy[Category] ~= nil ) or false
|
||||
end
|
||||
|
||||
@ -1237,7 +1230,7 @@ do -- DETECTION_BASE
|
||||
--- Background worker function to determine if there are friendlies nearby ...
|
||||
-- @param #DETECTION_BASE self
|
||||
function DETECTION_BASE:ReportFriendliesNearBy( TargetData )
|
||||
self:F( { "Search Friendlies", DetectedItem = TargetData.DetectedItem } )
|
||||
--self:F( { "Search Friendlies", DetectedItem = TargetData.DetectedItem } )
|
||||
|
||||
local DetectedItem = TargetData.DetectedItem -- Functional.Detection#DETECTION_BASE.DetectedItem
|
||||
local DetectedSet = TargetData.DetectedItem.Set
|
||||
@ -1286,7 +1279,7 @@ do -- DETECTION_BASE
|
||||
if FoundUnitInReportSetGroup == true then
|
||||
-- If the recce was part of the friendlies found, then check if the recce is part of the allowed friendly unit prefixes.
|
||||
for PrefixID, Prefix in pairs( self.FriendlyPrefixes or {} ) do
|
||||
self:F( { "Friendly Prefix:", Prefix = Prefix } )
|
||||
--self:F( { "Friendly Prefix:", Prefix = Prefix } )
|
||||
-- In case a match is found (so a recce unit name is part of the friendly prefixes), then report that recce to be part of the friendlies.
|
||||
-- This is important if CAP planes (so planes using their own radar) to be scanning for targets as part of the EWR network.
|
||||
-- But CAP planes are also attackers, so they need to be considered friendlies too!
|
||||
@ -1298,7 +1291,7 @@ do -- DETECTION_BASE
|
||||
end
|
||||
end
|
||||
|
||||
self:F( { "Friendlies near Target:", FoundUnitName, FoundUnitCoalition, EnemyUnitName, EnemyCoalition, FoundUnitInReportSetGroup } )
|
||||
--self:F( { "Friendlies near Target:", FoundUnitName, FoundUnitCoalition, EnemyUnitName, EnemyCoalition, FoundUnitInReportSetGroup } )
|
||||
|
||||
if FoundUnitCoalition ~= EnemyCoalition and FoundUnitInReportSetGroup == false then
|
||||
local FriendlyUnit = UNIT:Find( FoundDCSUnit )
|
||||
@ -1313,7 +1306,7 @@ do -- DETECTION_BASE
|
||||
local Distance = DetectedUnitCoord:Get2DDistance( FriendlyUnit:GetCoordinate() )
|
||||
DetectedItem.FriendliesDistance = DetectedItem.FriendliesDistance or {}
|
||||
DetectedItem.FriendliesDistance[Distance] = FriendlyUnit
|
||||
self:T( { "Friendlies Found:", FriendlyUnitName = FriendlyUnitName, Distance = Distance, FriendlyUnitCategory = FriendlyUnitCategory, FriendliesCategory = self.FriendliesCategory } )
|
||||
--self:F( { "Friendlies Found:", FriendlyUnitName = FriendlyUnitName, Distance = Distance, FriendlyUnitCategory = FriendlyUnitCategory, FriendliesCategory = self.FriendliesCategory } )
|
||||
return true
|
||||
end
|
||||
|
||||
@ -1355,6 +1348,9 @@ do -- DETECTION_BASE
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
self:F( { Friendlies = DetectedItem.FriendliesNearBy, Players = DetectedItem.PlayersNearBy } )
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
@ -1886,7 +1882,6 @@ do -- DETECTION_UNITS
|
||||
-- @param #DETECTION_UNITS self
|
||||
-- @return #DETECTION_UNITS self
|
||||
function DETECTION_UNITS:CreateDetectionItems()
|
||||
self:F2( #self.DetectedObjects )
|
||||
|
||||
-- Loop the current detected items, and check if each object still exists and is detected.
|
||||
|
||||
@ -2137,7 +2132,6 @@ do -- DETECTION_TYPES
|
||||
-- @param #DETECTION_TYPES self
|
||||
-- @return #DETECTION_TYPES self
|
||||
function DETECTION_TYPES:CreateDetectionItems()
|
||||
self:F2( #self.DetectedObjects )
|
||||
|
||||
-- Loop the current detected items, and check if each object still exists and is detected.
|
||||
|
||||
@ -2525,10 +2519,9 @@ do -- DETECTION_AREAS
|
||||
-- @param #DETECTION_AREAS self
|
||||
-- @return #DETECTION_AREAS self
|
||||
function DETECTION_AREAS:CreateDetectionItems()
|
||||
self:F2()
|
||||
|
||||
|
||||
self:T( "Checking Detected Items for new Detected Units ..." )
|
||||
self:T2( "Checking Detected Items for new Detected Units ..." )
|
||||
-- First go through all detected sets, and check if there are new detected units, match all existing detected units and identify undetected units.
|
||||
-- Regroup when needed, split groups when needed.
|
||||
for DetectedItemID, DetectedItemData in pairs( self.DetectedItems ) do
|
||||
@ -2537,8 +2530,7 @@ do -- DETECTION_AREAS
|
||||
|
||||
if DetectedItem then
|
||||
|
||||
self:T( { "Detected Item ID:", DetectedItemID } )
|
||||
|
||||
self:T2( { "Detected Item ID: ", DetectedItemID } )
|
||||
|
||||
local DetectedSet = DetectedItem.Set
|
||||
|
||||
@ -2667,7 +2659,6 @@ do -- DETECTION_AREAS
|
||||
|
||||
local DetectedItem = DetectedItemData -- #DETECTION_BASE.DetectedItem
|
||||
if DetectedItem then
|
||||
self:T( "Detection Area #" .. DetectedItem.ID )
|
||||
local DetectedSet = DetectedItem.Set
|
||||
if not self:IsDetectedObjectIdentified( DetectedObject ) and DetectedUnit:IsInZone( DetectedItem.Zone ) then
|
||||
self:IdentifyDetectedObject( DetectedObject )
|
||||
|
||||
@ -858,7 +858,7 @@ function SCORING:OnEventBirth( Event )
|
||||
if Event.IniUnit then
|
||||
if Event.IniObjectCategory == 1 then
|
||||
local PlayerName = Event.IniUnit:GetPlayerName()
|
||||
if PlayerName ~= "" then
|
||||
if PlayerName then
|
||||
self:_AddPlayerFromUnit( Event.IniUnit )
|
||||
self:SetScoringMenu( Event.IniGroup )
|
||||
end
|
||||
|
||||
@ -86,11 +86,13 @@ COMMANDCENTER = {
|
||||
-- @return #COMMANDCENTER
|
||||
function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
|
||||
local self = BASE:Inherit( self, BASE:New() )
|
||||
local self = BASE:Inherit( self, BASE:New() ) -- #COMMANDCENTER
|
||||
|
||||
self.CommandCenterPositionable = CommandCenterPositionable
|
||||
self.CommandCenterName = CommandCenterName or CommandCenterPositionable:GetName()
|
||||
self.CommandCenterCoalition = CommandCenterPositionable:GetCoalition()
|
||||
|
||||
self.AutoAssignTasks = false
|
||||
|
||||
self.Missions = {}
|
||||
|
||||
@ -171,7 +173,7 @@ function COMMANDCENTER:New( CommandCenterPositionable, CommandCenterName )
|
||||
end
|
||||
)
|
||||
|
||||
-- Handle when a player leaves a slot and goes back to spectators ...
|
||||
-- Handle when a player crashes ...
|
||||
-- The PlayerUnit will be UnAssigned from the Task.
|
||||
-- When there is no Unit left running the Task, the Task goes into Abort...
|
||||
self:HandleEvent( EVENTS.Crash,
|
||||
@ -241,7 +243,7 @@ end
|
||||
-- @return #list<Tasking.Mission#MISSION>
|
||||
function COMMANDCENTER:GetMissions()
|
||||
|
||||
return self.Missions
|
||||
return self.Missions or {}
|
||||
end
|
||||
|
||||
--- Add a MISSION to be governed by the HQ command center.
|
||||
@ -330,7 +332,7 @@ end
|
||||
--- Sets the menu structure of the Missions governed by the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:SetMenu()
|
||||
self:F()
|
||||
self:F2()
|
||||
|
||||
local MenuTime = timer.getTime()
|
||||
for MissionID, Mission in pairs( self:GetMissions() or {} ) do
|
||||
@ -339,7 +341,7 @@ function COMMANDCENTER:SetMenu()
|
||||
end
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() or {} ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
Mission = Mission -- Tasking.Mission#MISSION
|
||||
Mission:RemoveMenu( MenuTime )
|
||||
end
|
||||
|
||||
@ -348,10 +350,133 @@ end
|
||||
--- Gets the commandcenter menu structure governed by the HQ command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return Core.Menu#MENU_COALITION
|
||||
function COMMANDCENTER:GetMenu()
|
||||
return self.CommandCenterMenu
|
||||
function COMMANDCENTER:GetMenu( TaskGroup )
|
||||
|
||||
local MenuTime = timer.getTime()
|
||||
|
||||
self.CommandCenterMenus = self.CommandCenterMenus or {}
|
||||
local CommandCenterMenu
|
||||
|
||||
local CommandCenterText = self:GetText()
|
||||
CommandCenterMenu = MENU_GROUP:New( TaskGroup, CommandCenterText ):SetTime(MenuTime)
|
||||
self.CommandCenterMenus[TaskGroup] = CommandCenterMenu
|
||||
|
||||
if self.AutoAssignTasks == false then
|
||||
local AutoAssignTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Assign Task On", CommandCenterMenu, self.SetAutoAssignTasks, self, true ):SetTime(MenuTime):SetTag("AutoTask")
|
||||
local AssignTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Assign Task", CommandCenterMenu, self.AssignRandomTask, self, TaskGroup ):SetTime(MenuTime):SetTag("AutoTask")
|
||||
else
|
||||
local AutoAssignTaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, "Assign Task Off", CommandCenterMenu, self.SetAutoAssignTasks, self, false ):SetTime(MenuTime):SetTag("AutoTask")
|
||||
end
|
||||
CommandCenterMenu:Remove( MenuTime, "AutoTask" )
|
||||
|
||||
return self.CommandCenterMenus[TaskGroup]
|
||||
end
|
||||
|
||||
|
||||
--- Assigns a random task to a TaskGroup.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return #COMMANDCENTER
|
||||
function COMMANDCENTER:AssignRandomTask( TaskGroup )
|
||||
|
||||
local Tasks = {}
|
||||
|
||||
for MissionID, Mission in pairs( self:GetMissions() ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
local MissionTasks = Mission:GetGroupTasks( TaskGroup )
|
||||
for MissionTaskName, MissionTask in pairs( MissionTasks or {} ) do
|
||||
Tasks[#Tasks+1] = MissionTask
|
||||
end
|
||||
end
|
||||
|
||||
local Task = Tasks[ math.random( 1, #Tasks ) ] -- Tasking.Task#TASK
|
||||
|
||||
Task:SetAssignMethod( ACT_ASSIGN_MENU_ACCEPT:New( Task.TaskBriefing ) )
|
||||
|
||||
Task:AssignToGroup( TaskGroup )
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Automatically assigns tasks to all TaskGroups.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param #boolean AutoAssign true for ON and false or nil for OFF.
|
||||
-- @return #COMMANDCENTER
|
||||
function COMMANDCENTER:SetAutoAssignTasks( AutoAssign )
|
||||
|
||||
self.AutoAssignTasks = AutoAssign or false
|
||||
|
||||
local GroupSet = self:AddGroups()
|
||||
|
||||
for GroupID, TaskGroup in pairs( GroupSet:GetSet() ) do
|
||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
self:GetMenu( TaskGroup )
|
||||
end
|
||||
|
||||
if self.AutoAssignTasks == true then
|
||||
self:ScheduleRepeat( 10, 30, 0, nil, self.AssignTasks, self )
|
||||
else
|
||||
self:ScheduleStop( self.AssignTasks )
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- Automatically assigns tasks to all TaskGroups.
|
||||
-- @param #COMMANDCENTER self
|
||||
function COMMANDCENTER:AssignTasks()
|
||||
|
||||
local GroupSet = self:AddGroups()
|
||||
|
||||
for GroupID, TaskGroup in pairs( GroupSet:GetSet() ) do
|
||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
|
||||
if self:IsGroupAssigned( TaskGroup ) then
|
||||
else
|
||||
-- Only groups with planes or helicopters will receive automatic tasks.
|
||||
-- TODO Workaround DCS-BUG-3 - https://github.com/FlightControl-Master/MOOSE/issues/696
|
||||
if TaskGroup:IsAir() then
|
||||
self:AssignRandomTask( TaskGroup )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--- Get all the Groups active within the command center.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return Core.Set#SET_GROUP
|
||||
function COMMANDCENTER:AddGroups()
|
||||
|
||||
local GroupSet = SET_GROUP:New()
|
||||
|
||||
for MissionID, Mission in pairs( self.Missions ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
GroupSet = Mission:AddGroups( GroupSet )
|
||||
end
|
||||
|
||||
return GroupSet
|
||||
end
|
||||
|
||||
|
||||
--- Checks of the TaskGroup has a Task.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @return #boolean
|
||||
function COMMANDCENTER:IsGroupAssigned( TaskGroup )
|
||||
|
||||
local Assigned = false
|
||||
|
||||
for MissionID, Mission in pairs( self.Missions ) do
|
||||
local Mission = Mission -- Tasking.Mission#MISSION
|
||||
if Mission:IsGroupAssigned( TaskGroup ) then
|
||||
Assigned = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return Assigned
|
||||
end
|
||||
|
||||
|
||||
--- Checks of the COMMANDCENTER has a GROUP.
|
||||
-- @param #COMMANDCENTER self
|
||||
-- @param Wrapper.Group#GROUP
|
||||
@ -407,7 +532,7 @@ function COMMANDCENTER:MessageToCoalition( Message )
|
||||
local CCCoalition = self:GetPositionable():GetCoalition()
|
||||
--TODO: Fix coalition bug!
|
||||
|
||||
self:GetPositionable():MessageToCoalition( Message, 15, CCCoalition )
|
||||
self:GetPositionable():MessageToCoalition( Message, 15, CCCoalition, self:GetShortText() )
|
||||
|
||||
end
|
||||
|
||||
@ -421,7 +546,7 @@ function COMMANDCENTER:MessageTypeToCoalition( Message, MessageType )
|
||||
local CCCoalition = self:GetPositionable():GetCoalition()
|
||||
--TODO: Fix coalition bug!
|
||||
|
||||
self:GetPositionable():MessageTypeToCoalition( Message, MessageType, CCCoalition )
|
||||
self:GetPositionable():MessageTypeToCoalition( Message, MessageType, CCCoalition, self:GetShortText() )
|
||||
|
||||
end
|
||||
|
||||
|
||||
@ -377,24 +377,30 @@ function MISSION:GetScoring()
|
||||
return self.Scoring
|
||||
end
|
||||
|
||||
--- Get the groups for which TASKS are given in the mission
|
||||
--- Gets the groups for which TASKS are given in the mission
|
||||
-- @param #MISSION self
|
||||
-- @param Core.Set#SET_GROUP GroupSet
|
||||
-- @return Core.Set#SET_GROUP
|
||||
function MISSION:GetGroups()
|
||||
|
||||
local SetGroup = SET_GROUP:New()
|
||||
return self:AddGroups()
|
||||
|
||||
end
|
||||
|
||||
--- Adds the groups for which TASKS are given in the mission
|
||||
-- @param #MISSION self
|
||||
-- @param Core.Set#SET_GROUP GroupSet
|
||||
-- @return Core.Set#SET_GROUP
|
||||
function MISSION:AddGroups( GroupSet )
|
||||
|
||||
GroupSet = GroupSet or SET_GROUP:New()
|
||||
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
local GroupSet = Task:GetGroups()
|
||||
GroupSet:ForEachGroup(
|
||||
function( TaskGroup )
|
||||
SetGroup:Add( TaskGroup, TaskGroup )
|
||||
end
|
||||
)
|
||||
GroupSet = Task:AddGroups( GroupSet )
|
||||
end
|
||||
|
||||
return SetGroup
|
||||
return GroupSet
|
||||
|
||||
end
|
||||
|
||||
@ -443,11 +449,11 @@ do -- Group Assignment
|
||||
local MissionGroupName = MissionGroup:GetName()
|
||||
|
||||
if self.AssignedGroups[MissionGroupName] == MissionGroup then
|
||||
self:T( { "Mission is assigned to:", MissionGroup:GetName() } )
|
||||
self:T2( { "Mission is assigned to:", MissionGroup:GetName() } )
|
||||
return true
|
||||
end
|
||||
|
||||
self:T( { "Mission is not assigned to:", MissionGroup:GetName() } )
|
||||
self:T2( { "Mission is not assigned to:", MissionGroup:GetName() } )
|
||||
return false
|
||||
end
|
||||
|
||||
@ -524,18 +530,13 @@ end
|
||||
function MISSION:GetMenu( TaskGroup ) -- R2.1 -- Changed Menu Structure
|
||||
|
||||
local CommandCenter = self:GetCommandCenter()
|
||||
local CommandCenterMenu = CommandCenter:GetMenu()
|
||||
local CommandCenterMenu = CommandCenter:GetMenu( TaskGroup )
|
||||
|
||||
--local MissionMenu = CommandCenterMenu:GetMenu( MissionName )
|
||||
|
||||
self.MissionGroupMenu = self.MissionGroupMenu or {}
|
||||
self.MissionGroupMenu[TaskGroup] = self.MissionGroupMenu[TaskGroup] or {}
|
||||
|
||||
local GroupMenu = self.MissionGroupMenu[TaskGroup]
|
||||
|
||||
local CommandCenterText = CommandCenter:GetText()
|
||||
CommandCenterMenu = MENU_GROUP:New( TaskGroup, CommandCenterText )
|
||||
|
||||
local MissionText = self:GetText()
|
||||
self.MissionMenu = MENU_GROUP:New( TaskGroup, MissionText, CommandCenterMenu )
|
||||
|
||||
@ -564,7 +565,7 @@ end
|
||||
-- @param #string TaskName The Name of the @{Task} within the @{Mission}.
|
||||
-- @return Tasking.Task#TASK The Task
|
||||
-- @return #nil Returns nil if no task was found.
|
||||
function MISSION:GetTask( TaskName )
|
||||
function MISSION:GetTask( TaskName )
|
||||
self:F( { TaskName } )
|
||||
|
||||
return self.Tasks[TaskName]
|
||||
@ -1005,9 +1006,28 @@ end
|
||||
-- env.info( "Task 2 Completion = " .. Tasks[2]:GetGoalPercentage() .. "%" )
|
||||
function MISSION:GetTasks()
|
||||
|
||||
return self.Tasks
|
||||
return self.Tasks or {}
|
||||
end
|
||||
|
||||
--- Get the relevant tasks of a TaskGroup.
|
||||
-- @param #MISSION
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
-- @return #list<Tasking.Task#TASK>
|
||||
function MISSION:GetGroupTasks( TaskGroup )
|
||||
|
||||
local Tasks = {}
|
||||
|
||||
for TaskID, Task in pairs( self:GetTasks() ) do
|
||||
local Task = Task -- Tasking.Task#TASK
|
||||
if Task:HasGroup( TaskGroup ) then
|
||||
Tasks[#Tasks+1] = Task
|
||||
end
|
||||
end
|
||||
|
||||
return Tasks
|
||||
end
|
||||
|
||||
|
||||
--- Reports the briefing.
|
||||
-- @param #MISSION self
|
||||
-- @param Wrapper.Group#GROUP ReportGroup The group to which the report needs to be sent.
|
||||
|
||||
@ -161,7 +161,7 @@ TASK = {
|
||||
-- @return #TASK self
|
||||
function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
||||
|
||||
local self = BASE:Inherit( self, FSM_TASK:New() ) -- Tasking.Task#TASK
|
||||
local self = BASE:Inherit( self, FSM_TASK:New( TaskName ) ) -- Tasking.Task#TASK
|
||||
|
||||
self:SetStartState( "Planned" )
|
||||
self:AddTransition( "Planned", "Assign", "Assigned" )
|
||||
@ -169,10 +169,17 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
||||
self:AddTransition( "Assigned", "Success", "Success" )
|
||||
self:AddTransition( "Assigned", "Hold", "Hold" )
|
||||
self:AddTransition( "Assigned", "Fail", "Failed" )
|
||||
self:AddTransition( "Assigned", "Abort", "Aborted" )
|
||||
self:AddTransition( { "Planned", "Assigned" }, "Abort", "Aborted" )
|
||||
self:AddTransition( "Assigned", "Cancel", "Cancelled" )
|
||||
self:AddTransition( "Assigned", "Goal", "*" )
|
||||
|
||||
self.Fsm = {}
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
Fsm:SetStartState( "Planned" )
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "Assigned", Rejected = "Reject" } )
|
||||
Fsm:AddTransition( "Assigned", "Assigned", "*" )
|
||||
|
||||
--- Goal Handler OnBefore for TASK
|
||||
-- @function [parent=#TASK] OnBeforeGoal
|
||||
-- @param #TASK self
|
||||
@ -209,6 +216,7 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
||||
|
||||
self:AddTransition( "*", "PlayerCrashed", "*" )
|
||||
self:AddTransition( "*", "PlayerAborted", "*" )
|
||||
self:AddTransition( "*", "PlayerRejected", "*" )
|
||||
self:AddTransition( "*", "PlayerDead", "*" )
|
||||
self:AddTransition( { "Failed", "Aborted", "Cancelled" }, "Replan", "Planned" )
|
||||
self:AddTransition( "*", "TimeOut", "Cancelled" )
|
||||
@ -216,7 +224,6 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
||||
self:F( "New TASK " .. TaskName )
|
||||
|
||||
self.Processes = {}
|
||||
self.Fsm = {}
|
||||
|
||||
self.Mission = Mission
|
||||
self.CommandCenter = Mission:GetCommandCenter()
|
||||
@ -229,7 +236,6 @@ function TASK:New( Mission, SetGroupAssign, TaskName, TaskType, TaskBriefing )
|
||||
|
||||
self:SetBriefing( TaskBriefing )
|
||||
|
||||
self.FsmTemplate = self.FsmTemplate or FSM_PROCESS:New()
|
||||
|
||||
self.TaskInfo = TASKINFO:New( self )
|
||||
|
||||
@ -246,7 +252,8 @@ function TASK:GetUnitProcess( TaskUnit )
|
||||
if TaskUnit then
|
||||
return self:GetStateMachine( TaskUnit )
|
||||
else
|
||||
return self.FsmTemplate
|
||||
self.FsmTemplate = self.FsmTemplate or FSM_PROCESS:New()
|
||||
return self.FsmTemplate
|
||||
end
|
||||
end
|
||||
|
||||
@ -295,34 +302,61 @@ function TASK:JoinUnit( PlayerUnit, PlayerGroup )
|
||||
return PlayerUnitAdded
|
||||
end
|
||||
|
||||
--- Abort a PlayerUnit from a Task.
|
||||
-- If the Unit was not part of the Task, false is returned.
|
||||
-- If the Unit is part of the Task, true is returned.
|
||||
--- A group rejecting a planned task.
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player aborting the Task.
|
||||
-- @param Wrapper.Group#GROUP PlayerGroup The group rejecting the task.
|
||||
-- @return #TASK
|
||||
function TASK:AbortGroup( PlayerGroup )
|
||||
self:F( { PlayerGroup = PlayerGroup } )
|
||||
function TASK:RejectGroup( PlayerGroup )
|
||||
|
||||
local PlayerGroups = self:GetGroups()
|
||||
|
||||
-- Is the PlayerGroup part of the PlayerGroups?
|
||||
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
|
||||
|
||||
-- Check if the PlayerGroup is already assigned to the Task. If yes, the PlayerGroup is aborted from the Task.
|
||||
-- Check if the PlayerGroup is already assigned or is planned to be assigned to the Task.
|
||||
-- If yes, the PlayerGroup is aborted from the Task.
|
||||
-- If the PlayerUnit was the last unit of the PlayerGroup, the menu needs to be removed from the Group.
|
||||
if self:IsStateAssigned() then
|
||||
if self:IsStatePlanned() then
|
||||
|
||||
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
|
||||
if IsGroupAssigned then
|
||||
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
|
||||
self:GetMission():GetCommandCenter():MessageToGroup( "Task " .. self:GetName() .. " has been rejected! We will select another task.", PlayerGroup )
|
||||
self:UnAssignFromGroup( PlayerGroup )
|
||||
|
||||
self:PlayerRejected( PlayerGroup:GetUnit(1) )
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
|
||||
--- A group aborting the task.
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Group#GROUP PlayerGroup The group aborting the task.
|
||||
-- @return #TASK
|
||||
function TASK:AbortGroup( PlayerGroup )
|
||||
|
||||
local PlayerGroups = self:GetGroups()
|
||||
|
||||
-- Is the PlayerGroup part of the PlayerGroups?
|
||||
if PlayerGroups:IsIncludeObject( PlayerGroup ) then
|
||||
|
||||
-- Check if the PlayerGroup is already assigned or is planned to be assigned to the Task.
|
||||
-- If yes, the PlayerGroup is aborted from the Task.
|
||||
-- If the PlayerUnit was the last unit of the PlayerGroup, the menu needs to be removed from the Group.
|
||||
if self:IsStateAssigned() then
|
||||
|
||||
local IsGroupAssigned = self:IsGroupAssigned( PlayerGroup )
|
||||
self:F( { IsGroupAssigned = IsGroupAssigned } )
|
||||
if IsGroupAssigned then
|
||||
local PlayerName = PlayerGroup:GetUnit(1):GetPlayerName()
|
||||
--self:MessageToGroups( PlayerName .. " aborted Task " .. self:GetName() )
|
||||
self:UnAssignFromGroup( PlayerGroup )
|
||||
--self:Abort()
|
||||
|
||||
-- Now check if the task needs to go to hold...
|
||||
-- It will go to hold, if there are no players in the mission...
|
||||
|
||||
PlayerGroups:Flush( self )
|
||||
local IsRemaining = false
|
||||
for GroupName, AssignedGroup in pairs( PlayerGroups:GetSet() or {} ) do
|
||||
@ -347,11 +381,10 @@ function TASK:AbortGroup( PlayerGroup )
|
||||
return self
|
||||
end
|
||||
|
||||
--- A PlayerUnit crashed in a Task. Abort the Player.
|
||||
-- If the Unit was not part of the Task, false is returned.
|
||||
-- If the Unit is part of the Task, true is returned.
|
||||
|
||||
--- A group crashing and thus aborting from the task.
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Unit#UNIT PlayerUnit The CLIENT or UNIT of the Player aborting the Task.
|
||||
-- @param Wrapper.Group#GROUP PlayerGroup The group aborting the task.
|
||||
-- @return #TASK
|
||||
function TASK:CrashGroup( PlayerGroup )
|
||||
self:F( { PlayerGroup = PlayerGroup } )
|
||||
@ -413,9 +446,29 @@ end
|
||||
-- @param #TASK self
|
||||
-- @return Core.Set#SET_GROUP
|
||||
function TASK:GetGroups()
|
||||
|
||||
return self.SetGroup
|
||||
end
|
||||
|
||||
|
||||
--- Gets the SET_GROUP assigned to the TASK.
|
||||
-- @param #TASK self
|
||||
-- @param Core.Set#SET_GROUP GroupSet
|
||||
-- @return Core.Set#SET_GROUP
|
||||
function TASK:AddGroups( GroupSet )
|
||||
|
||||
GroupSet = GroupSet or SET_GROUP:New()
|
||||
|
||||
self.SetGroup:ForEachGroup(
|
||||
--- @param Wrapper.Group#GROUP GroupSet
|
||||
function( GroupItem )
|
||||
GroupSet:Add( GroupItem:GetName(), GroupItem)
|
||||
end
|
||||
)
|
||||
|
||||
return GroupSet
|
||||
end
|
||||
|
||||
do -- Group Assignment
|
||||
|
||||
--- Returns if the @{Task} is assigned to the Group.
|
||||
@ -500,6 +553,16 @@ end
|
||||
|
||||
do -- Group Assignment
|
||||
|
||||
--- @param #TASK self
|
||||
-- @param Actions.Act_Assign#ACT_ASSIGN AcceptClass
|
||||
function TASK:SetAssignMethod( AcceptClass )
|
||||
|
||||
local ProcessTemplate = self:GetUnitProcess()
|
||||
|
||||
ProcessTemplate:SetProcess( "Planned", "Accept", AcceptClass ) -- Actions.Act_Assign#ACT_ASSIGN
|
||||
end
|
||||
|
||||
|
||||
--- Assign the @{Task} to a @{Group}.
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Group#GROUP TaskGroup
|
||||
@ -597,7 +660,9 @@ function TASK:UnAssignFromUnit( TaskUnit )
|
||||
self:F( TaskUnit:GetName() )
|
||||
|
||||
self:RemoveStateMachine( TaskUnit )
|
||||
|
||||
|
||||
-- If a Task Control Menu had been set, then this will be removed.
|
||||
self:RemoveTaskControlMenu( TaskUnit )
|
||||
return self
|
||||
end
|
||||
|
||||
@ -620,9 +685,11 @@ function TASK:MessageToGroups( Message )
|
||||
local Mission = self:GetMission()
|
||||
local CC = Mission:GetCommandCenter()
|
||||
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
CC:MessageToGroup( Message, TaskGroup, TaskGroup:GetName() )
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
if TaskGroup:IsAlive() == true then
|
||||
CC:MessageToGroup( Message, TaskGroup, TaskGroup:GetName() )
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -632,10 +699,11 @@ end
|
||||
function TASK:SendBriefingToAssignedGroups()
|
||||
self:F2()
|
||||
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||
|
||||
if self:IsGroupAssigned( TaskGroup ) then
|
||||
TaskGroup:Message( self.TaskBriefing, 60 )
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
if TaskGroup:IsAlive() then
|
||||
if self:IsGroupAssigned( TaskGroup ) then
|
||||
TaskGroup:Message( self.TaskBriefing, 60 )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -646,9 +714,11 @@ end
|
||||
function TASK:UnAssignFromGroups()
|
||||
self:F2()
|
||||
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||
if self:IsGroupAssigned(TaskGroup) then
|
||||
self:UnAssignFromGroup( TaskGroup )
|
||||
for TaskGroupName, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
if TaskGroup:IsAlive() == true then
|
||||
if self:IsGroupAssigned(TaskGroup) then
|
||||
self:UnAssignFromGroup( TaskGroup )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -661,13 +731,15 @@ end
|
||||
function TASK:HasAliveUnits()
|
||||
self:F()
|
||||
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||
if self:IsStateAssigned() then
|
||||
if self:IsGroupAssigned( TaskGroup ) then
|
||||
for TaskUnitID, TaskUnit in pairs( TaskGroup:GetUnits() ) do
|
||||
if TaskUnit:IsAlive() then
|
||||
self:T( { HasAliveUnits = true } )
|
||||
return true
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
if TaskGroup:IsAlive() == true then
|
||||
if self:IsStateAssigned() then
|
||||
if self:IsGroupAssigned( TaskGroup ) then
|
||||
for TaskUnitID, TaskUnit in pairs( TaskGroup:GetUnits() ) do
|
||||
if TaskUnit:IsAlive() then
|
||||
self:T( { HasAliveUnits = true } )
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -686,7 +758,8 @@ function TASK:SetMenu( MenuTime ) --R2.1 Mission Reports and Task Reports added.
|
||||
self:F( { self:GetName(), MenuTime } )
|
||||
|
||||
--self.SetGroup:Flush()
|
||||
for TaskGroupID, TaskGroupData in pairs( self.SetGroup:GetAliveSet() ) do
|
||||
--for TaskGroupID, TaskGroupData in pairs( self.SetGroup:GetAliveSet() ) do
|
||||
for TaskGroupID, TaskGroupData in pairs( self.SetGroup:GetSet() ) do
|
||||
local TaskGroup = TaskGroupData -- Wrapper.Group#GROUP
|
||||
if TaskGroup:IsAlive() == true and TaskGroup:GetPlayerNames() then
|
||||
|
||||
@ -729,21 +802,14 @@ function TASK:SetPlannedMenuForGroup( TaskGroup, MenuTime )
|
||||
|
||||
local Mission = self:GetMission()
|
||||
local MissionName = Mission:GetName()
|
||||
local CommandCenter = Mission:GetCommandCenter()
|
||||
local CommandCenterMenu = CommandCenter:GetMenu()
|
||||
local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||
|
||||
local TaskType = self:GetType()
|
||||
local TaskPlayerCount = self:GetPlayerCount()
|
||||
local TaskPlayerString = string.format( " (%dp)", TaskPlayerCount )
|
||||
-- local TaskText = string.format( "%s%s", self:GetName(), TaskPlayerString ) --, TaskThreatLevelString )
|
||||
local TaskText = string.format( "%s", self:GetName() )
|
||||
local TaskName = string.format( "%s", self:GetName() )
|
||||
|
||||
local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||
--local MissionMenu = MENU_GROUP:New( TaskGroup, MissionName, CommandCenterMenu ):SetTime( MenuTime )
|
||||
|
||||
--local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||
|
||||
self.MenuPlanned = self.MenuPlanned or {}
|
||||
self.MenuPlanned[TaskGroup] = MENU_GROUP_DELAYED:New( TaskGroup, "Join Planned Task", MissionMenu, Mission.MenuReportTasksPerStatus, Mission, TaskGroup, "Planned" ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
local TaskTypeMenu = MENU_GROUP_DELAYED:New( TaskGroup, TaskType, self.MenuPlanned[TaskGroup] ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
@ -768,26 +834,24 @@ end
|
||||
function TASK:SetAssignedMenuForGroup( TaskGroup, MenuTime )
|
||||
self:F( { TaskGroup:GetName(), MenuTime } )
|
||||
|
||||
local Mission = self:GetMission()
|
||||
local MissionName = Mission:GetName()
|
||||
local CommandCenter = Mission:GetCommandCenter()
|
||||
local CommandCenterMenu = CommandCenter:GetMenu()
|
||||
|
||||
local TaskType = self:GetType()
|
||||
local TaskPlayerCount = self:GetPlayerCount()
|
||||
local TaskPlayerString = string.format( " (%dp)", TaskPlayerCount )
|
||||
local TaskText = string.format( "%s%s", self:GetName(), TaskPlayerString ) --, TaskThreatLevelString )
|
||||
local TaskName = string.format( "%s", self:GetName() )
|
||||
|
||||
local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||
-- local MissionMenu = MENU_GROUP:New( TaskGroup, MissionName, CommandCenterMenu ):SetTime( MenuTime )
|
||||
-- local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||
|
||||
self.MenuAssigned = self.MenuAssigned or {}
|
||||
self.MenuAssigned[TaskGroup] = MENU_GROUP_DELAYED:New( TaskGroup, string.format( "Assigned Task %s", TaskName ), MissionMenu ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
local TaskMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Abort Task" ), self.MenuAssigned[TaskGroup], self.MenuTaskAbort, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
local MarkMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Mark Task Location on Map" ), self.MenuAssigned[TaskGroup], self.MenuMarkToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
local TaskTypeMenu = MENU_GROUP_COMMAND_DELAYED:New( TaskGroup, string.format( "Report Task Details" ), self.MenuAssigned[TaskGroup], self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
for UnitName, TaskUnit in pairs( TaskGroup:GetPlayerUnits() ) do
|
||||
local TaskUnit = TaskUnit -- Wrapper.Unit#UNIT
|
||||
if TaskUnit then
|
||||
local MenuControl = self:GetTaskControlMenu( TaskUnit )
|
||||
local TaskControl = MENU_GROUP:New( TaskGroup, "Control Task", MenuControl ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
if self:IsStateAssigned() then
|
||||
local TaskMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Abort Task" ), TaskControl, self.MenuTaskAbort, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
end
|
||||
local MarkMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Mark Task Location on Map" ), TaskControl, self.MenuMarkToGroup, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
local TaskTypeMenu = MENU_GROUP_COMMAND:New( TaskGroup, string.format( "Report Task Details" ), TaskControl, self.MenuTaskStatus, self, TaskGroup ):SetTime( MenuTime ):SetTag( "Tasking" )
|
||||
end
|
||||
end
|
||||
|
||||
return self
|
||||
end
|
||||
@ -799,10 +863,12 @@ end
|
||||
function TASK:RemoveMenu( MenuTime )
|
||||
self:F( { self:GetName(), MenuTime } )
|
||||
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetAliveSet() ) do
|
||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
if TaskGroup:IsAlive() == true and TaskGroup:GetPlayerNames() then
|
||||
self:RefreshMenus( TaskGroup, MenuTime )
|
||||
for TaskGroupID, TaskGroup in pairs( self.SetGroup:GetSet() ) do
|
||||
if TaskGroup:IsAlive() == true then
|
||||
local TaskGroup = TaskGroup -- Wrapper.Group#GROUP
|
||||
if TaskGroup:IsAlive() == true and TaskGroup:GetPlayerNames() then
|
||||
self:RefreshMenus( TaskGroup, MenuTime )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -818,9 +884,6 @@ function TASK:RefreshMenus( TaskGroup, MenuTime )
|
||||
|
||||
local Mission = self:GetMission()
|
||||
local MissionName = Mission:GetName()
|
||||
local CommandCenter = Mission:GetCommandCenter()
|
||||
local CommandCenterMenu = CommandCenter:GetMenu()
|
||||
|
||||
local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||
|
||||
local TaskName = self:GetName()
|
||||
@ -852,7 +915,6 @@ function TASK:RemoveAssignedMenuForGroup( TaskGroup )
|
||||
|
||||
local Mission = self:GetMission()
|
||||
local MissionName = Mission:GetName()
|
||||
|
||||
local MissionMenu = Mission:GetMenu( TaskGroup )
|
||||
|
||||
if MissionMenu then
|
||||
@ -1210,12 +1272,16 @@ function TASK:onenterAssigned( From, Event, To, PlayerUnit, PlayerName )
|
||||
|
||||
--- This test is required, because the state transition will be fired also when the state does not change in case of an event.
|
||||
if From ~= "Assigned" then
|
||||
self:F( { From, Event, To, PlayerUnit:GetName(), PlayerName } )
|
||||
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is assigned." )
|
||||
|
||||
local PlayerNames = self:GetPlayerNames()
|
||||
local PlayerText = REPORT:New()
|
||||
for PlayerName, TaskName in pairs( PlayerNames ) do
|
||||
PlayerText:Add( PlayerName )
|
||||
end
|
||||
|
||||
self:GetMission():GetCommandCenter():MessageToCoalition( "Task " .. self:GetName() .. " is assigned to players " .. PlayerText:Text(",") .. ". Good Luck!" )
|
||||
|
||||
-- Set the total Progress to be achieved.
|
||||
|
||||
self:SetGoalTotal() -- Polymorphic to set the initial goal total!
|
||||
|
||||
if self.Dispatcher then
|
||||
@ -1231,7 +1297,7 @@ function TASK:onenterAssigned( From, Event, To, PlayerUnit, PlayerName )
|
||||
self:SetMenu()
|
||||
|
||||
self:F( { "--> Task Assigned", TaskName = self:GetName(), Mission = self:GetMission():GetName() } )
|
||||
self:F( { "--> Task Player Names", PlayerNames = self:GetPlayerNames() } )
|
||||
self:F( { "--> Task Player Names", PlayerNames = PlayerNames } )
|
||||
|
||||
end
|
||||
end
|
||||
@ -1273,6 +1339,7 @@ function TASK:onenterAborted( From, Event, To )
|
||||
|
||||
end
|
||||
|
||||
|
||||
--- FSM function for a TASK
|
||||
-- @param #TASK self
|
||||
-- @param #string From
|
||||
@ -1441,11 +1508,13 @@ function TASK:GetPlayerCount() --R2.1 Get a count of the players.
|
||||
local PlayerCount = 0
|
||||
|
||||
-- Loop each Unit active in the Task, and find Player Names.
|
||||
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetAliveSet() ) do
|
||||
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetSet() ) do
|
||||
local PlayerGroup = PlayerGroup -- Wrapper.Group#GROUP
|
||||
if self:IsGroupAssigned( PlayerGroup ) then
|
||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||
PlayerCount = PlayerCount + #PlayerNames
|
||||
if PlayerGroup:IsAlive() == true then
|
||||
if self:IsGroupAssigned( PlayerGroup ) then
|
||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||
PlayerCount = PlayerCount + #PlayerNames
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1461,12 +1530,14 @@ function TASK:GetPlayerNames() --R2.1 Get a map of the players.
|
||||
local PlayerNameMap = {}
|
||||
|
||||
-- Loop each Unit active in the Task, and find Player Names.
|
||||
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetAliveSet() ) do
|
||||
for TaskGroupID, PlayerGroup in pairs( self:GetGroups():GetSet() ) do
|
||||
local PlayerGroup = PlayerGroup -- Wrapper.Group#GROUP
|
||||
if self:IsGroupAssigned( PlayerGroup ) then
|
||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||
for PlayerNameID, PlayerName in pairs( PlayerNames ) do
|
||||
PlayerNameMap[PlayerName] = PlayerGroup
|
||||
if PlayerGroup:IsAlive() == true then
|
||||
if self:IsGroupAssigned( PlayerGroup ) then
|
||||
local PlayerNames = PlayerGroup:GetPlayerNames()
|
||||
for PlayerNameID, PlayerName in pairs( PlayerNames ) do
|
||||
PlayerNameMap[PlayerName] = PlayerGroup
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -1499,7 +1570,7 @@ function TASK:ReportDetails( ReportGroup )
|
||||
|
||||
local PlayerReport = REPORT:New()
|
||||
for PlayerName, PlayerGroup in pairs( PlayerNames ) do
|
||||
PlayerReport:Add( "Group " .. PlayerGroup:GetCallsign() .. ": " .. PlayerName )
|
||||
PlayerReport:Add( "Players group " .. PlayerGroup:GetCallsign() .. ": " .. PlayerName )
|
||||
end
|
||||
local Players = PlayerReport:Text()
|
||||
|
||||
@ -1595,3 +1666,65 @@ do -- Additional Task Scoring and Task Progress
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
do -- Task Control Menu
|
||||
|
||||
-- The Task Control Menu is a menu attached to the task at the main menu to quickly be able to do actions in the task.
|
||||
-- The Task Control Menu can only be shown when the task is assigned to the player.
|
||||
-- The Task Control Menu is linked to the process executing the task, so no task menu can be set to the main static task definition.
|
||||
|
||||
--- Init Task Control Menu
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit The @{Unit} that contains a player.
|
||||
-- @return Task Control Menu Refresh ID
|
||||
function TASK:InitTaskControlMenu( TaskUnit )
|
||||
|
||||
self.TaskControlMenuTime = timer.getTime()
|
||||
|
||||
return self.TaskControlMenuTime
|
||||
end
|
||||
|
||||
--- Get Task Control Menu
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit The @{Unit} that contains a player.
|
||||
-- @return Core.Menu#MENU_GROUP TaskControlMenu The Task Control Menu
|
||||
function TASK:GetTaskControlMenu( TaskUnit, TaskName )
|
||||
|
||||
TaskName = TaskName or ""
|
||||
|
||||
local TaskGroup = TaskUnit:GetGroup()
|
||||
local TaskPlayerCount = TaskGroup:GetPlayerCount()
|
||||
|
||||
if TaskPlayerCount <= 1 then
|
||||
self.TaskControlMenu = MENU_GROUP:New( TaskUnit:GetGroup(), "Task " .. self:GetName() .. " control" ):SetTime( self.TaskControlMenuTime )
|
||||
else
|
||||
self.TaskControlMenu = MENU_GROUP:New( TaskUnit:GetGroup(), "Task " .. self:GetName() .. " control for " .. TaskUnit:GetPlayerName() ):SetTime( self.TaskControlMenuTime )
|
||||
end
|
||||
|
||||
return self.TaskControlMenu
|
||||
end
|
||||
|
||||
--- Remove Task Control Menu
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit The @{Unit} that contains a player.
|
||||
function TASK:RemoveTaskControlMenu( TaskUnit )
|
||||
|
||||
if self.TaskControlMenu then
|
||||
self.TaskControlMenu:Remove()
|
||||
self.TaskControlMenu = nil
|
||||
end
|
||||
end
|
||||
|
||||
--- Refresh Task Control Menu
|
||||
-- @param #TASK self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit The @{Unit} that contains a player.
|
||||
-- @param MenuTime The refresh time that was used to refresh the Task Control Menu items.
|
||||
-- @param MenuTag The tag.
|
||||
function TASK:RefreshTaskControlMenu( TaskUnit, MenuTime, MenuTag )
|
||||
|
||||
if self.TaskControlMenu then
|
||||
self.TaskControlMenu:Remove( MenuTime, MenuTag )
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -249,17 +249,15 @@ end
|
||||
function TASKINFO:AddCargoSet( SetCargo, Order, Detail, Keep )
|
||||
|
||||
local CargoReport = REPORT:New()
|
||||
CargoReport:Add( "" )
|
||||
SetCargo:ForEachCargo(
|
||||
--- @param Core.Cargo#CARGO Cargo
|
||||
--- @param Cargo.Cargo#CARGO Cargo
|
||||
function( Cargo )
|
||||
local CargoType = Cargo:GetType()
|
||||
local CargoName = Cargo:GetName()
|
||||
local CargoCoordinate = Cargo:GetCoordinate()
|
||||
CargoReport:Add( string.format( '"%s" (%s) at %s', CargoName, CargoType, CargoCoordinate:ToStringMGRS() ) )
|
||||
CargoReport:Add( string.format( ' - %s (%s) %s - status %s ', Cargo:GetName(), Cargo:GetType(), Cargo:GetTransportationMethod(), Cargo:GetCurrentState() ) )
|
||||
end
|
||||
)
|
||||
|
||||
self:AddInfo( "CargoSet", CargoReport:Text(), Order, Detail, Keep )
|
||||
self:AddInfo( "Cargo", CargoReport:Text(), Order, Detail, Keep )
|
||||
|
||||
return self
|
||||
end
|
||||
@ -319,7 +317,7 @@ function TASKINFO:Report( Report, Detail, ReportGroup )
|
||||
local Coordinate = Data.Data -- Core.Point#COORDINATE
|
||||
Text = Coordinate:ToStringWind( ReportGroup:GetUnit(1), nil, self )
|
||||
end
|
||||
if Key == "CargoSet" then
|
||||
if Key == "Cargo" then
|
||||
local DataText = Data.Data -- #string
|
||||
Text = DataText
|
||||
end
|
||||
|
||||
@ -62,8 +62,6 @@ do -- TASK_A2A
|
||||
local Fsm = self:GetUnitProcess()
|
||||
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "RouteToRendezVous", Rejected = "Reject" } )
|
||||
|
||||
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
|
||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||
@ -84,6 +82,15 @@ do -- TASK_A2A
|
||||
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
|
||||
---- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param #TASK_CARGO Task
|
||||
function Fsm:OnLeaveAssigned( TaskUnit, Task )
|
||||
self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
self:SelectAction()
|
||||
end
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
|
||||
@ -61,9 +61,6 @@ do -- TASK_A2G
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "RouteToRendezVous", Rejected = "Reject" } )
|
||||
|
||||
Fsm:AddTransition( "Assigned", "RouteToRendezVous", "RoutingToRendezVous" )
|
||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousPoint", ACT_ROUTE_POINT:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||
Fsm:AddProcess ( "RoutingToRendezVous", "RouteToRendezVousZone", ACT_ROUTE_ZONE:New(), { Arrived = "ArriveAtRendezVous" } )
|
||||
@ -84,6 +81,18 @@ do -- TASK_A2G
|
||||
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_A2G#TASK_A2G Task
|
||||
function Fsm:onafterAssigned( TaskUnit, Task )
|
||||
self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
-- Determine the first Unit from the self.RendezVousSetUnit
|
||||
|
||||
self:RouteToRendezVous()
|
||||
end
|
||||
|
||||
--- Test
|
||||
-- @param #FSM_PROCESS self
|
||||
|
||||
@ -215,9 +215,9 @@ do -- TASK_CARGO
|
||||
|
||||
local Fsm = self:GetUnitProcess()
|
||||
|
||||
Fsm:SetStartState( "Planned" )
|
||||
|
||||
Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "SelectAction", Rejected = "Reject" } )
|
||||
-- Fsm:SetStartState( "Planned" )
|
||||
--
|
||||
-- Fsm:AddProcess ( "Planned", "Accept", ACT_ASSIGN_ACCEPT:New( self.TaskBriefing ), { Assigned = "SelectAction", Rejected = "Reject" } )
|
||||
|
||||
Fsm:AddTransition( { "Planned", "Assigned", "Cancelled", "WaitingForCommand", "ArrivedAtPickup", "ArrivedAtDeploy", "Boarded", "UnBoarded", "Loaded", "UnLoaded", "Landed", "Boarding" }, "SelectAction", "*" )
|
||||
|
||||
@ -252,26 +252,29 @@ do -- TASK_CARGO
|
||||
Fsm:AddTransition( "Deployed", "Success", "Success" )
|
||||
Fsm:AddTransition( "Rejected", "Reject", "Aborted" )
|
||||
Fsm:AddTransition( "Failed", "Fail", "Failed" )
|
||||
|
||||
|
||||
---- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param #TASK_CARGO Task
|
||||
function Fsm:OnAfterAssigned( TaskUnit, Task )
|
||||
self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
self:SelectAction()
|
||||
end
|
||||
|
||||
|
||||
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_CARGO#TASK_CARGO Task
|
||||
-- @param #TASK_CARGO Task
|
||||
function Fsm:onafterSelectAction( TaskUnit, Task )
|
||||
|
||||
local TaskUnitName = TaskUnit:GetName()
|
||||
|
||||
self:F( { TaskUnit = TaskUnitName, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
local MenuTime = timer.getTime()
|
||||
|
||||
TaskUnit.Menu = MENU_GROUP:New( TaskUnit:GetGroup(), Task:GetName() .. " @ " .. TaskUnit:GetName() )
|
||||
|
||||
local MenuTime = Task:InitTaskControlMenu( TaskUnit )
|
||||
local MenuControl = Task:GetTaskControlMenu( TaskUnit )
|
||||
local CargoItemCount = TaskUnit:CargoItemCount()
|
||||
|
||||
--Task:GetMission():GetCommandCenter():MessageToGroup( "Cargo in carrier: " .. CargoItemCount, TaskUnit:GetGroup() )
|
||||
|
||||
|
||||
Task.SetCargo:ForEachCargo(
|
||||
|
||||
@ -284,16 +287,17 @@ do -- TASK_CARGO
|
||||
-- MENU_GROUP_COMMAND:New(
|
||||
-- TaskUnit:GetGroup(),
|
||||
-- "Cancel Route " .. Cargo.Name,
|
||||
-- TaskUnit.Menu,
|
||||
-- MenuControl,
|
||||
-- self.MenuRouteToPickupCancel,
|
||||
-- self,
|
||||
-- Cargo
|
||||
-- ):SetTime(MenuTime)
|
||||
-- end
|
||||
|
||||
self:F( { CargoUnloaded = Cargo:IsUnLoaded(), CargoLoaded = Cargo:IsLoaded(), CargoItemCount = CargoItemCount } )
|
||||
Task:E( { TaskDeployZones = Task.DeployZones, TaskName = Task:GetName() } )
|
||||
--self:F( { CargoUnloaded = Cargo:IsUnLoaded(), CargoLoaded = Cargo:IsLoaded(), CargoItemCount = CargoItemCount } )
|
||||
|
||||
local TaskGroup = TaskUnit:GetGroup()
|
||||
|
||||
if Cargo:IsUnLoaded() then
|
||||
if CargoItemCount < 1 then
|
||||
if Cargo:IsInReportRadius( TaskUnit:GetPointVec2() ) then
|
||||
@ -307,40 +311,39 @@ do -- TASK_CARGO
|
||||
if not TaskUnit:InAir() then
|
||||
if Cargo:CanBoard() == true then
|
||||
if Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then
|
||||
Cargo:Report( "ready for boarding at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "board", TaskUnit:GetGroup() )
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Board cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuBoardCargo, self, Cargo ):SetTime(MenuTime)
|
||||
Cargo:Report( "Ready for boarding.", "board", TaskUnit:GetGroup() )
|
||||
local BoardMenu = MENU_GROUP:New( TaskGroup, "Board cargo", MenuControl ):SetTime( MenuTime ):SetTag( "Cargo" )
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), Cargo.Name, BoardMenu, self.MenuBoardCargo, self, Cargo ):SetTime(MenuTime):SetTag("Cargo"):SetRemoveParent()
|
||||
else
|
||||
Cargo:Report( "Board at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "reporting", TaskUnit:GetGroup() )
|
||||
Cargo:Report( "Board at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() .. "." ), "reporting", TaskUnit:GetGroup() )
|
||||
end
|
||||
else
|
||||
if Cargo:CanLoad() == true then
|
||||
if Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then
|
||||
Cargo:Report( "ready for loading at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "load", TaskUnit:GetGroup() )
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Load cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuLoadCargo, self, Cargo ):SetTime(MenuTime)
|
||||
Cargo:Report( "Ready for loading.", "load", TaskUnit:GetGroup() )
|
||||
local LoadMenu = MENU_GROUP:New( TaskGroup, "Load cargo", MenuControl ):SetTime( MenuTime ):SetTag( "Cargo" )
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), Cargo.Name, LoadMenu, self.MenuLoadCargo, self, Cargo ):SetTime(MenuTime):SetTag("Cargo"):SetRemoveParent()
|
||||
else
|
||||
Cargo:Report( "Load at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "reporting", TaskUnit:GetGroup() )
|
||||
Cargo:Report( "Load at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ) .. " within " .. Cargo.NearRadius .. ".", "reporting", TaskUnit:GetGroup() )
|
||||
end
|
||||
else
|
||||
if Cargo:CanSlingload() == true then
|
||||
if Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then
|
||||
Cargo:Report( "ready for slingloading at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "slingload", TaskUnit:GetGroup() )
|
||||
Cargo:Report( "Ready for slingloading.", "slingload", TaskUnit:GetGroup() )
|
||||
else
|
||||
Cargo:Report( "Slingload at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "reporting", TaskUnit:GetGroup() )
|
||||
Cargo:Report( "Slingload at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ) .. ".", "reporting", TaskUnit:GetGroup() )
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
TaskUnit.Menu:SetTime( MenuTime )
|
||||
else
|
||||
Cargo:ReportResetAll( TaskUnit:GetGroup() )
|
||||
end
|
||||
end
|
||||
else
|
||||
if self:Is( "RoutingToPickup" ) then
|
||||
else
|
||||
self:F("route menu set")
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Route to Pickup cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuRouteToPickup, self, Cargo ):SetTime(MenuTime)
|
||||
TaskUnit.Menu:SetTime( MenuTime )
|
||||
if not Cargo:IsDeployed() == true then
|
||||
local RouteToPickupMenu = MENU_GROUP:New( TaskGroup, "Route to pickup cargo", MenuControl ):SetTime( MenuTime ):SetTag( "Cargo" )
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), Cargo.Name, RouteToPickupMenu, self.MenuRouteToPickup, self, Cargo ):SetTime(MenuTime):SetTag("Cargo"):SetRemoveParent()
|
||||
Cargo:ReportResetAll( TaskUnit:GetGroup() )
|
||||
end
|
||||
end
|
||||
@ -348,7 +351,6 @@ do -- TASK_CARGO
|
||||
|
||||
-- Cargo in deployzones are flagged as deployed.
|
||||
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
|
||||
Task:E( { DeployZone = DeployZone } )
|
||||
if Cargo:IsInZone( DeployZone ) then
|
||||
Task:E( { CargoIsDeployed = Task.CargoDeployed and "true" or "false" } )
|
||||
if Cargo:IsDeployed() == false then
|
||||
@ -367,20 +369,22 @@ do -- TASK_CARGO
|
||||
if Cargo:IsLoaded() == true and Cargo:IsLoadedInCarrier( TaskUnit ) == true then
|
||||
if not TaskUnit:InAir() then
|
||||
if Cargo:CanUnboard() == true then
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Unboard cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuUnboardCargo, self, Cargo ):SetTime(MenuTime)
|
||||
local UnboardMenu = MENU_GROUP:New( TaskGroup, "Unboard cargo", MenuControl ):SetTime( MenuTime ):SetTag( "Cargo" )
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), Cargo.Name, UnboardMenu, self.MenuUnboardCargo, self, Cargo ):SetTime(MenuTime):SetTag("Cargo"):SetRemoveParent()
|
||||
else
|
||||
if Cargo:CanUnload() == true then
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Unload cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuUnloadCargo, self, Cargo ):SetTime(MenuTime)
|
||||
local UnloadMenu = MENU_GROUP:New( TaskGroup, "Unload cargo", MenuControl ):SetTime( MenuTime ):SetTag( "Cargo" )
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), Cargo.Name, UnloadMenu, self.MenuUnloadCargo, self, Cargo ):SetTime(MenuTime):SetTag("Cargo"):SetRemoveParent()
|
||||
end
|
||||
end
|
||||
TaskUnit.Menu:SetTime( MenuTime )
|
||||
end
|
||||
-- Deployzones are optional zones that can be selected to request routing information.
|
||||
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
|
||||
if not Cargo:IsInZone( DeployZone ) then
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Route to Deploy cargo at " .. DeployZoneName, TaskUnit.Menu, self.MenuRouteToDeploy, self, DeployZone ):SetTime(MenuTime)
|
||||
TaskUnit.Menu:SetTime( MenuTime )
|
||||
end
|
||||
end
|
||||
|
||||
-- Deployzones are optional zones that can be selected to request routing information.
|
||||
for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do
|
||||
if not Cargo:IsInZone( DeployZone ) then
|
||||
local RouteToDeployMenu = MENU_GROUP:New( TaskGroup, "Route to deploy cargo", MenuControl ):SetTime( MenuTime ):SetTag( "Cargo" )
|
||||
MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Zone " .. DeployZoneName, RouteToDeployMenu, self.MenuRouteToDeploy, self, DeployZone ):SetTime(MenuTime):SetTag("Cargo"):SetRemoveParent()
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -388,8 +392,7 @@ do -- TASK_CARGO
|
||||
end
|
||||
)
|
||||
|
||||
TaskUnit.Menu:Remove( MenuTime )
|
||||
|
||||
Task:RefreshTaskControlMenu( TaskUnit, MenuTime, "Cargo" )
|
||||
|
||||
self:__SelectAction( -1 )
|
||||
|
||||
@ -399,11 +402,13 @@ do -- TASK_CARGO
|
||||
---
|
||||
-- @param #FSM_PROCESS self
|
||||
-- @param Wrapper.Unit#UNIT TaskUnit
|
||||
-- @param Tasking.Task_Cargo#TASK_CARGO Task
|
||||
-- @param #TASK_CARGO Task
|
||||
function Fsm:OnLeaveWaitingForCommand( TaskUnit, Task )
|
||||
self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
TaskUnit.Menu:Remove()
|
||||
--local MenuControl = Task:GetTaskControlMenu( TaskUnit )
|
||||
|
||||
--MenuControl:Remove()
|
||||
end
|
||||
|
||||
function Fsm:MenuBoardCargo( Cargo )
|
||||
@ -639,7 +644,7 @@ do -- TASK_CARGO
|
||||
local TaskUnitName = TaskUnit:GetName()
|
||||
self:F( { TaskUnit = TaskUnitName, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
Cargo:MessageToGroup( "Boarded ...", TaskUnit:GetGroup() )
|
||||
Cargo:MessageToGroup( "Boarded cargo " .. Cargo:GetName(), TaskUnit:GetGroup() )
|
||||
|
||||
self:__Load( -0.1, Cargo )
|
||||
|
||||
@ -658,7 +663,7 @@ do -- TASK_CARGO
|
||||
Cargo:Load( TaskUnit )
|
||||
end
|
||||
|
||||
Cargo:MessageToGroup( "Loaded ...", TaskUnit:GetGroup() )
|
||||
Cargo:MessageToGroup( "Loaded cargo " .. Cargo:GetName(), TaskUnit:GetGroup() )
|
||||
TaskUnit:AddCargo( Cargo )
|
||||
|
||||
Task:CargoPickedUp( TaskUnit, Cargo )
|
||||
@ -732,7 +737,7 @@ do -- TASK_CARGO
|
||||
local TaskUnitName = TaskUnit:GetName()
|
||||
self:F( { TaskUnit = TaskUnitName, Task = Task and Task:GetClassNameAndID() } )
|
||||
|
||||
self.Cargo:MessageToGroup( "UnBoarded ...", TaskUnit:GetGroup() )
|
||||
self.Cargo:MessageToGroup( "UnBoarded cargo " .. self.Cargo:GetName(), TaskUnit:GetGroup() )
|
||||
|
||||
self:Unload( self.Cargo )
|
||||
end
|
||||
@ -755,6 +760,8 @@ do -- TASK_CARGO
|
||||
end
|
||||
TaskUnit:RemoveCargo( Cargo )
|
||||
|
||||
Cargo:MessageToGroup( "Unloaded cargo " .. Cargo:GetName(), TaskUnit:GetGroup() )
|
||||
|
||||
self:Planned()
|
||||
self:__SelectAction( 1 )
|
||||
end
|
||||
@ -820,12 +827,15 @@ do -- TASK_CARGO
|
||||
|
||||
self:F({Cargo, TaskUnit})
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local MenuTime = self:InitTaskControlMenu( TaskUnit )
|
||||
local MenuControl = self:GetTaskControlMenu( TaskUnit )
|
||||
|
||||
local ActRouteCargo = ProcessUnit:GetProcess( "RoutingToPickup", "RouteToPickupPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT
|
||||
ActRouteCargo:Reset()
|
||||
ActRouteCargo:SetCoordinate( Cargo:GetCoordinate() )
|
||||
ActRouteCargo:SetRange( Cargo:GetLoadRadius() )
|
||||
ActRouteCargo:SetMenuCancel( TaskUnit:GetGroup(), "Cancel Routing to Cargo " .. Cargo:GetName(), TaskUnit.Menu )
|
||||
ActRouteCargo:SetMenuCancel( TaskUnit:GetGroup(), "Cancel Routing to Cargo " .. Cargo:GetName(), MenuControl, MenuTime, "Cargo" )
|
||||
ActRouteCargo:Start()
|
||||
|
||||
return self
|
||||
@ -840,10 +850,13 @@ do -- TASK_CARGO
|
||||
|
||||
local ProcessUnit = self:GetUnitProcess( TaskUnit )
|
||||
|
||||
local MenuTime = self:InitTaskControlMenu( TaskUnit )
|
||||
local MenuControl = self:GetTaskControlMenu( TaskUnit )
|
||||
|
||||
local ActRouteDeployZone = ProcessUnit:GetProcess( "RoutingToDeploy", "RouteToDeployZone" ) -- Actions.Act_Route#ACT_ROUTE_ZONE
|
||||
ActRouteDeployZone:Reset()
|
||||
ActRouteDeployZone:SetZone( DeployZone )
|
||||
ActRouteDeployZone:SetMenuCancel( TaskUnit:GetGroup(), "Cancel Routing to Deploy Zone" .. DeployZone:GetName(), TaskUnit.Menu )
|
||||
ActRouteDeployZone:SetMenuCancel( TaskUnit:GetGroup(), "Cancel Routing to Deploy Zone" .. DeployZone:GetName(), MenuControl, MenuTime, "Cargo" )
|
||||
ActRouteDeployZone:Start()
|
||||
|
||||
return self
|
||||
@ -960,7 +973,6 @@ do -- TASK_CARGO
|
||||
function TASK_CARGO:UpdateTaskInfo( DetectedItem )
|
||||
|
||||
if self:IsStatePlanned() or self:IsStateAssigned() then
|
||||
self.TaskInfo:AddTaskName( 0, "MSOD" )
|
||||
self.TaskInfo:AddCargoSet( self.SetCargo, 10, "SOD", true )
|
||||
end
|
||||
end
|
||||
@ -970,6 +982,8 @@ do -- TASK_CARGO
|
||||
return 0
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -439,6 +439,7 @@ do -- TASK_CARGO_DISPATCHER
|
||||
function TASK_CARGO_DISPATCHER:AddTransportTask( TaskName, SetCargo, Briefing )
|
||||
|
||||
self.TransportCount = self.TransportCount + 1
|
||||
|
||||
local TaskName = string.format( ( TaskName or "Transport" ) .. ".%03d", self.TransportCount )
|
||||
|
||||
self.Transport[TaskName] = {}
|
||||
@ -446,7 +447,7 @@ do -- TASK_CARGO_DISPATCHER
|
||||
self.Transport[TaskName].Briefing = Briefing
|
||||
self.Transport[TaskName].Task = nil
|
||||
|
||||
return self
|
||||
return TaskName
|
||||
end
|
||||
|
||||
|
||||
|
||||
@ -10,7 +10,7 @@ do -- TASK_CARGO_TRANSPORT
|
||||
|
||||
--- The TASK_CARGO_TRANSPORT class
|
||||
-- @type TASK_CARGO_TRANSPORT
|
||||
-- @extends Tasking.Task_Cargo#TASK_CARGO
|
||||
-- @extends Tasking.Task_CARGO#TASK_CARGO
|
||||
TASK_CARGO_TRANSPORT = {
|
||||
ClassName = "TASK_CARGO_TRANSPORT",
|
||||
}
|
||||
|
||||
@ -179,10 +179,10 @@ function CLIENT:ShowBriefing()
|
||||
if not self.ClientBriefingShown then
|
||||
self.ClientBriefingShown = true
|
||||
local Briefing = ""
|
||||
if self.ClientBriefing then
|
||||
if self.ClientBriefing and self.ClientBriefing ~= "" then
|
||||
Briefing = Briefing .. self.ClientBriefing
|
||||
self:Message( Briefing, 60, "Briefing" )
|
||||
end
|
||||
self:Message( Briefing, 60, "Briefing" )
|
||||
end
|
||||
|
||||
return self
|
||||
|
||||
@ -2223,7 +2223,7 @@ function CONTROLLABLE:GetDetectedTargets( DetectVisual, DetectOptical, DetectRad
|
||||
local DetectionRWR = ( DetectRWR and DetectRWR == true ) and Controller.Detection.RWR or nil
|
||||
local DetectionDLINK = ( DetectDLINK and DetectDLINK == true ) and Controller.Detection.DLINK or nil
|
||||
|
||||
self:T( { DetectionVisual, DetectionOptical, DetectionRadar, DetectionIRST, DetectionRWR, DetectionDLINK } )
|
||||
self:T2( { DetectionVisual, DetectionOptical, DetectionRadar, DetectionIRST, DetectionRWR, DetectionDLINK } )
|
||||
|
||||
return self:_GetController():getDetectedTargets( DetectionVisual, DetectionOptical, DetectionRadar, DetectionIRST, DetectionRWR, DetectionDLINK )
|
||||
end
|
||||
|
||||
@ -352,13 +352,39 @@ function GROUP:GetUnits()
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns a list of @{Unit} objects of the @{Group} that are occupied by a player.
|
||||
-- @param #GROUP self
|
||||
-- @return #list<Wrapper.Unit#UNIT> The list of player occupied @{Unit} objects of the @{Group}.
|
||||
function GROUP:GetPlayerUnits()
|
||||
self:F2( { self.GroupName } )
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
local DCSUnits = DCSGroup:getUnits()
|
||||
local Units = {}
|
||||
for Index, UnitData in pairs( DCSUnits ) do
|
||||
local PlayerUnit = UNIT:Find( UnitData )
|
||||
if PlayerUnit:GetPlayerName() then
|
||||
Units[#Units+1] = PlayerUnit
|
||||
end
|
||||
end
|
||||
self:T3( Units )
|
||||
return Units
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Returns the UNIT wrapper class with number UnitNumber.
|
||||
-- If the underlying DCS Unit does not exist, the method will return nil. .
|
||||
-- @param #GROUP self
|
||||
-- @param #number UnitNumber The number of the UNIT wrapper class to be returned.
|
||||
-- @return Wrapper.Unit#UNIT The UNIT wrapper class.
|
||||
function GROUP:GetUnit( UnitNumber )
|
||||
self:E( { self.GroupName, UnitNumber } )
|
||||
self:F3( { self.GroupName, UnitNumber } )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
@ -378,7 +404,7 @@ end
|
||||
-- @param #number UnitNumber The number of the DCS Unit to be returned.
|
||||
-- @return Dcs.DCSWrapper.Unit#Unit The DCS Unit.
|
||||
function GROUP:GetDCSUnit( UnitNumber )
|
||||
self:F2( { self.GroupName, UnitNumber } )
|
||||
self:F3( { self.GroupName, UnitNumber } )
|
||||
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
@ -396,7 +422,7 @@ end
|
||||
-- @param #GROUP self
|
||||
-- @return #number The DCS Group size.
|
||||
function GROUP:GetSize()
|
||||
self:F2( { self.GroupName } )
|
||||
self:F3( { self.GroupName } )
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
@ -419,7 +445,7 @@ end
|
||||
-- @param #GROUP self
|
||||
-- @return #number The DCS Group initial size.
|
||||
function GROUP:GetInitialSize()
|
||||
self:F2( { self.GroupName } )
|
||||
self:F3( { self.GroupName } )
|
||||
local DCSGroup = self:GetDCSObject()
|
||||
|
||||
if DCSGroup then
|
||||
@ -1115,7 +1141,7 @@ function GROUP:Respawn( Template, Reset )
|
||||
else
|
||||
for UnitID, TemplateUnitData in pairs( Template.units ) do
|
||||
self:F( "Reset" )
|
||||
local GroupUnitVec3 = { x = TemplateUnitData.x, y = TemplateUnitData.alt, z = TemplateUnitData.z }
|
||||
local GroupUnitVec3 = { x = TemplateUnitData.x, y = TemplateUnitData.alt, z = TemplateUnitData.y }
|
||||
if Zone then
|
||||
if self.InitRespawnRandomizePositionZone then
|
||||
GroupUnitVec3 = Zone:GetRandomVec3()
|
||||
@ -1148,7 +1174,101 @@ function GROUP:Respawn( Template, Reset )
|
||||
end
|
||||
|
||||
|
||||
--- @param Wrapper.Group#GROUP self
|
||||
function GROUP:RespawnAtAirbase( AirbaseRespawn, Takeoff, TakeoffAltitude ) -- R2.4
|
||||
self:F( { AirbaseRespawn, Takeoff, TakeoffAltitude } )
|
||||
|
||||
local PointVec3 = AirbaseRespawn:GetPointVec3()
|
||||
|
||||
Takeoff = Takeoff or SPAWN.Takeoff.Hot
|
||||
|
||||
local SpawnTemplate = self:GetTemplate()
|
||||
|
||||
if SpawnTemplate then
|
||||
|
||||
local SpawnPoint = SpawnTemplate.route.points[1]
|
||||
|
||||
-- These are only for ships.
|
||||
SpawnPoint.linkUnit = nil
|
||||
SpawnPoint.helipadId = nil
|
||||
SpawnPoint.airdromeId = nil
|
||||
|
||||
local AirbaseID = AirbaseRespawn:GetID()
|
||||
local AirbaseCategory = AirbaseRespawn:GetDesc().category
|
||||
self:F( { AirbaseCategory = AirbaseCategory, Ship = Airbase.Category.SHIP, Helipad = Airbase.Category.HELIPAD, Airdrome = Airbase.Category.AIRDROME } )
|
||||
|
||||
if AirbaseCategory == Airbase.Category.SHIP then
|
||||
SpawnPoint.linkUnit = AirbaseID
|
||||
SpawnPoint.helipadId = AirbaseID
|
||||
elseif AirbaseCategory == Airbase.Category.HELIPAD then
|
||||
SpawnPoint.linkUnit = AirbaseID
|
||||
SpawnPoint.helipadId = AirbaseID
|
||||
elseif AirbaseCategory == Airbase.Category.AIRDROME then
|
||||
SpawnPoint.airdromeId = AirbaseID
|
||||
end
|
||||
|
||||
SpawnPoint.alt = 0
|
||||
|
||||
SpawnPoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type
|
||||
SpawnPoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action
|
||||
|
||||
|
||||
-- Translate the position of the Group Template to the Vec3.
|
||||
for UnitID = 1, #SpawnTemplate.units do
|
||||
self:T( 'Before Translation SpawnTemplate.units['..UnitID..'].x = ' .. SpawnTemplate.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. SpawnTemplate.units[UnitID].y )
|
||||
|
||||
-- These cause a lot of confusion.
|
||||
local UnitTemplate = SpawnTemplate.units[UnitID]
|
||||
|
||||
UnitTemplate.parking = 15
|
||||
UnitTemplate.parking_id = "30"
|
||||
UnitTemplate.alt = 0
|
||||
|
||||
local SX = UnitTemplate.x
|
||||
local SY = UnitTemplate.y
|
||||
local BX = SpawnPoint.x
|
||||
local BY = SpawnPoint.y
|
||||
local TX = PointVec3.x + ( SX - BX )
|
||||
local TY = PointVec3.z + ( SY - BY )
|
||||
|
||||
UnitTemplate.x = TX
|
||||
UnitTemplate.y = TY
|
||||
|
||||
if Takeoff == GROUP.Takeoff.Air then
|
||||
UnitTemplate.alt = PointVec3.y + ( TakeoffAltitude or 200 )
|
||||
--else
|
||||
-- UnitTemplate.alt = PointVec3.y + 10
|
||||
end
|
||||
self:T( 'After Translation SpawnTemplate.units['..UnitID..'].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. UnitTemplate.y )
|
||||
end
|
||||
|
||||
SpawnPoint.x = PointVec3.x
|
||||
SpawnPoint.y = PointVec3.z
|
||||
|
||||
if Takeoff == GROUP.Takeoff.Air then
|
||||
SpawnPoint.alt = PointVec3.y + ( TakeoffAltitude or 200 )
|
||||
--else
|
||||
-- SpawnPoint.alt = PointVec3.y + 10
|
||||
end
|
||||
|
||||
SpawnTemplate.x = PointVec3.x
|
||||
SpawnTemplate.y = PointVec3.z
|
||||
|
||||
local GroupSpawned = self:Respawn( SpawnTemplate )
|
||||
|
||||
-- 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 GroupSpawned
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Return the mission template of the group.
|
||||
@ -1382,6 +1502,8 @@ do -- Players
|
||||
-- @return #nil The group has no players
|
||||
function GROUP:GetPlayerNames()
|
||||
|
||||
local HasPlayers = false
|
||||
|
||||
local PlayerNames = {}
|
||||
|
||||
local Units = self:GetUnits()
|
||||
@ -1391,11 +1513,36 @@ do -- Players
|
||||
if PlayerName and PlayerName ~= "" then
|
||||
PlayerNames = PlayerNames or {}
|
||||
table.insert( PlayerNames, PlayerName )
|
||||
HasPlayers = true
|
||||
end
|
||||
end
|
||||
|
||||
if HasPlayers == true then
|
||||
self:F2( PlayerNames )
|
||||
return PlayerNames
|
||||
end
|
||||
|
||||
self:F2( PlayerNames )
|
||||
return PlayerNames
|
||||
return nil
|
||||
end
|
||||
|
||||
|
||||
--- Get the active player count in the group.
|
||||
-- @param #GROUP self
|
||||
-- @return #number The amount of players.
|
||||
function GROUP:GetPlayerCount()
|
||||
|
||||
local PlayerCount = 0
|
||||
|
||||
local Units = self:GetUnits()
|
||||
for UnitID, UnitData in pairs( Units or {} ) do
|
||||
local Unit = UnitData -- Wrapper.Unit#UNIT
|
||||
local PlayerName = Unit:GetPlayerName()
|
||||
if PlayerName and PlayerName ~= "" then
|
||||
PlayerCount = PlayerCount + 1
|
||||
end
|
||||
end
|
||||
|
||||
return PlayerCount
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@ -73,6 +73,7 @@ end
|
||||
|
||||
--- Destroys the OBJECT.
|
||||
-- @param #OBJECT self
|
||||
-- @return #boolean true if the object is destroyed.
|
||||
-- @return #nil The DCS Unit is not existing or alive.
|
||||
function OBJECT:Destroy()
|
||||
|
||||
@ -80,7 +81,8 @@ function OBJECT:Destroy()
|
||||
|
||||
if DCSObject then
|
||||
--BASE:CreateEventCrash( timer.getTime(), DCSObject )
|
||||
DCSObject:destroy()
|
||||
DCSObject:destroy( false )
|
||||
return true
|
||||
end
|
||||
|
||||
BASE:E( { "Cannot Destroy", Name = self.ObjectName, Class = self:GetClassName() } )
|
||||
|
||||
@ -129,7 +129,7 @@ function POSITIONABLE:GetPointVec2()
|
||||
|
||||
local PositionablePointVec2 = POINT_VEC2:NewFromVec3( PositionableVec3 )
|
||||
|
||||
self:T( PositionablePointVec2 )
|
||||
--self:F( PositionablePointVec2 )
|
||||
return PositionablePointVec2
|
||||
end
|
||||
|
||||
@ -538,10 +538,11 @@ end
|
||||
-- @param #string Message The message text
|
||||
-- @param Dcs.DCSTYpes#Duration Duration The duration of the message.
|
||||
-- @param Dcs.DCScoalition#coalition MessageCoalition The Coalition receiving the message.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageToCoalition( Message, Duration, MessageCoalition, Name )
|
||||
self:F2( { Message, Duration } )
|
||||
|
||||
local Name = ""
|
||||
local Name = Name or ""
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
@ -558,10 +559,11 @@ end
|
||||
-- @param #string Message The message text
|
||||
-- @param Core.Message#MESSAGE.Type MessageType The message type that determines the duration.
|
||||
-- @param Dcs.DCScoalition#coalition MessageCoalition The Coalition receiving the message.
|
||||
function POSITIONABLE:MessageTypeToCoalition( Message, MessageType, MessageCoalition )
|
||||
-- @param #string Name (optional) The Name of the sender. If not provided, the Name is the type of the Positionable.
|
||||
function POSITIONABLE:MessageTypeToCoalition( Message, MessageType, MessageCoalition, Name )
|
||||
self:F2( { Message, MessageType } )
|
||||
|
||||
local Name = ""
|
||||
local Name = Name or ""
|
||||
|
||||
local DCSObject = self:GetDCSObject()
|
||||
if DCSObject then
|
||||
|
||||
@ -130,12 +130,32 @@ end
|
||||
-- @param #UNIT self
|
||||
-- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static.
|
||||
-- @param #number Heading The heading of the unit respawn.
|
||||
function STATIC:ReSpawn( Coordinate, Heading )
|
||||
function STATIC:SpawnAt( Coordinate, Heading )
|
||||
|
||||
|
||||
-- todo: need to fix country
|
||||
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName )
|
||||
|
||||
SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName )
|
||||
end
|
||||
|
||||
|
||||
--- Respawn the @{Unit} at the same location with the same properties.
|
||||
-- This is useful to respawn a cargo after it has been destroyed.
|
||||
-- @param #UNIT self
|
||||
function STATIC:ReSpawn()
|
||||
|
||||
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName )
|
||||
|
||||
SpawnStatic:ReSpawn()
|
||||
end
|
||||
|
||||
|
||||
--- Respawn the @{Unit} at a defined Coordinate with an optional heading.
|
||||
-- @param #UNIT self
|
||||
-- @param Core.Point#COORDINATE Coordinate The coordinate where to spawn the new Static.
|
||||
-- @param #number Heading The heading of the unit respawn.
|
||||
function STATIC:ReSpawnAt( Coordinate, Heading )
|
||||
|
||||
local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName )
|
||||
|
||||
SpawnStatic:ReSpawnAt( Coordinate, Heading )
|
||||
end
|
||||
|
||||
@ -189,9 +189,9 @@ end
|
||||
-- * Then it will respawn the re-modelled group.
|
||||
--
|
||||
-- @param #UNIT self
|
||||
-- @param Dcs.DCSTypes#Vec3 SpawnVec3 The position where to Spawn the new Unit at.
|
||||
-- @param Core.Point#COORDINATE Coordinate The position where to Spawn the new Unit at.
|
||||
-- @param #number Heading The heading of the unit respawn.
|
||||
function UNIT:ReSpawn( SpawnVec3, Heading )
|
||||
function UNIT:ReSpawnAt( Coordinate, Heading )
|
||||
|
||||
self:T( self:Name() )
|
||||
local SpawnGroupTemplate = UTILS.DeepCopy( _DATABASE:GetGroupTemplateFromUnitName( self:Name() ) )
|
||||
@ -203,8 +203,8 @@ function UNIT:ReSpawn( SpawnVec3, Heading )
|
||||
if SpawnGroup then
|
||||
|
||||
local Vec3 = SpawnGroup:GetVec3()
|
||||
SpawnGroupTemplate.x = SpawnVec3.x
|
||||
SpawnGroupTemplate.y = SpawnVec3.z
|
||||
SpawnGroupTemplate.x = Coordinate.x
|
||||
SpawnGroupTemplate.y = Coordinate.z
|
||||
|
||||
self:F( #SpawnGroupTemplate.units )
|
||||
for UnitID, UnitData in pairs( SpawnGroup:GetUnits() ) do
|
||||
@ -227,9 +227,9 @@ function UNIT:ReSpawn( SpawnVec3, Heading )
|
||||
SpawnGroupTemplate.units[UnitTemplateID].unitId = nil
|
||||
if UnitTemplateData.name == self:Name() then
|
||||
self:T("Adjusting")
|
||||
SpawnGroupTemplate.units[UnitTemplateID].alt = SpawnVec3.y
|
||||
SpawnGroupTemplate.units[UnitTemplateID].x = SpawnVec3.x
|
||||
SpawnGroupTemplate.units[UnitTemplateID].y = SpawnVec3.z
|
||||
SpawnGroupTemplate.units[UnitTemplateID].alt = Coordinate.y
|
||||
SpawnGroupTemplate.units[UnitTemplateID].x = Coordinate.x
|
||||
SpawnGroupTemplate.units[UnitTemplateID].y = Coordinate.z
|
||||
SpawnGroupTemplate.units[UnitTemplateID].heading = Heading
|
||||
self:F( { UnitTemplateID, SpawnGroupTemplate.units[UnitTemplateID], SpawnGroupTemplate.units[UnitTemplateID] } )
|
||||
else
|
||||
@ -344,18 +344,30 @@ end
|
||||
function UNIT:GetPlayerName()
|
||||
self:F2( self.UnitName )
|
||||
|
||||
local DCSUnit = self:GetDCSObject()
|
||||
local DCSUnit = self:GetDCSObject() -- Dcs.DCSUnit#Unit
|
||||
|
||||
if DCSUnit then
|
||||
|
||||
local PlayerName = DCSUnit:getPlayerName()
|
||||
if PlayerName == nil then
|
||||
PlayerName = ""
|
||||
-- TODO Workaround DCS-BUG-3 - https://github.com/FlightControl-Master/MOOSE/issues/696
|
||||
if PlayerName == nil or PlayerName == "" then
|
||||
local PlayerCategory = DCSUnit:getDesc().category
|
||||
if PlayerCategory == Unit.Category.GROUND_UNIT or PlayerCategory == Unit.Category.SHIP then
|
||||
PlayerName = "Player" .. DCSUnit:getID()
|
||||
end
|
||||
end
|
||||
-- -- Good code
|
||||
-- if PlayerName == nil then
|
||||
-- PlayerName = nil
|
||||
-- else
|
||||
-- if PlayerName == "" then
|
||||
-- PlayerName = "Player" .. DCSUnit:getID()
|
||||
-- end
|
||||
-- end
|
||||
return PlayerName
|
||||
end
|
||||
|
||||
return nil
|
||||
return nil
|
||||
|
||||
end
|
||||
|
||||
@ -638,12 +650,9 @@ function UNIT:GetThreatLevel()
|
||||
if Descriptor then
|
||||
|
||||
local Attributes = Descriptor.attributes
|
||||
self:T( Attributes )
|
||||
|
||||
if self:IsGround() then
|
||||
|
||||
self:T( "Ground" )
|
||||
|
||||
local ThreatLevels = {
|
||||
"Unarmed",
|
||||
"Infantry",
|
||||
@ -680,8 +689,6 @@ function UNIT:GetThreatLevel()
|
||||
|
||||
if self:IsAir() then
|
||||
|
||||
self:T( "Air" )
|
||||
|
||||
local ThreatLevels = {
|
||||
"Unarmed",
|
||||
"Tanker",
|
||||
@ -714,8 +721,6 @@ function UNIT:GetThreatLevel()
|
||||
|
||||
if self:IsShip() then
|
||||
|
||||
self:T( "Ship" )
|
||||
|
||||
--["Aircraft Carriers"] = {"Heavy armed ships",},
|
||||
--["Cruisers"] = {"Heavy armed ships",},
|
||||
--["Destroyers"] = {"Heavy armed ships",},
|
||||
@ -753,7 +758,6 @@ function UNIT:GetThreatLevel()
|
||||
end
|
||||
end
|
||||
|
||||
self:T2( ThreatLevel )
|
||||
return ThreatLevel, ThreatText
|
||||
|
||||
end
|
||||
|
||||
@ -66,7 +66,9 @@ AI/AI_Cap.lua
|
||||
AI/AI_Cas.lua
|
||||
AI/AI_Bai.lua
|
||||
AI/AI_Formation.lua
|
||||
AI/AI_Cargo_Troops.lua
|
||||
AI/AI_Cargo_APC.lua
|
||||
AI/AI_Cargo_Helicopter.lua
|
||||
AI/AI_Cargo_Airplane.lua
|
||||
|
||||
Actions/Act_Assign.lua
|
||||
Actions/Act_Route.lua
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user