From 269b52fd0eb7ab05314327700cebeb1ee71d7529 Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Fri, 6 Apr 2018 21:28:43 +0200 Subject: [PATCH 1/4] Fixed slingload deploy problem. Fixed messaging. Now a message is shown when cargo reports itself when in LoadRange and when near, it will allow for loading of cargo. Fixed the perception that cargo can be boarded when loaded in an other carrier, which is totally wrong. --- Moose Development/Moose/Cargo/Cargo.lua | 234 ++++++++++++++---- Moose Development/Moose/Cargo/CargoCrate.lua | 51 ++-- Moose Development/Moose/Cargo/CargoGroup.lua | 43 +++- .../Moose/Cargo/CargoSlingload.lua | 52 ++-- Moose Development/Moose/Cargo/CargoUnit.lua | 2 +- .../Moose/Tasking/Task_CARGO.lua | 68 ++--- 6 files changed, 305 insertions(+), 145 deletions(-) diff --git a/Moose Development/Moose/Cargo/Cargo.lua b/Moose Development/Moose/Cargo/Cargo.lua index 2528b1b32..cdba0ec8f 100644 --- a/Moose Development/Moose/Cargo/Cargo.lua +++ b/Moose Development/Moose/Cargo/Cargo.lua @@ -224,6 +224,7 @@ do -- CARGO Slingloadable = false, Moveable = false, Containable = false, + Reported = {}, } --- @type CARGO.CargoObjects @@ -235,12 +236,13 @@ do -- CARGO -- @param #string Type -- @param #string Name -- @param #number Weight + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO - function CARGO:New( Type, Name, Weight ) --R2.1 + function CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) --R2.1 local self = BASE:Inherit( self, FSM:New() ) -- #CARGO - self:F( { Type, Name, Weight } ) + self:F( { Type, Name, Weight, LoadRadius, NearRadius } ) self:SetStartState( "UnLoaded" ) self:AddTransition( { "UnLoaded", "Boarding" }, "Board", "Boarding" ) @@ -267,6 +269,9 @@ do -- CARGO self.Moveable = false self.Containable = false + self.LoadRadius = LoadRadius or 500 + self.NearRadius = NearRadius or 25 + self:SetDeployed( false ) self.CargoScheduler = SCHEDULER:New() @@ -405,8 +410,9 @@ do -- CARGO end end - --- Set the cargo as deployed + --- Set the cargo as deployed. -- @param #CARGO self + -- @param #boolean Deployed true if the cargo is to be deployed. false or nil otherwise. function CARGO:SetDeployed( Deployed ) self.Deployed = Deployed end @@ -507,7 +513,86 @@ do -- CARGO end + --- Set the Load radius, which is the radius till when the Cargo can be loaded. + -- @param #CARGO self + -- @param #number LoadRadius The radius till Cargo can be loaded. + -- @return #CARGO + function CARGO:SetLoadRadius( LoadRadius ) + self.LoadRadius = LoadRadius or 150 + end + --- Get the Load radius, which is the radius till when the Cargo can be loaded. + -- @param #CARGO self + -- @return #number The radius till Cargo can be loaded. + function CARGO:GetLoadRadius() + return self.LoadRadius + end + + + + --- Check if Cargo is in the LoadRadius for the Cargo to be Boarded or Loaded. + -- @param #CARGO self + -- @param Core.Point#Coordinate Coordinate + -- @return #boolean true if the CargoGroup is within the loading radius. + function CARGO:IsInLoadRadius( Coordinate ) + self:F( { Coordinate } ) + + local Distance = 0 + if self:IsUnLoaded() then + Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + self:T( Distance ) + if Distance <= self.LoadRadius then + return true + end + end + + return false + end + + + --- Check if the Cargo can report itself to be Boarded or Loaded. + -- @param #CARGO self + -- @param Core.Point#Coordinate Coordinate + -- @return #boolean true if the Cargo can report itself. + function CARGO:IsInReportRadius( Coordinate ) + self:F( { Coordinate } ) + + local Distance = 0 + if self:IsUnLoaded() then + Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + self:T( Distance ) + if Distance <= self.LoadRadius then + return true + end + end + + return false + end + + + --- Check if CargoCarrier is near the Cargo to be Loaded. + -- @param #CARGO self + -- @param Core.Point#POINT_VEC2 PointVec2 + -- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision). + -- @return #boolean + function CARGO:IsNear( PointVec2, NearRadius ) + self:F( { PointVec2 = PointVec2, NearRadius = NearRadius } ) + + if self.CargoObject:IsAlive() then + --local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + self:F( { CargoObjectName = self.CargoObject:GetName() } ) + self:F( { CargoObjectVec2 = self.CargoObject:GetVec2() } ) + self:F( { PointVec2 = PointVec2:GetVec2() } ) + local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() ) + self:T( Distance ) + + if Distance <= NearRadius then + return true + end + end + + return false + end @@ -534,30 +619,6 @@ do -- CARGO end - --- Check if CargoCarrier is near the Cargo to be Loaded. - -- @param #CARGO self - -- @param Core.Point#POINT_VEC2 PointVec2 - -- @param #number NearRadius The radius when the cargo will board the Carrier (to avoid collision). - -- @return #boolean - function CARGO:IsNear( PointVec2, NearRadius ) - self:F( { PointVec2 = PointVec2, NearRadius = NearRadius } ) - - if self.CargoObject:IsAlive() then - --local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) - self:F( { CargoObjectName = self.CargoObject:GetName() } ) - self:F( { CargoObjectVec2 = self.CargoObject:GetVec2() } ) - self:F( { PointVec2 = PointVec2:GetVec2() } ) - local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() ) - self:T( Distance ) - - if Distance <= NearRadius then - return true - end - end - - return false - end - --- Get the current PointVec2 of the cargo. -- @param #CARGO self -- @return Core.Point#POINT_VEC2 @@ -580,6 +641,85 @@ do -- CARGO self.Weight = Weight return self end + + --- Send a CC message to a @{Group}. + -- @param #CARGO self + -- @param #string Message + -- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group. + -- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown. + function CARGO:MessageToGroup( Message, CarrierGroup, Name ) + + MESSAGE:New( Message, 20, "Cargo " .. self:GetName() ):ToGroup( CarrierGroup ) + + end + + --- Report to a Carrier Group. + -- @param #CARGO self + -- @param #string Action The string describing the action for the cargo. + -- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group to send the report to. + -- @return #CARGO + function CARGO:Report( ReportText, Action, CarrierGroup ) + + if not self.Reported[CarrierGroup] or not self.Reported[CarrierGroup][Action] then + self.Reported[CarrierGroup] = {} + self.Reported[CarrierGroup][Action] = true + self:MessageToGroup( ReportText, CarrierGroup ) + if self.ReportFlareColor then + if not self.Reported[CarrierGroup]["Flaring"] then + self:Flare( self.ReportFlareColor ) + self.Reported[CarrierGroup]["Flaring"] = true + end + end + if self.ReportSmokeColor then + if not self.Reported[CarrierGroup]["Smoking"] then + self:Smoke( self.ReportSmokeColor ) + self.Reported[CarrierGroup]["Smoking"] = true + end + end + end + end + + + --- Report to a Carrier Group with a Flaring signal. + -- @param #CARGO self + -- @param Utils#UTILS.FlareColor FlareColor the color of the flare. + -- @return #CARGO + function CARGO:ReportFlare( FlareColor ) + + self.ReportFlareColor = FlareColor + end + + + --- Report to a Carrier Group with a Smoking signal. + -- @param #CARGO self + -- @param Utils#UTILS.SmokeColor SmokeColor the color of the smoke. + -- @return #CARGO + function CARGO:ReportSmoke( SmokeColor ) + + self.ReportSmokeColor = SmokeColor + end + + + --- Reset the reporting for a Carrier Group. + -- @param #CARGO self + -- @param #string Action The string describing the action for the cargo. + -- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group to send the report to. + -- @return #CARGO + function CARGO:ReportReset( Action, CarrierGroup ) + + self.Reported[CarrierGroup][Action] = nil + end + + --- Reset all the reporting for a Carrier Group. + -- @param #CARGO self + -- @param Wrapper.Group#GROUP CarrierGroup The Carrier Group to send the report to. + -- @return #CARGO + function CARGO:ReportResetAll( CarrierGroup ) + + self.Reported[CarrierGroup] = nil + end + + end -- CARGO @@ -600,16 +740,13 @@ do -- CARGO_REPRESENTABLE -- @param #string Type -- @param #string Name -- @param #number Weight - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_REPRESENTABLE - function CARGO_REPRESENTABLE:New( CargoObject, Type, Name, Weight, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight ) ) -- #CARGO_REPRESENTABLE - self:F( { Type, Name, Weight, ReportRadius, NearRadius } ) + function CARGO_REPRESENTABLE:New( CargoObject, Type, Name, Weight, LoadRadius, NearRadius ) + local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_REPRESENTABLE + self:F( { Type, Name, Weight, LoadRadius, NearRadius } ) - self.ReportRadius = ReportRadius or 500 - self.NearRadius = NearRadius or 25 - return self end @@ -661,14 +798,12 @@ do -- CARGO_REPORTABLE -- @param #string Type -- @param #string Name -- @param #number Weight - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_REPORTABLE - function CARGO_REPORTABLE:New( Type, Name, Weight, ReportRadius ) - local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight ) ) -- #CARGO_REPORTABLE - self:F( { Type, Name, Weight, ReportRadius } ) - - self.ReportRadius = ReportRadius or 1000 + function CARGO_REPORTABLE:New( Type, Name, Weight, LoadRadius, NearRadius ) + local self = BASE:Inherit( self, CARGO:New( Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_REPORTABLE + self:F( { Type, Name, Weight, LoadRadius, NearRadius } ) return self end @@ -680,19 +815,10 @@ do -- CARGO_REPORTABLE -- @param #sring Name (optional) The name of the Group used as a prefix for the message to the Group. If not provided, there will be nothing shown. function CARGO_REPORTABLE:MessageToGroup( Message, TaskGroup, Name ) - local Prefix = Name and "@ " .. Name .. ": " or "@ " .. TaskGroup:GetCallsign() .. ": " - Message = Prefix .. Message - MESSAGE:New( Message, 20, "Cargo: " .. self:GetName() ):ToGroup( TaskGroup ) + MESSAGE:New( Message, 20, "Cargo " .. self:GetName() ):ToGroup( TaskGroup ) end - --- Get the Report radius, which is the radius when the Cargo is reporting itself. - -- @param #CARGO_REPORTABLE self - -- @return #number The range till Cargo reports itself. - function CARGO_REPORTABLE:GetBoardingRange() - return self.ReportRadius - end - end @@ -717,12 +843,12 @@ do -- CARGO_PACKAGE -- @param #string Type -- @param #string Name -- @param #number Weight --- @param #number ReportRadius (optional) +-- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_PACKAGE -function CARGO_PACKAGE:New( CargoCarrier, Type, Name, Weight, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCarrier, Type, Name, Weight, ReportRadius, NearRadius ) ) -- #CARGO_PACKAGE - self:F( { Type, Name, Weight, ReportRadius, NearRadius } ) +function CARGO_PACKAGE:New( CargoCarrier, Type, Name, Weight, LoadRadius, NearRadius ) + local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCarrier, Type, Name, Weight, LoadRadius, NearRadius ) ) -- #CARGO_PACKAGE + self:F( { Type, Name, Weight, LoadRadius, NearRadius } ) self:T( CargoCarrier ) self.CargoCarrier = CargoCarrier diff --git a/Moose Development/Moose/Cargo/CargoCrate.lua b/Moose Development/Moose/Cargo/CargoCrate.lua index 1f083a010..44ef41af6 100644 --- a/Moose Development/Moose/Cargo/CargoCrate.lua +++ b/Moose Development/Moose/Cargo/CargoCrate.lua @@ -23,7 +23,7 @@ do -- CARGO_CRATE --- Models the behaviour of cargo crates, which can be slingloaded and boarded on helicopters. -- @type CARGO_CRATE - -- @extends #CARGO_REPRESENTABLE + -- @extends Cargo.Cargo#CARGO_REPRESENTABLE --- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE} -- @@ -42,11 +42,11 @@ do -- CARGO_CRATE -- @param Wrapper.Static#STATIC CargoStatic -- @param #string Type -- @param #string Name - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_CRATE - function CARGO_CRATE:New( CargoStatic, Type, Name, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, ReportRadius, NearRadius ) ) -- #CARGO_CRATE + function CARGO_CRATE:New( CargoStatic, Type, Name, LoadRadius, NearRadius ) + local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_CRATE self:F( { Type, Name, NearRadius } ) self.CargoObject = CargoStatic @@ -134,6 +134,27 @@ do -- CARGO_CRATE return false end + --- Check if Cargo Crate is in the radius for the Cargo to be Boarded or Loaded. + -- @param #CARGO self + -- @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 } ) + + local Distance = 0 + if self:IsUnLoaded() then + Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + self:T( Distance ) + if Distance <= self.NearRadius then + return true + end + end + + return false + end + + + --- Get the current Coordinate of the CargoGroup. -- @param #CARGO_CRATE self -- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup. @@ -188,28 +209,6 @@ do -- CARGO_CRATE end - --- Check if CargoGroup is in the ReportRadius for the Cargo to be Loaded. - -- @param #CARGO_CRATE self - -- @param Core.Point#Coordinate Coordinate - -- @return #boolean true if the CargoGroup is within the reporting radius. - function CARGO_CRATE:IsInRadius( Coordinate ) - self:F( { Coordinate } ) - - local Distance = 0 - if self:IsLoaded() then - Distance = Coordinate:DistanceFromPointVec2( self.CargoCarrier:GetPointVec2() ) - else - Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) - end - self:T( Distance ) - - if Distance <= self.ReportRadius then - return true - else - return false - end - end - --- Respawn the CargoGroup. -- @param #CARGO_CRATE self function CARGO_CRATE:Respawn() diff --git a/Moose Development/Moose/Cargo/CargoGroup.lua b/Moose Development/Moose/Cargo/CargoGroup.lua index 2a5f8fee5..07806b45c 100644 --- a/Moose Development/Moose/Cargo/CargoGroup.lua +++ b/Moose Development/Moose/Cargo/CargoGroup.lua @@ -23,7 +23,7 @@ do -- CARGO_GROUP --- @type CARGO_GROUP - -- @extends #CARGO_REPORTABLE + -- @extends Cargo.Cargo#CARGO_REPORTABLE -- @field Core.Set#SET_CARGO CargoSet The collection of derived CARGO objects. -- @field #string GroupName The name of the CargoGroup. @@ -45,12 +45,12 @@ do -- CARGO_GROUP -- @param Wrapper.Group#GROUP CargoGroup -- @param #string Type -- @param #string Name --- @param #number ReportRadius (optional) +-- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_GROUP -function CARGO_GROUP:New( CargoGroup, Type, Name, ReportRadius ) - local self = BASE:Inherit( self, CARGO_REPORTABLE:New( Type, Name, 0, ReportRadius ) ) -- #CARGO_GROUP - self:F( { Type, Name, ReportRadius } ) +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() @@ -455,11 +455,11 @@ function CARGO_GROUP:OnEventCargoDead( EventData ) return nil end - --- Check if CargoGroup is in the ReportRadius for the Cargo to be Loaded. + --- Check if Cargo Group is in the radius for the Cargo to be Boarded. -- @param #CARGO_GROUP self -- @param Core.Point#Coordinate Coordinate - -- @return #boolean true if the CargoGroup is within the reporting radius. - function CARGO_GROUP:IsInRadius( Coordinate ) + -- @return #boolean true if the Cargo Group is within the load radius. + function CARGO_GROUP:IsInLoadRadius( Coordinate ) self:F( { Coordinate } ) local Cargo = self.CargoSet:GetFirst() -- #CARGO @@ -473,7 +473,7 @@ function CARGO_GROUP:OnEventCargoDead( EventData ) end self:T( Distance ) - if Distance <= self.ReportRadius then + if Distance <= self.LoadRadius then return true else return false @@ -484,6 +484,31 @@ function CARGO_GROUP:OnEventCargoDead( EventData ) end + + --- Check if Cargo Group is in the report radius. + -- @param #CARGO_GROUP self + -- @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 } ) + + local Cargo = self.CargoSet:GetFirst() -- #CARGO + + if Cargo then + local Distance = 0 + if Cargo:IsUnLoaded() then + Distance = Coordinate:DistanceFromPointVec2( Cargo.CargoObject:GetPointVec2() ) + self:T( Distance ) + if Distance <= self.LoadRadius then + return true + end + end + end + + return nil + + end + --- Respawn the CargoGroup. -- @param #CARGO_GROUP self function CARGO_GROUP:Respawn() diff --git a/Moose Development/Moose/Cargo/CargoSlingload.lua b/Moose Development/Moose/Cargo/CargoSlingload.lua index a610e4b34..91f69f873 100644 --- a/Moose Development/Moose/Cargo/CargoSlingload.lua +++ b/Moose Development/Moose/Cargo/CargoSlingload.lua @@ -24,7 +24,7 @@ do -- CARGO_SLINGLOAD --- Models the behaviour of cargo crates, which can only be slingloaded. -- @type CARGO_SLINGLOAD - -- @extends #CARGO_REPRESENTABLE + -- @extends Cargo.Cargo#CARGO_REPRESENTABLE --- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE} -- @@ -42,11 +42,11 @@ do -- CARGO_SLINGLOAD -- @param Wrapper.Static#STATIC CargoStatic -- @param #string Type -- @param #string Name - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_SLINGLOAD - function CARGO_SLINGLOAD:New( CargoStatic, Type, Name, ReportRadius, NearRadius ) - local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, ReportRadius, NearRadius ) ) -- #CARGO_SLINGLOAD + function CARGO_SLINGLOAD:New( CargoStatic, Type, Name, LoadRadius, NearRadius ) + local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoStatic, Type, Name, nil, LoadRadius, NearRadius ) ) -- #CARGO_SLINGLOAD self:F( { Type, Name, NearRadius } ) self.CargoObject = CargoStatic @@ -90,6 +90,28 @@ do -- CARGO_SLINGLOAD return false end + + --- Check if Cargo Slingload is in the radius for the Cargo to be Boarded or Loaded. + -- @param #CARGO_SLINGLOAD self + -- @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 } ) + + local Distance = 0 + if self:IsUnLoaded() then + Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) + self:T( Distance ) + if Distance <= self.NearRadius then + return true + end + end + + return false + end + + + --- Get the current Coordinate of the CargoGroup. -- @param #CARGO_SLINGLOAD self -- @return Core.Point#COORDINATE The current Coordinate of the first Cargo of the CargoGroup. @@ -144,28 +166,6 @@ do -- CARGO_SLINGLOAD end - --- Check if CargoGroup is in the ReportRadius for the Cargo to be Loaded. - -- @param #CARGO_SLINGLOAD self - -- @param Core.Point#Coordinate Coordinate - -- @return #boolean true if the CargoGroup is within the reporting radius. - function CARGO_SLINGLOAD:IsInRadius( Coordinate ) - self:F( { Coordinate } ) - - local Distance = 0 - if self:IsLoaded() then - Distance = Coordinate:DistanceFromPointVec2( self.CargoCarrier:GetPointVec2() ) - else - Distance = Coordinate:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) - end - self:T( Distance ) - - if Distance <= self.ReportRadius then - return true - else - return false - end - end - --- Respawn the CargoGroup. -- @param #CARGO_SLINGLOAD self function CARGO_SLINGLOAD:Respawn() diff --git a/Moose Development/Moose/Cargo/CargoUnit.lua b/Moose Development/Moose/Cargo/CargoUnit.lua index ba9c17f61..5f6b4e941 100644 --- a/Moose Development/Moose/Cargo/CargoUnit.lua +++ b/Moose Development/Moose/Cargo/CargoUnit.lua @@ -44,7 +44,7 @@ do -- CARGO_UNIT -- @param #string Type -- @param #string Name -- @param #number Weight - -- @param #number ReportRadius (optional) + -- @param #number LoadRadius (optional) -- @param #number NearRadius (optional) -- @return #CARGO_UNIT function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius ) diff --git a/Moose Development/Moose/Tasking/Task_CARGO.lua b/Moose Development/Moose/Tasking/Task_CARGO.lua index efb21f018..101399783 100644 --- a/Moose Development/Moose/Tasking/Task_CARGO.lua +++ b/Moose Development/Moose/Tasking/Task_CARGO.lua @@ -230,7 +230,7 @@ do -- TASK_CARGO Task.SetCargo:ForEachCargo( - --- @param Core.Cargo#CARGO Cargo + --- @param Cargo.Cargo#CARGO Cargo function( Cargo ) if Cargo:IsAlive() then @@ -250,7 +250,7 @@ do -- TASK_CARGO if Cargo:IsUnLoaded() then if CargoItemCount <= Task.CargoLimit then - if Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then + if Cargo:IsInReportRadius( TaskUnit:GetPointVec2() ) then local NotInDeployZones = true for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do if Cargo:IsInZone( DeployZone ) then @@ -260,20 +260,50 @@ do -- TASK_CARGO if NotInDeployZones then if not TaskUnit:InAir() then if Cargo:CanBoard() == true then - MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Board cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuBoardCargo, self, Cargo ):SetTime(MenuTime) + if Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then + Cargo:Report( "Reporting 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) + else + Cargo:Report( "Reporting at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "reporting", TaskUnit:GetGroup() ) + end else if Cargo:CanLoad() == true then - MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Load cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuLoadCargo, self, Cargo ):SetTime(MenuTime) + if Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then + Cargo:Report( "Reporting 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) + else + Cargo:Report( "Reporting at " .. Cargo:GetCoordinate():ToString( TaskUnit:GetGroup() ), "reporting", TaskUnit:GetGroup() ) + end end end TaskUnit.Menu:SetTime( MenuTime ) + else + Cargo:ReportResetAll( TaskUnit:GetGroup() ) end end else MENU_GROUP_COMMAND:New( TaskUnit:GetGroup(), "Route to Pickup cargo " .. Cargo.Name, TaskUnit.Menu, self.MenuRouteToPickup, self, Cargo ):SetTime(MenuTime) TaskUnit.Menu:SetTime( MenuTime ) + Cargo:ReportResetAll( TaskUnit:GetGroup() ) end end + -- Cargo in deployzones are flagged as deployed. + for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do + if Cargo:IsInZone( DeployZone ) then + if not Cargo:IsDeployed() then + Cargo:SetDeployed( true ) + -- TODO:I need to find a more decent solution for this. + Task:E( { CargoDeployed = Task.CargoDeployed and "true" or "false" } ) + Task:E( { CargoIsAlive = Cargo:IsAlive() and "true" or "false" } ) + if Cargo:IsAlive() then + if Task.CargoDeployed then + Task:CargoDeployed( TaskUnit, Cargo, DeployZone ) + end + end + end + end + end + end if Cargo:IsLoaded() then @@ -303,7 +333,7 @@ do -- TASK_CARGO TaskUnit.Menu:Remove( MenuTime ) - self:__SelectAction( -15 ) + self:__SelectAction( -5 ) end @@ -441,7 +471,7 @@ do -- TASK_CARGO self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } ) if self.Cargo:IsAlive() then - if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then + if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then if TaskUnit:InAir() then self:__Land( -10, Action ) else @@ -465,7 +495,7 @@ do -- TASK_CARGO self:F( { TaskUnit = TaskUnit, Task = Task and Task:GetClassNameAndID() } ) if self.Cargo:IsAlive() then - if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then + if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then if TaskUnit:InAir() then self:__Land( -0.1, Action ) else @@ -506,7 +536,7 @@ do -- TASK_CARGO end if self.Cargo:IsAlive() then - if self.Cargo:IsInRadius( TaskUnit:GetPointVec2() ) then + if self.Cargo:IsInLoadRadius( TaskUnit:GetPointVec2() ) then if TaskUnit:InAir() then --- ABORT the boarding. Split group if any and go back to select action. else @@ -649,26 +679,6 @@ do -- TASK_CARGO end end TaskUnit:RemoveCargo( Cargo ) - - local NotInDeployZones = true - for DeployZoneName, DeployZone in pairs( Task.DeployZones ) do - if Cargo:IsInZone( DeployZone ) then - NotInDeployZones = false - end - end - - if NotInDeployZones == false then - Cargo:SetDeployed( true ) - end - - -- TODO:I need to find a more decent solution for this. - Task:E( { CargoDeployed = Task.CargoDeployed and "true" or "false" } ) - Task:E( { CargoIsAlive = Cargo:IsAlive() and "true" or "false" } ) - if Cargo:IsAlive() then - if Task.CargoDeployed then - Task:CargoDeployed( TaskUnit, Cargo, self.DeployZone ) - end - end self:Planned() self:__SelectAction( 1 ) @@ -739,7 +749,7 @@ do -- TASK_CARGO local ActRouteCargo = ProcessUnit:GetProcess( "RoutingToPickup", "RouteToPickupPoint" ) -- Actions.Act_Route#ACT_ROUTE_POINT ActRouteCargo:Reset() ActRouteCargo:SetCoordinate( Cargo:GetCoordinate() ) - ActRouteCargo:SetRange( Cargo:GetBoardingRange() ) + ActRouteCargo:SetRange( Cargo:GetLoadRadius() ) ActRouteCargo:SetMenuCancel( TaskUnit:GetGroup(), "Cancel Routing to Cargo " .. Cargo:GetName(), TaskUnit.Menu ) ActRouteCargo:Start() return self From a247f56c7e8fed690884e284dfb48671bd1dec01 Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Sat, 7 Apr 2018 10:18:52 +0200 Subject: [PATCH 2/4] Progress on AI_CARGO_TROOPS --- .../Moose/AI/AI_Cargo_Troops.lua | 170 ++++++++++++++---- Moose Development/Moose/Cargo/Cargo.lua | 14 +- Moose Development/Moose/Cargo/CargoUnit.lua | 72 ++++---- Moose Development/Moose/Core/Zone.lua | 8 + Moose Development/Moose/Wrapper/Group.lua | 9 +- .../Moose/Wrapper/Identifiable.lua | 20 +++ Moose Development/Moose/Wrapper/Object.lua | 2 + 7 files changed, 215 insertions(+), 80 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo_Troops.lua b/Moose Development/Moose/AI/AI_Cargo_Troops.lua index 754409aeb..2051fa22d 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Troops.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Troops.lua @@ -24,19 +24,16 @@ AI_CARGO_TROOPS = { --- Creates a new AI_CARGO_TROOPS object. -- @param #AI_CARGO_TROOPS 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 ) local self = BASE:Inherit( self, FSM_CONTROLLABLE:New( ) ) -- #AI_CARGO_TROOPS - self.CargoCarrier = CargoCarrier -- Wrapper.Unit#UNIT - self.CargoGroup = CargoGroup -- Core.Cargo#CARGO_GROUP + self.CargoGroup = CargoGroup -- Cargo.CargoGroup#CARGO_GROUP self.CombatRadius = CombatRadius - - self.Zone = ZONE_UNIT:New( self.CargoCarrier:GetName() .. "-Zone", self.CargoCarrier, CombatRadius ) - self.Coalition = self.CargoCarrier:GetCoalition() - - self:SetControllable( CargoCarrier ) self:SetStartState( "UnLoaded" ) @@ -50,14 +47,91 @@ function AI_CARGO_TROOPS:New( CargoCarrier, CargoGroup, CombatRadius ) self:AddTransition( "*", "Monitor", "*" ) self:AddTransition( "*", "Follow", "Following" ) self:AddTransition( "*", "Guard", "Guarding" ) + + self:AddTransition( "*", "Destroyed", "Destroyed" ) self:__Monitor( 1 ) - self:__Load( 1 ) + + self:SetCarrier( CargoCarrier ) return self end +--- Set the Carrier. +-- @param #AI_CARGO_TROOPS self +-- @param Wrapper.Unit#UNIT CargoCarrier +-- @return #AI_CARGO_TROOPS +function AI_CARGO_TROOPS:SetCarrier( CargoCarrier ) + + self.CargoCarrier = CargoCarrier -- Wrapper.Unit#UNIT + self.CargoCarrier:SetState( self.CargoCarrier, "AI_CARGO_TROOPS", self ) + + CargoCarrier:HandleEvent( EVENTS.Dead ) + CargoCarrier:HandleEvent( EVENTS.Hit ) + + function CargoCarrier:OnEventDead( EventData ) + self:F({"dead"}) + local AICargoTroops = self:GetState( self, "AI_CARGO_TROOPS" ) + self:F({AICargoTroops=AICargoTroops}) + if AICargoTroops then + self:F({}) + if not AICargoTroops:Is( "Loaded" ) then + -- There are enemies within combat range. Unload the CargoCarrier. + AICargoTroops:Destroyed() + end + end + end + + function CargoCarrier:OnEventHit( EventData ) + self:F({"hit"}) + local AICargoTroops = self:GetState( self, "AI_CARGO_TROOPS" ) + 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 CargoCarrier. + AICargoTroops:Unload() + end + end + end + + self.Zone = ZONE_UNIT:New( self.CargoCarrier:GetName() .. "-Zone", self.CargoCarrier, self.CombatRadius ) + self.Coalition = self.CargoCarrier:GetCoalition() + + self:SetControllable( CargoCarrier ) + + self:Guard() + + return self +end + + +--- Find a free Carrier within a range. +-- @param #AI_CARGO_TROOPS self +-- @param Core.Point#COORDINATE Coordinate +-- @param #number Radius +-- @return Wrapper.Unit#UNIT NewCarrier +function AI_CARGO_TROOPS: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 + local Attributes = NearUnit:GetDesc() + self:F({Desc=Attributes}) + if NearUnit:HasAttribute( "Trucks" ) then + self:SetCarrier( NearUnit ) + break + end + end + end + +end + + + --- Follow Infantry to the Carrier. -- @param #AI_CARGO_TROOPS self -- @param #AI_CARGO_TROOPS Me @@ -68,40 +142,44 @@ function AI_CARGO_TROOPS:FollowToCarrier( Me, CargoCarrier, InfantryGroup ) self:F( { self = self:GetClassNameAndID(), InfantryGroup = InfantryGroup:GetName() } ) - -- We check if the Cargo is near to the CargoCarrier. - if InfantryGroup:IsPartlyInZone( ZONE_UNIT:New( "Radius", CargoCarrier, 5 ) ) then + --if self:Is( "Following" ) then - -- The Cargo does not need to follow the Carrier. - Me:Guard() + if CargoCarrier:IsAlive() then + -- We check if the Cargo is near to the CargoCarrier. + if InfantryGroup:IsPartlyInZone( ZONE_UNIT:New( "Radius", CargoCarrier, 5 ) ) then - else + -- The Cargo does not need to follow the Carrier. + Me:Guard() - self:F( { InfantryGroup = InfantryGroup:GetName() } ) - - if InfantryGroup:IsAlive() then - + else + self:F( { InfantryGroup = InfantryGroup:GetName() } ) - - local Waypoints = {} - - -- Calculate the new Route. - local FromCoord = InfantryGroup:GetCoordinate() - local FromGround = FromCoord:WaypointGround( 10, "Diamond" ) - self:F({FromGround=FromGround}) - table.insert( Waypoints, FromGround ) - - local ToCoord = CargoCarrier:GetCoordinate() - local ToGround = ToCoord:WaypointGround( 10, "Diamond" ) - self:F({ToGround=ToGround}) - table.insert( Waypoints, ToGround ) - - local TaskRoute = InfantryGroup:TaskFunction( "AI_CARGO_TROOPS.FollowToCarrier", Me, CargoCarrier, InfantryGroup ) - - self:F({Waypoints = Waypoints}) - local Waypoint = Waypoints[#Waypoints] - InfantryGroup:SetTaskWaypoint( Waypoint, TaskRoute ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. - InfantryGroup:Route( Waypoints, 1 ) -- Move after a random seconds to the Route. See the Route method for details. + if InfantryGroup:IsAlive() then + + self:F( { InfantryGroup = InfantryGroup:GetName() } ) + + local Waypoints = {} + + -- Calculate the new Route. + local FromCoord = InfantryGroup:GetCoordinate() + local FromGround = FromCoord:WaypointGround( 10, "Diamond" ) + self:F({FromGround=FromGround}) + table.insert( Waypoints, FromGround ) + + local ToCoord = CargoCarrier:GetCoordinate():GetRandomCoordinateInRadius( 10, 5 ) + local ToGround = ToCoord:WaypointGround( 10, "Diamond" ) + self:F({ToGround=ToGround}) + table.insert( Waypoints, ToGround ) + + local TaskRoute = InfantryGroup:TaskFunction( "AI_CARGO_TROOPS.FollowToCarrier", Me, CargoCarrier, InfantryGroup ) + + self:F({Waypoints = Waypoints}) + local Waypoint = Waypoints[#Waypoints] + InfantryGroup:SetTaskWaypoint( Waypoint, TaskRoute ) -- Set for the given Route at Waypoint 2 the TaskRouteToZone. + + InfantryGroup:Route( Waypoints, 1 ) -- Move after a random seconds to the Route. See the Route method for details. + end end end end @@ -132,6 +210,22 @@ function AI_CARGO_TROOPS:onafterMonitor( CargoCarrier, From, Event, To ) self:Follow() end end + if self:Is( "Following" ) then + local Distance = Coordinate:Get2DDistance( self.CargoGroup:GetCoordinate() ) + self:F( { Distance = Distance } ) + if Distance > 40 then + CargoCarrier:RouteStop() + self.CarrierStopped = true + else + if self.CarrierStopped then + if self.CargoGroup:IsNear( CargoCarrier, 10 ) then + CargoCarrier:RouteResume() + self.CarrierStopped = nil + end + end + end + end + end self.CarrierCoordinate = CargoCarrier:GetCoordinate() end @@ -149,7 +243,7 @@ function AI_CARGO_TROOPS:onafterLoad( CargoCarrier, From, Event, To ) if CargoCarrier and CargoCarrier:IsAlive() then CargoCarrier:RouteStop() self:__Board( 10 ) - self.CargoGroup:Board( CargoCarrier, 100 ) + self.CargoGroup:Board( CargoCarrier, 10 ) end end diff --git a/Moose Development/Moose/Cargo/Cargo.lua b/Moose Development/Moose/Cargo/Cargo.lua index cdba0ec8f..eb44217a3 100644 --- a/Moose Development/Moose/Cargo/Cargo.lua +++ b/Moose Development/Moose/Cargo/Cargo.lua @@ -325,7 +325,7 @@ do -- CARGO -- @param #CARGO self function CARGO:Destroy() if self.CargoObject then - self.CargoObject:Destroy() + self.CargoObject:Destroy( false ) end self:Destroyed() end @@ -576,21 +576,23 @@ 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:F( { PointVec2 = PointVec2, NearRadius = NearRadius } ) + self:F2( { PointVec2 = PointVec2, NearRadius = NearRadius } ) if self.CargoObject:IsAlive() then --local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) - self:F( { CargoObjectName = self.CargoObject:GetName() } ) - self:F( { CargoObjectVec2 = self.CargoObject:GetVec2() } ) - self:F( { PointVec2 = PointVec2:GetVec2() } ) + --self:F( { CargoObjectName = self.CargoObject:GetName() } ) + --self:F( { CargoObjectVec2 = self.CargoObject:GetVec2() } ) + --self:F( { PointVec2 = PointVec2:GetVec2() } ) local Distance = PointVec2:Get2DDistance( self.CargoObject:GetPointVec2() ) - self:T( Distance ) + --self:F( Distance ) if Distance <= NearRadius then + self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = true } ) return true end end + self:F( { PointVec2 = PointVec2, NearRadius = NearRadius, IsNear = false } ) return false end diff --git a/Moose Development/Moose/Cargo/CargoUnit.lua b/Moose Development/Moose/Cargo/CargoUnit.lua index 5f6b4e941..2ba33aa4b 100644 --- a/Moose Development/Moose/Cargo/CargoUnit.lua +++ b/Moose Development/Moose/Cargo/CargoUnit.lua @@ -23,7 +23,7 @@ do -- CARGO_UNIT --- Models CARGO in the form of units, which can be boarded, unboarded, loaded, unloaded. -- @type CARGO_UNIT - -- @extends #CARGO_REPRESENTABLE + -- @extends Cargo.Cargo#CARGO_REPRESENTABLE --- # CARGO\_UNIT class, extends @{#CARGO_REPRESENTABLE} -- @@ -82,42 +82,48 @@ do -- CARGO_UNIT if not self:IsDestroyed() then local CargoCarrier = self.CargoCarrier -- Wrapper.Controllable#CONTROLLABLE - - local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2() - local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees. - local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle ) - - - local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading ) - - -- if there is no ToPointVec2 given, then use the CargoRoutePointVec2 - local FromDirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3( ToPointVec2 or CargoRoutePointVec2 ) - local FromAngle = CargoCarrierPointVec2:GetAngleDegrees(FromDirectionVec3) - local FromPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, FromAngle ) - --local CargoDeployPointVec2 = CargoCarrierPointVec2:GetRandomCoordinateInRadius( 10, 5 ) - - ToPointVec2 = ToPointVec2 or CargoCarrierPointVec2:GetRandomCoordinateInRadius( NearRadius, DeployDistance ) - - -- Respawn the group... - if self.CargoObject then - self.CargoObject:ReSpawn( FromPointVec2:GetVec3(), CargoDeployHeading ) - self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } ) - self.CargoCarrier = nil + if CargoCarrier:IsAlive() then - local Points = {} - - -- From - Points[#Points+1] = FromPointVec2:WaypointGround( Speed, "Vee" ) - - -- To - Points[#Points+1] = ToPointVec2:WaypointGround( Speed, "Vee" ) + local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2() + local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees. + local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle ) - local TaskRoute = self.CargoObject:TaskRoute( Points ) - self.CargoObject:SetTask( TaskRoute, 1 ) - + + local CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading ) - self:__UnBoarding( 1, ToPointVec2, NearRadius ) + + -- if there is no ToPointVec2 given, then use the CargoRoutePointVec2 + local FromDirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3( ToPointVec2 or CargoRoutePointVec2 ) + local FromAngle = CargoCarrierPointVec2:GetAngleDegrees(FromDirectionVec3) + local FromPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, FromAngle ) + --local CargoDeployPointVec2 = CargoCarrierPointVec2:GetRandomCoordinateInRadius( 10, 5 ) + + ToPointVec2 = ToPointVec2 or CargoCarrierPointVec2:GetRandomCoordinateInRadius( NearRadius, DeployDistance ) + + -- Respawn the group... + if self.CargoObject then + self.CargoObject:ReSpawn( FromPointVec2:GetVec3(), CargoDeployHeading ) + self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } ) + self.CargoCarrier = nil + + local Points = {} + + -- From + Points[#Points+1] = FromPointVec2:WaypointGround( Speed, "Vee" ) + + -- To + Points[#Points+1] = ToPointVec2:WaypointGround( Speed, "Vee" ) + + local TaskRoute = self.CargoObject:TaskRoute( Points ) + self.CargoObject:SetTask( TaskRoute, 1 ) + + + self:__UnBoarding( 1, ToPointVec2, NearRadius ) + end + else + -- the Carrier is dead. This cargo is dead too! + self:Destroyed() end end end diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index 72317d2ba..8c05d8a14 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -603,6 +603,7 @@ function ZONE_RADIUS:Scan( ObjectCategories ) self.ScanData = {} self.ScanData.Coalitions = {} self.ScanData.Scenery = {} + self.ScanData.Units = {} local ZoneCoord = self:GetCoordinate() local ZoneRadius = self:GetRadius() @@ -625,6 +626,7 @@ function ZONE_RADIUS:Scan( ObjectCategories ) (ObjectCategory == Object.Category.STATIC and ZoneObject:isExist()) then local CoalitionDCSUnit = ZoneObject:getCoalition() self.ScanData.Coalitions[CoalitionDCSUnit] = true + self.ScanData.Units[ZoneObject] = ZoneObject self:F( { Name = ZoneObject:getName(), Coalition = CoalitionDCSUnit } ) end if ObjectCategory == Object.Category.SCENERY then @@ -643,6 +645,12 @@ function ZONE_RADIUS:Scan( ObjectCategories ) end +function ZONE_RADIUS:GetScannedUnits() + + return self.ScanData.Units +end + + function ZONE_RADIUS:CountScannedCoalitions() local Count = 0 diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 26062ea09..23fd5da1a 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -239,14 +239,17 @@ end -- Note that this destroy method also raises a destroy event at run-time. -- So all event listeners will catch the destroy event of this DCS Group. -- @param #GROUP self -function GROUP:Destroy() +-- @param #boolean GenerateEvent +function GROUP:Destroy( GenerateEvent ) self:F2( self.GroupName ) local DCSGroup = self:GetDCSObject() if DCSGroup then - for Index, UnitData in pairs( DCSGroup:getUnits() ) do - self:CreateEventCrash( timer.getTime(), UnitData ) + if not GenerateEvent then + for Index, UnitData in pairs( DCSGroup:getUnits() ) do + self:CreateEventCrash( timer.getTime(), UnitData ) + end end USERFLAG:New( self:GetName() ):Set( 100 ) DCSGroup:destroy() diff --git a/Moose Development/Moose/Wrapper/Identifiable.lua b/Moose Development/Moose/Wrapper/Identifiable.lua index baa83eedb..edd123665 100644 --- a/Moose Development/Moose/Wrapper/Identifiable.lua +++ b/Moose Development/Moose/Wrapper/Identifiable.lua @@ -229,6 +229,26 @@ function IDENTIFIABLE:GetDesc() return nil end +--- Check if the Object has the attribute. +-- @param #IDENTIFIABLE self +-- @param #string AttributeName The attribute name. +-- @return #boolean true if the attribute exists. +-- @return #nil The DCS Identifiable is not existing or alive. +function IDENTIFIABLE:HasAttribute( AttributeName ) + self:F2( self.IdentifiableName ) + + local DCSIdentifiable = self:GetDCSObject() + + if DCSIdentifiable then + local IdentifiableHasAttribute = DCSIdentifiable:hasAttribute( AttributeName ) + self:T2( IdentifiableHasAttribute ) + return IdentifiableHasAttribute + end + + self:F( self.ClassName .. " " .. self.IdentifiableName .. " not found!" ) + return nil +end + --- Gets the CallSign of the IDENTIFIABLE, which is a blank by default. -- @param #IDENTIFIABLE self -- @return #string The CallSign of the IDENTIFIABLE. diff --git a/Moose Development/Moose/Wrapper/Object.lua b/Moose Development/Moose/Wrapper/Object.lua index fc3c11126..29901fd4b 100644 --- a/Moose Development/Moose/Wrapper/Object.lua +++ b/Moose Development/Moose/Wrapper/Object.lua @@ -91,3 +91,5 @@ end + + From 7735120f25b18a54326c85a12d2928de81c8f014 Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Sat, 7 Apr 2018 14:21:34 +0200 Subject: [PATCH 3/4] Progress on AI_CARGO_TROOPS --- Moose Development/Moose/Cargo/CargoUnit.lua | 53 +++++++++++-------- Moose Development/Moose/Core/Set.lua | 13 +++++ .../Moose/Wrapper/Controllable.lua | 4 +- 3 files changed, 46 insertions(+), 24 deletions(-) diff --git a/Moose Development/Moose/Cargo/CargoUnit.lua b/Moose Development/Moose/Cargo/CargoUnit.lua index 2ba33aa4b..5ac185277 100644 --- a/Moose Development/Moose/Cargo/CargoUnit.lua +++ b/Moose Development/Moose/Cargo/CargoUnit.lua @@ -231,7 +231,11 @@ do -- CARGO_UNIT local NearRadius = NearRadius or 25 self.CargoInAir = self.CargoObject:InAir() - + + local Desc = self.CargoObject:GetDesc() + local MaxSpeed = Desc.speedMaxOffRoad + local TypeName = Desc.typeName + self:T( self.CargoInAir ) -- Only move the group to the carrier when the cargo is not in the air @@ -240,28 +244,33 @@ do -- CARGO_UNIT if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then self:Load( CargoCarrier, NearRadius, ... ) else - local Speed = 90 - local Angle = 180 - local Distance = 5 + if MaxSpeed and MaxSpeed == 0 or TypeName and TypeName == "Stinger comm" then + self:Load( CargoCarrier, NearRadius, ... ) + else + + local Speed = 90 + local Angle = 180 + local Distance = 5 + + NearRadius = NearRadius or 25 - NearRadius = NearRadius or 25 - - local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2() - local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees. - local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle ) - local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading ) - - local Points = {} - - local PointStartVec2 = self.CargoObject:GetPointVec2() - - Points[#Points+1] = PointStartVec2:WaypointGround( Speed ) - Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed ) - - local TaskRoute = self.CargoObject:TaskRoute( Points ) - self.CargoObject:SetTask( TaskRoute, 2 ) - self:__Boarding( -1, CargoCarrier, NearRadius ) - self.RunCount = 0 + local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2() + local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees. + local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle ) + local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( Distance, CargoDeployHeading ) + + local Points = {} + + local PointStartVec2 = self.CargoObject:GetPointVec2() + + Points[#Points+1] = PointStartVec2:WaypointGround( Speed ) + Points[#Points+1] = CargoDeployPointVec2:WaypointGround( Speed ) + + local TaskRoute = self.CargoObject:TaskRoute( Points ) + self.CargoObject:SetTask( TaskRoute, 2 ) + self:__Boarding( -1, CargoCarrier, NearRadius ) + self.RunCount = 0 + end end end diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index 939973fd1..58c24bcce 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -4131,6 +4131,19 @@ function SET_CARGO:New() --R2.1 return self end + +--- (R2.1) Add CARGO to SET_CARGO. +-- @param Core.Set#SET_CARGO self +-- @param Cargo.Cargo#CARGO Cargo A single cargo. +-- @return self +function SET_CARGO:AddCargo( Cargo ) --R2.4 + + self:Add( Cargo:GetName(), Cargo ) + + return self +end + + --- (R2.1) Add CARGOs to SET_CARGO. -- @param Core.Set#SET_CARGO self -- @param #string AddCargoNames A single name or an array of CARGO names. diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 1847a16cd..f5b414e60 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1892,7 +1892,7 @@ end -- @param #CONTROLLABLE self -- @return #CONTROLLABLE function CONTROLLABLE:RouteStop() - self:F2() + self:F("RouteStop") local CommandStop = self:CommandStopRoute( true ) self:SetCommand( CommandStop ) @@ -1903,7 +1903,7 @@ end -- @param #CONTROLLABLE self -- @return #CONTROLLABLE function CONTROLLABLE:RouteResume() - self:F2() + self:F("RouteResume") local CommandResume = self:CommandStopRoute( false ) self:SetCommand( CommandResume ) From b1ecdc727c98ca17f758a7d0d58b1df91a291a32 Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Sat, 7 Apr 2018 19:00:18 +0200 Subject: [PATCH 4/4] Faster menu and fix for Disembark loaded engineers in other helicopter. --- Moose Development/Moose/Cargo/Cargo.lua | 8 ++++++++ Moose Development/Moose/Tasking/Task_CARGO.lua | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/Moose Development/Moose/Cargo/Cargo.lua b/Moose Development/Moose/Cargo/Cargo.lua index eb44217a3..cacd5fa64 100644 --- a/Moose Development/Moose/Cargo/Cargo.lua +++ b/Moose Development/Moose/Cargo/Cargo.lua @@ -384,6 +384,14 @@ do -- CARGO return self:Is( "Loaded" ) end + --- Check if cargo is loaded. + -- @param #CARGO self + -- @param Wrapper.Unit#UNIT Carrier + -- @return #boolean true if loaded + function CARGO:IsLoadedInCarrier( Carrier ) + return self.CargoCarrier and self.CargoCarrier:GetName() == Carrier:GetName() + end + --- Check if cargo is unloaded. -- @param #CARGO self -- @return #boolean true if unloaded diff --git a/Moose Development/Moose/Tasking/Task_CARGO.lua b/Moose Development/Moose/Tasking/Task_CARGO.lua index 101399783..933413ebc 100644 --- a/Moose Development/Moose/Tasking/Task_CARGO.lua +++ b/Moose Development/Moose/Tasking/Task_CARGO.lua @@ -306,7 +306,7 @@ do -- TASK_CARGO end - if Cargo:IsLoaded() then + 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) @@ -333,7 +333,7 @@ do -- TASK_CARGO TaskUnit.Menu:Remove( MenuTime ) - self:__SelectAction( -5 ) + self:__SelectAction( -1 ) end