From 3757eb06d9411267330ac24cec6ab8904b4dea9e Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Sun, 15 Apr 2018 04:41:52 +0200 Subject: [PATCH 1/2] Fixes for AI_CARGO_AIRPLANE --- .../Moose/AI/AI_Cargo_Airplane.lua | 128 ++++++++++++++++-- Moose Development/Moose/Core/Base.lua | 16 +++ Moose Development/Moose/Wrapper/Group.lua | 33 +++-- 3 files changed, 154 insertions(+), 23 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua index 679900301..a55bf0d10 100644 --- a/Moose Development/Moose/AI/AI_Cargo_Airplane.lua +++ b/Moose Development/Moose/AI/AI_Cargo_Airplane.lua @@ -228,16 +228,10 @@ end -- @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:Route( Airplane, Airbase, Speed ) self.RoutePickup = true self.Airbase = Airbase - - Airplane:RouteRTB( Airbase, Speed) end end @@ -252,16 +246,10 @@ end -- @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:Route( Airplane, Airbase, Speed ) self.RouteDeploy = true self.Airbase = Airbase - - Airplane:RouteRTB( Airbase, Speed ) end end @@ -346,3 +334,115 @@ function AI_CARGO_AIRPLANE:onafterUnloaded( Airplane, From, Event, To ) end +--- @param #AI_CARGO_AIRPLANE self +-- @param Wrapper.Group#GROUP Airplane +-- @param Wrapper.Airbase#AIRBASE Airbase +-- @param #number Speed +function AI_CARGO_AIRPLANE:Route( Airplane, Airbase, Speed ) + + if Airplane and Airplane:IsAlive() then + + local PointVec3 = Airplane:GetPointVec3() + + local Takeoff = SPAWN.Takeoff.Hot + + local Template = Airplane:GetTemplate() + + if Template then + + local Points = {} + + if self.Airbase then + + local FromWaypoint = Template.route.points[1] + + -- These are only for ships. + FromWaypoint.linkUnit = nil + FromWaypoint.helipadId = nil + FromWaypoint.airdromeId = nil + + local AirbaseID = self.Airbase:GetID() + local AirbaseCategory = self.Airbase:GetDesc().category + + FromWaypoint.airdromeId = AirbaseID + + FromWaypoint.alt = 0 + + FromWaypoint.type = GROUPTEMPLATE.Takeoff[Takeoff][1] -- type + FromWaypoint.action = GROUPTEMPLATE.Takeoff[Takeoff][2] -- action + + + -- Translate the position of the Group Template to the Vec3. + for UnitID = 1, #Template.units do + self:T( 'Before Translation SpawnTemplate.units['..UnitID..'].x = ' .. Template.units[UnitID].x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. Template.units[UnitID].y ) + + -- These cause a lot of confusion. + local UnitTemplate = Template.units[UnitID] + + UnitTemplate.parking = 15 + UnitTemplate.parking_id = "1" + UnitTemplate.alt = 0 + + local SX = UnitTemplate.x + local SY = UnitTemplate.y + local BX = FromWaypoint.x + local BY = FromWaypoint.y + local TX = PointVec3.x + ( SX - BX ) + local TY = PointVec3.z + ( SY - BY ) + + UnitTemplate.x = TX + UnitTemplate.y = TY + + self:T( 'After Translation SpawnTemplate.units['..UnitID..'].x = ' .. UnitTemplate.x .. ', SpawnTemplate.units['..UnitID..'].y = ' .. UnitTemplate.y ) + end + + FromWaypoint.x = PointVec3.x + FromWaypoint.y = PointVec3.z + + Points[#Points+1] = FromWaypoint + else + + local GroupPoint = Airplane:GetVec2() + local GroupVelocity = Airplane:GetUnit(1):GetDesc().speedMax + + local FromWaypoint = {} + FromWaypoint.x = GroupPoint.x + FromWaypoint.y = GroupPoint.y + FromWaypoint.type = "Turning Point" + FromWaypoint.action = "Turning Point" + FromWaypoint.speed = GroupVelocity + + Points[#Points+1] = FromWaypoint + end + + local AirbasePointVec2 = Airbase:GetPointVec2() + local ToWaypoint = AirbasePointVec2:WaypointAir( + POINT_VEC3.RoutePointAltType.BARO, + "Land", + "Landing", + Speed or Airplane:GetUnit(1):GetDesc().speedMax + ) + + ToWaypoint["airdromeId"] = Airbase:GetID() + ToWaypoint["speed_locked"] = true, + + self:F( ToWaypoint ) + + Points[#Points+1] = ToWaypoint + + Template.x = PointVec3.x + Template.y = PointVec3.z + + self:T3( Points ) + Template.route.points = Points + + --self:Respawn( Template ) + + local GroupSpawned = Airplane:Respawn( Template ) + + return GroupSpawned + end + + end + +end diff --git a/Moose Development/Moose/Core/Base.lua b/Moose Development/Moose/Core/Base.lua index f642d79b1..555786ab4 100644 --- a/Moose Development/Moose/Core/Base.lua +++ b/Moose Development/Moose/Core/Base.lua @@ -645,6 +645,22 @@ function BASE:CreateEventCrash( EventTime, Initiator ) world.onEvent( Event ) end +--- Creation of a Dead Event. +-- @param #BASE self +-- @param Dcs.DCSTypes#Time EventTime The time stamp of the event. +-- @param Dcs.DCSWrapper.Object#Object Initiator The initiating object of the event. +function BASE:CreateEventDead( EventTime, Initiator ) + self:F( { EventTime, Initiator } ) + + local Event = { + id = world.event.S_EVENT_DEAD, + time = EventTime, + initiator = Initiator, + } + + world.onEvent( Event ) +end + --- Creation of a Takeoff Event. -- @param #BASE self -- @param Dcs.DCSTypes#Time EventTime The time stamp of the event. diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index af83d6553..c595a5dbb 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -236,19 +236,36 @@ function GROUP:IsAlive() end --- Destroys the DCS Group and all of its DCS Units. --- 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. +-- Note that this destroy method also can raise a destroy event at run-time. +-- So all event listeners will catch the destroy event of this group for each unit in the group. +-- To raise these events, provide the `GenerateEvent` parameter. -- @param #GROUP self --- @param #boolean GenerateEvent +-- @param #boolean GenerateEvent true if you want to generate a crash or dead event for each unit. +-- @usage +-- -- Air unit example: destroy the Helicopter and generate a S_EVENT_CRASH for each unit in the Helicopter group. +-- Helicopter = GROUP:FindByName( "Helicopter" ) +-- Helicopter:Destroy( true ) +-- @usage +-- -- Ground unit example: destroy the Tanks and generate a S_EVENT_DEAD for each unit in the Tanks group. +-- Tanks = GROUP:FindByName( "Tanks" ) +-- Tanks:Destroy( true ) +-- @usage +-- -- Ship unit example: destroy the Ship silently. +-- Ship = GROUP:FindByName( "Ship" ) +-- Ship:Destroy( true ) function GROUP:Destroy( GenerateEvent ) self:F2( self.GroupName ) local DCSGroup = self:GetDCSObject() if DCSGroup then - if not GenerateEvent then + if GenerateEvent and GenerateEvent == true then for Index, UnitData in pairs( DCSGroup:getUnits() ) do - self:CreateEventCrash( timer.getTime(), UnitData ) + if self:IsAir() then + self:CreateEventCrash( timer.getTime(), UnitData ) + else + self:CreateEventDead( timer.getTime(), UnitData ) + end end end USERFLAG:New( self:GetName() ):Set( 100 ) @@ -1394,7 +1411,7 @@ do -- Route methods -- @param #number Speed (optional) The Speed, if no Speed is given, the maximum Speed of the first unit is selected. -- @return #GROUP function GROUP:RouteRTB( RTBAirbase, Speed ) - self:F2( { RTBAirbase, Speed } ) + self:F( { RTBAirbase:GetName(), Speed } ) local DCSGroup = self:GetDCSObject() @@ -1435,9 +1452,7 @@ do -- Route methods Template.route.points = Points self:Respawn( Template ) - self:Route( Points ) - - self:Respawn(Template) + --self:Route( Points ) else self:ClearTasks() end From af050629aab4f401c186c4038fa429c33b84624a Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Tue, 17 Apr 2018 06:25:40 +0200 Subject: [PATCH 2/2] Made it. Now cargo can be defined in the Mission Editor as #CARGO --- Moose Development/Moose/Cargo/Cargo.lua | 2 +- Moose Development/Moose/Core/Database.lua | 107 +++++++++++++++++----- Moose Development/Moose/Moose.lua | 2 + 3 files changed, 87 insertions(+), 24 deletions(-) diff --git a/Moose Development/Moose/Cargo/Cargo.lua b/Moose Development/Moose/Cargo/Cargo.lua index 2cf5be78e..446d58da4 100644 --- a/Moose Development/Moose/Cargo/Cargo.lua +++ b/Moose Development/Moose/Cargo/Cargo.lua @@ -610,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:F( { PointVec2 = PointVec2, NearRadius = NearRadius } ) if self.CargoObject:IsAlive() then --local Distance = PointVec2:DistanceFromPointVec2( self.CargoObject:GetPointVec2() ) diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 6eb78eccc..262175514 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -242,35 +242,96 @@ function DATABASE:FindAirbase( AirbaseName ) return AirbaseFound end ---- Adds a Cargo based on the Cargo Name in the DATABASE. --- @param #DATABASE self --- @param #string CargoName The name of the airbase -function DATABASE:AddCargo( Cargo ) - if not self.CARGOS[Cargo.Name] then - self.CARGOS[Cargo.Name] = Cargo + +do -- cargo + + --- Adds a Cargo based on the Cargo Name in the DATABASE. + -- @param #DATABASE self + -- @param #string CargoName The name of the airbase + function DATABASE:AddCargo( Cargo ) + + if not self.CARGOS[Cargo.Name] then + self.CARGOS[Cargo.Name] = Cargo + end end -end + + + --- Deletes a Cargo from the DATABASE based on the Cargo Name. + -- @param #DATABASE self + -- @param #string CargoName The name of the airbase + function DATABASE:DeleteCargo( CargoName ) + + self.CARGOS[CargoName] = nil + end + + --- Finds an CARGO based on the CargoName. + -- @param #DATABASE self + -- @param #string CargoName + -- @return Wrapper.Cargo#CARGO The found CARGO. + function DATABASE:FindCargo( CargoName ) + + local CargoFound = self.CARGOS[CargoName] + return CargoFound + end + + --- Checks if the Template name has a ~CARGO tag. + -- If yes, the group is a cargo. + -- @param #DATABASE self + -- @param #string TemplateName + -- @return #boolean + function DATABASE:IsCargo( TemplateName ) + TemplateName = env.getValueDictByKey( TemplateName ) + + local Cargo = TemplateName:match( "#(CARGO)" ) ---- Deletes a Cargo from the DATABASE based on the Cargo Name. --- @param #DATABASE self --- @param #string CargoName The name of the airbase -function DATABASE:DeleteCargo( CargoName ) + return Cargo and Cargo == "CARGO" + end - self.CARGOS[CargoName] = nil -end - ---- Finds an CARGO based on the CargoName. --- @param #DATABASE self --- @param #string CargoName --- @return Wrapper.Cargo#CARGO The found CARGO. -function DATABASE:FindCargo( CargoName ) - - local CargoFound = self.CARGOS[CargoName] - return CargoFound -end + --- Private method that registers new Static Templates within the DATABASE Object. + -- @param #DATABASE self + -- @return #DATABASE self + function DATABASE:RegisterCargos() + + for CargoGroupName, CargoGroup in pairs( self.GROUPS ) do + if self:IsCargo( CargoGroupName ) then + local CargoInfo = CargoGroupName:match("~CARGO(.*)") + local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)") + local CargoName = CargoGroupName:match("(.*)~CARGO") + local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?") + local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") + local LoadRadius = CargoParam and CargoParam:match( "RR=([%a%d]+),?") + local NearRadius = CargoParam and CargoParam:match( "NR=([%a%d]+),?") + + CARGO_GROUP:New( CargoGroup, Type, Name or CargoName, LoadRadius, NearRadius ) + end + end + + for CargoStaticName, CargoStatic in pairs( self.STATICS ) do + if self:IsCargo( CargoStaticName ) then + local CargoInfo = CargoStaticName:match("~CARGO(.*)") + local CargoParam = CargoInfo and CargoInfo:match( "%((.*)%)") + local CargoName = CargoStaticName:match("(.*)~CARGO") + local Type = CargoParam and CargoParam:match( "T=([%a%d ]+),?") + local Category = CargoParam and CargoParam:match( "C=([%a%d ]+),?") + local Name = CargoParam and CargoParam:match( "N=([%a%d]+),?") + local LoadRadius = CargoParam and tonumber( CargoParam:match( "RR=([%a%d]+),?") ) + local NearRadius = CargoParam and tonumber( CargoParam:match( "NR=([%a%d]+),?") ) + + if Category == "SLING" then + CARGO_SLINGLOAD:New( CargoStatic, Type, Name or CargoName, LoadRadius, NearRadius ) + else + if Category == "CRATE" then + CARGO_CRATE:New( CargoStatic, Type, Name or CargoName, LoadRadius, NearRadius ) + end + end + end + end + + end +end -- cargo --- Finds a CLIENT based on the ClientName. -- @param #DATABASE self diff --git a/Moose Development/Moose/Moose.lua b/Moose Development/Moose/Moose.lua index 5e1e394cc..6a748922a 100644 --- a/Moose Development/Moose/Moose.lua +++ b/Moose Development/Moose/Moose.lua @@ -13,3 +13,5 @@ _DATABASE = DATABASE:New() -- Core.Database#DATABASE _SETTINGS = SETTINGS:Set() _SETTINGS:SetPlayerMenuOn() +_DATABASE:RegisterCargos() +