From 15ea0bc63a1fe8c660b5a8b0de63fb94162688cf Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Fri, 6 Oct 2017 19:56:31 +0200 Subject: [PATCH 1/3] ZONE GOAL CARGO stuff --- .../Moose/Functional/ZoneGoalCargo.lua | 452 ++++++++++++++++++ .../Moose/Tasking/TaskZoneCapture.lua | 3 + 2 files changed, 455 insertions(+) create mode 100644 Moose Development/Moose/Functional/ZoneGoalCargo.lua diff --git a/Moose Development/Moose/Functional/ZoneGoalCargo.lua b/Moose Development/Moose/Functional/ZoneGoalCargo.lua new file mode 100644 index 000000000..78707d461 --- /dev/null +++ b/Moose Development/Moose/Functional/ZoneGoalCargo.lua @@ -0,0 +1,452 @@ +--- **Functional (WIP)** -- Base class that models processes to achieve goals involving a Zone and Cargo. +-- +-- ==== +-- +-- ZONE_GOAL_CARGO models processes that have a Goal with a defined achievement involving a Zone and Cargo. +-- Derived classes implement the ways how the achievements can be realized. +-- +-- ==== +-- +-- ### Author: **Sven Van de Velde (FlightControl)** +-- +-- ==== +-- +-- @module ZoneGoalCargo + +do -- ZoneGoal + + --- @type ZONE_GOAL_CARGO + -- @extends Functional.ZoneGoal#ZONE_GOAL + + + --- # ZONE_GOAL_CARGO class, extends @{ZoneGoal#ZONE_GOAL} + -- + -- ZONE_GOAL_CARGO models processes that have a Goal with a defined achievement involving a Zone and Cargo. + -- Derived classes implement the ways how the achievements can be realized. + -- + -- ## 1. ZONE_GOAL_CARGO constructor + -- + -- * @{#ZONE_GOAL_CARGO.New}(): Creates a new ZONE_GOAL_CARGO object. + -- + -- ## 2. ZONE_GOAL_CARGO is a finite state machine (FSM). + -- + -- ### 2.1 ZONE_GOAL_CARGO States + -- + -- * **Deployed**: The Zone has been captured by an other coalition. + -- * **Airborne**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone. + -- * **Loaded**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone. + -- * **Empty**: The Zone is empty. There is not valid unit in the Zone. + -- + -- ### 2.2 ZONE_GOAL_CARGO Events + -- + -- * **Capture**: The Zone has been captured by an other coalition. + -- * **Attack**: The Zone is currently intruded by an other coalition. There are units of the owning coalition and an other coalition in the Zone. + -- * **Guard**: The Zone is guarded by the owning coalition. There is no other unit of an other coalition in the Zone. + -- * **Empty**: The Zone is empty. There is not valid unit in the Zone. + -- + -- ### 2.3 ZONE_GOAL_CARGO State Machine + -- + -- @field #ZONE_GOAL_CARGO + ZONE_GOAL_CARGO = { + ClassName = "ZONE_GOAL_CARGO", + } + + --- @field #table ZONE_GOAL_CARGO.States + ZONE_GOAL_CARGO.States = {} + + --- ZONE_GOAL_CARGO Constructor. + -- @param #ZONE_GOAL_CARGO self + -- @param Core.Zone#ZONE Zone A @{Zone} object with the goal to be achieved. + -- @param DCSCoalition.DCSCoalition#coalition Coalition The initial coalition owning the zone. + -- @return #ZONE_GOAL_CARGO + function ZONE_GOAL_CARGO:New( Zone, Coalition ) + + local self = BASE:Inherit( self, ZONE_GOAL:New( Zone ) ) -- #ZONE_GOAL_CARGO + self:F( { Zone = Zone, Coalition = Coalition } ) + + self:SetCoalition( Coalition ) + + do + + --- Captured State Handler OnLeave for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnLeaveCaptured + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @return #boolean + + --- Captured State Handler OnEnter for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnEnterCaptured + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + + end + + + do + + --- Attacked State Handler OnLeave for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnLeaveAttacked + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @return #boolean + + --- Attacked State Handler OnEnter for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnEnterAttacked + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + + end + + do + + --- Guarded State Handler OnLeave for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnLeaveGuarded + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @return #boolean + + --- Guarded State Handler OnEnter for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnEnterGuarded + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + + end + + + do + + --- Empty State Handler OnLeave for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnLeaveEmpty + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @return #boolean + + --- Empty State Handler OnEnter for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnEnterEmpty + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + + end + + self:AddTransition( "*", "Guard", "Guarded" ) + + --- Guard Handler OnBefore for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnBeforeGuard + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @return #boolean + + --- Guard Handler OnAfter for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnAfterGuard + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + + --- Guard Trigger for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] Guard + -- @param #ZONE_GOAL_CARGO self + + --- Guard Asynchronous Trigger for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] __Guard + -- @param #ZONE_GOAL_CARGO self + -- @param #number Delay + + self:AddTransition( "*", "Empty", "Empty" ) + + --- Empty Handler OnBefore for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnBeforeEmpty + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @return #boolean + + --- Empty Handler OnAfter for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnAfterEmpty + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + + --- Empty Trigger for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] Empty + -- @param #ZONE_GOAL_CARGO self + + --- Empty Asynchronous Trigger for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] __Empty + -- @param #ZONE_GOAL_CARGO self + -- @param #number Delay + + + self:AddTransition( { "Guarded", "Empty" }, "Attack", "Attacked" ) + + --- Attack Handler OnBefore for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnBeforeAttack + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @return #boolean + + --- Attack Handler OnAfter for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnAfterAttack + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + + --- Attack Trigger for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] Attack + -- @param #ZONE_GOAL_CARGO self + + --- Attack Asynchronous Trigger for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] __Attack + -- @param #ZONE_GOAL_CARGO self + -- @param #number Delay + + self:AddTransition( { "Guarded", "Attacked", "Empty" }, "Capture", "Captured" ) + + --- Capture Handler OnBefore for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnBeforeCapture + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + -- @return #boolean + + --- Capture Handler OnAfter for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] OnAfterCapture + -- @param #ZONE_GOAL_CARGO self + -- @param #string From + -- @param #string Event + -- @param #string To + + --- Capture Trigger for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] Capture + -- @param #ZONE_GOAL_CARGO self + + --- Capture Asynchronous Trigger for ZONE_GOAL_CARGO + -- @function [parent=#ZONE_GOAL_CARGO] __Capture + -- @param #ZONE_GOAL_CARGO self + -- @param #number Delay + + return self + end + + + --- Set the owning coalition of the zone. + -- @param #ZONE_GOAL_CARGO self + -- @param DCSCoalition.DCSCoalition#coalition Coalition + function ZONE_GOAL_CARGO:SetCoalition( Coalition ) + self.Coalition = Coalition + end + + + --- Get the owning coalition of the zone. + -- @param #ZONE_GOAL_CARGO self + -- @return DCSCoalition.DCSCoalition#coalition Coalition. + function ZONE_GOAL_CARGO:GetCoalition() + return self.Coalition + end + + + --- Get the owning coalition name of the zone. + -- @param #ZONE_GOAL_CARGO self + -- @return #string Coalition name. + function ZONE_GOAL_CARGO:GetCoalitionName() + + if self.Coalition == coalition.side.BLUE then + return "Blue" + end + + if self.Coalition == coalition.side.RED then + return "Red" + end + + if self.Coalition == coalition.side.NEUTRAL then + return "Neutral" + end + + return "" + end + + + function ZONE_GOAL_CARGO:IsGuarded() + + local IsGuarded = self.Zone:IsAllInZoneOfCoalition( self.Coalition ) + self:E( { IsGuarded = IsGuarded } ) + return IsGuarded + end + + + function ZONE_GOAL_CARGO:IsEmpty() + + local IsEmpty = self.Zone:IsNoneInZone() + self:E( { IsEmpty = IsEmpty } ) + return IsEmpty + end + + + function ZONE_GOAL_CARGO:IsCaptured() + + local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition ) + self:E( { IsCaptured = IsCaptured } ) + return IsCaptured + end + + + function ZONE_GOAL_CARGO:IsAttacked() + + local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition ) + self:E( { IsAttacked = IsAttacked } ) + return IsAttacked + end + + + + --- Mark. + -- @param #ZONE_GOAL_CARGO self + function ZONE_GOAL_CARGO:Mark() + + local Coord = self.Zone:GetCoordinate() + local ZoneName = self:GetZoneName() + local State = self:GetState() + + if self.MarkRed and self.MarkBlue then + self:E( { MarkRed = self.MarkRed, MarkBlue = self.MarkBlue } ) + Coord:RemoveMark( self.MarkRed ) + Coord:RemoveMark( self.MarkBlue ) + end + + if self.Coalition == coalition.side.BLUE then + self.MarkBlue = Coord:MarkToCoalitionBlue( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State ) + self.MarkRed = Coord:MarkToCoalitionRed( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State ) + else + self.MarkRed = Coord:MarkToCoalitionRed( "Guard Zone: " .. ZoneName .. "\nStatus: " .. State ) + self.MarkBlue = Coord:MarkToCoalitionBlue( "Capture Zone: " .. ZoneName .. "\nStatus: " .. State ) + end + end + + --- Bound. + -- @param #ZONE_GOAL_CARGO self + function ZONE_GOAL_CARGO:onenterGuarded() + + --self:GetParent( self ):onenterGuarded() + + if self.Coalition == coalition.side.BLUE then + --elf.ProtectZone:BoundZone( 12, country.id.USA ) + else + --self.ProtectZone:BoundZone( 12, country.id.RUSSIA ) + end + + self:Mark() + + end + + function ZONE_GOAL_CARGO:onenterCaptured() + + --self:GetParent( self ):onenterCaptured() + + local NewCoalition = self.Zone:GetCoalition() + self:E( { NewCoalition = NewCoalition } ) + self:SetCoalition( NewCoalition ) + + self:Mark() + end + + + function ZONE_GOAL_CARGO:onenterEmpty() + + --self:GetParent( self ):onenterEmpty() + + self:Mark() + end + + + function ZONE_GOAL_CARGO:onenterAttacked() + + --self:GetParent( self ):onenterAttacked() + + self:Mark() + end + + + --- When started, check the Coalition status. + -- @param #ZONE_GOAL_CARGO self + function ZONE_GOAL_CARGO:onafterGuard() + + --self:E({BASE:GetParent( self )}) + --BASE:GetParent( self ).onafterGuard( self ) + + if not self.SmokeScheduler then + self.SmokeScheduler = self:ScheduleRepeat( 1, 1, 0.1, nil, self.StatusSmoke, self ) + end + if not self.ScheduleStatusZone then + self.ScheduleStatusZone = self:ScheduleRepeat( 15, 15, 0.1, nil, self.StatusZone, self ) + end + end + + + function ZONE_GOAL_CARGO:IsCaptured() + + local IsCaptured = self.Zone:IsAllInZoneOfOtherCoalition( self.Coalition ) + self:E( { IsCaptured = IsCaptured } ) + return IsCaptured + end + + + function ZONE_GOAL_CARGO:IsAttacked() + + local IsAttacked = self.Zone:IsSomeInZoneOfCoalition( self.Coalition ) + self:E( { IsAttacked = IsAttacked } ) + return IsAttacked + end + + --- Check status Coalition ownership. + -- @param #ZONE_GOAL_CARGO self + function ZONE_GOAL_CARGO:StatusZone() + + local State = self:GetState() + self:E( { State = self:GetState() } ) + + self.Zone:Scan() + + if State ~= "Guarded" and self:IsGuarded() then + self:Guard() + end + + if State ~= "Empty" and self:IsEmpty() then + self:Empty() + end + + if State ~= "Attacked" and self:IsAttacked() then + self:Attack() + end + + if State ~= "Captured" and self:IsCaptured() then + self:Capture() + end + + end + +end + diff --git a/Moose Development/Moose/Tasking/TaskZoneCapture.lua b/Moose Development/Moose/Tasking/TaskZoneCapture.lua index b23f35988..fe8afcb5e 100644 --- a/Moose Development/Moose/Tasking/TaskZoneCapture.lua +++ b/Moose Development/Moose/Tasking/TaskZoneCapture.lua @@ -206,6 +206,7 @@ do -- TASK_ZONE_CAPTURE ClassName = "TASK_ZONE_CAPTURE", } + --- Instantiates a new TASK_ZONE_CAPTURE. -- @param #TASK_ZONE_CAPTURE self -- @param Tasking.Mission#MISSION Mission @@ -236,6 +237,7 @@ do -- TASK_ZONE_CAPTURE return self end + --- Instantiates a new TASK_ZONE_CAPTURE. -- @param #TASK_ZONE_CAPTURE self function TASK_ZONE_CAPTURE:UpdateTaskInfo() @@ -247,6 +249,7 @@ do -- TASK_ZONE_CAPTURE self:SetInfo( "Zone Coalition", self.ZoneGoal:GetCoalitionName(), 11 ) end + function TASK_ZONE_CAPTURE:ReportOrder( ReportGroup ) local Coordinate = self:GetInfo( "Coordinate" ) --local Coordinate = self.TaskInfo.Coordinates.TaskInfoText From 515cf70295656bb3716f3553b1599a0cc9580abe Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Wed, 11 Oct 2017 11:23:10 +0200 Subject: [PATCH 2/3] fixed text --- Moose Development/Moose/Functional/AirbasePolice.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Functional/AirbasePolice.lua b/Moose Development/Moose/Functional/AirbasePolice.lua index 85282eff9..c5b0c0d30 100644 --- a/Moose Development/Moose/Functional/AirbasePolice.lua +++ b/Moose Development/Moose/Functional/AirbasePolice.lua @@ -183,7 +183,7 @@ function AIRBASEPOLICE_BASE:_AirbaseMonitor() Client:Message( "You are speeding on the taxiway! Slow down or you will be removed from this airbase! Your current velocity is " .. string.format( "%2.0f km/h", Velocity ), 5, "Warning " .. SpeedingWarnings .. " / 3" ) Client:SetState( self, "Warnings", SpeedingWarnings + 1 ) else - MESSAGE:New( "Player " .. Client:GetPlayerName() .. " is being damaged at the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll() + MESSAGE:New( "Player " .. Client:GetPlayerName() .. " is being kicked from the airbase, due to a speeding violation ...", 10, "Airbase Police" ):ToAll() --- @param Wrapper.Client#CLIENT Client Client:Destroy() Client:SetState( self, "Speeding", false ) From 0cc36b5ee28cbb33dd2ac1edb58b813be9f396de Mon Sep 17 00:00:00 2001 From: FlightControl_Master Date: Thu, 12 Oct 2017 11:02:56 +0200 Subject: [PATCH 3/3] Added CARGO_CRATE Added a new object called CARGO_CRATE --- Moose Development/Moose/Core/Cargo.lua | 717 +++++++++++-------- Moose Development/Moose/Core/Database.lua | 3 +- Moose Development/Moose/Core/SpawnStatic.lua | 9 +- Moose Development/Moose/Wrapper/Group.lua | 2 + Moose Development/Moose/Wrapper/Object.lua | 1 - Moose Development/Moose/Wrapper/Static.lua | 17 +- Moose Development/Moose/Wrapper/Unit.lua | 18 + 7 files changed, 448 insertions(+), 319 deletions(-) diff --git a/Moose Development/Moose/Core/Cargo.lua b/Moose Development/Moose/Core/Cargo.lua index 1dd1bee64..b75ab205a 100644 --- a/Moose Development/Moose/Core/Cargo.lua +++ b/Moose Development/Moose/Core/Cargo.lua @@ -529,7 +529,7 @@ do -- CARGO_REPRESENTABLE -- @extends #CARGO -- @field test - --- + --- Models CARGO that is representable by a Unit. -- @field #CARGO_REPRESENTABLE CARGO_REPRESENTABLE CARGO_REPRESENTABLE = { ClassName = "CARGO_REPRESENTABLE" @@ -549,6 +549,18 @@ do -- CARGO_REPRESENTABLE return self end + + --- CARGO_REPRESENTABLE Destructor. + -- @param #CARGO_REPRESENTABLE self + -- @return #CARGO_REPRESENTABLE + function CARGO_REPRESENTABLE:Destroy() + + -- Cargo objects are deleted from the _DATABASE and SET_CARGO objects. + self:F( { CargoName = self:GetName() } ) + _EVENTDISPATCHER:CreateEventDeleteCargo( self ) + + return self + end --- Route a cargo unit to a PointVec2. -- @param #CARGO_REPRESENTABLE self @@ -678,7 +690,7 @@ end do -- CARGO_UNIT - --- Hello + --- Models CARGO in the form of units, which can be boarded, unboarded, loaded, unloaded. -- @type CARGO_UNIT -- @extends #CARGO_REPRESENTABLE @@ -695,346 +707,425 @@ do -- CARGO_UNIT ClassName = "CARGO_UNIT" } ---- CARGO_UNIT Constructor. --- @param #CARGO_UNIT self --- @param Wrapper.Unit#UNIT CargoUnit --- @param #string Type --- @param #string Name --- @param #number Weight --- @param #number ReportRadius (optional) --- @param #number NearRadius (optional) --- @return #CARGO_UNIT -function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius ) - local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, Weight, NearRadius ) ) -- #CARGO_UNIT - self:F( { Type, Name, Weight, NearRadius } ) - - self:T( CargoUnit ) - self.CargoObject = CargoUnit - - self:T( self.ClassName ) - --- self:HandleEvent( EVENTS.Dead, --- --- @param #CARGO Cargo --- -- @param Core.Event#EVENTDATA EventData --- function( Cargo, EventData ) --- if Cargo:GetObjectName() == EventData.IniUnit:GetName() then --- self:E( { "Cargo destroyed", Cargo } ) --- Cargo:Destroyed() --- end --- end --- ) - - self:SetEventPriority( 5 ) - - return self -end - ---- CARGO_UNIT Destructor. --- @param #CARGO_UNIT self --- @return #CARGO_UNIT -function CARGO_UNIT:Destroy() - - -- Cargo objects are deleted from the _DATABASE and SET_CARGO objects. - self:F( { CargoName = self:GetName() } ) - _EVENTDISPATCHER:CreateEventDeleteCargo( self ) - - return self -end - ---- Enter UnBoarding State. --- @param #CARGO_UNIT self --- @param #string Event --- @param #string From --- @param #string To --- @param Core.Point#POINT_VEC2 ToPointVec2 -function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius ) - self:F( { From, Event, To, ToPointVec2, NearRadius } ) - - NearRadius = NearRadius or 25 - - local Angle = 180 - local Speed = 60 - local DeployDistance = 9 - local RouteDistance = 60 - - if From == "Loaded" 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 - ToPointVec2 = ToPointVec2 or CargoRoutePointVec2 - local DirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3(ToPointVec2) - local Angle = CargoCarrierPointVec2:GetAngleDegrees(DirectionVec3) - - local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, Angle ) - - local FromPointVec2 = CargoCarrierPointVec2 - - -- Respawn the group... - if self.CargoObject then - self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading ) - self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } ) - self.CargoCarrier = nil - - local Points = {} - Points[#Points+1] = CargoCarrierPointVec2:WaypointGround( Speed ) - - Points[#Points+1] = ToPointVec2:WaypointGround( Speed ) + --- CARGO_UNIT Constructor. + -- @param #CARGO_UNIT self + -- @param Wrapper.Unit#UNIT CargoUnit + -- @param #string Type + -- @param #string Name + -- @param #number Weight + -- @param #number ReportRadius (optional) + -- @param #number NearRadius (optional) + -- @return #CARGO_UNIT + function CARGO_UNIT:New( CargoUnit, Type, Name, Weight, NearRadius ) + local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoUnit, Type, Name, Weight, NearRadius ) ) -- #CARGO_UNIT + self:F( { Type, Name, Weight, NearRadius } ) - local TaskRoute = self.CargoObject:TaskRoute( Points ) - self.CargoObject:SetTask( TaskRoute, 1 ) - - - self:__UnBoarding( 1, ToPointVec2, NearRadius ) - end - end - -end - ---- Leave UnBoarding State. --- @param #CARGO_UNIT self --- @param #string Event --- @param #string From --- @param #string To --- @param Core.Point#POINT_VEC2 ToPointVec2 -function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius ) - self:F( { From, Event, To, ToPointVec2, NearRadius } ) - - NearRadius = NearRadius or 25 - - local Angle = 180 - local Speed = 10 - local Distance = 5 - - if From == "UnBoarding" then - if self:IsNear( ToPointVec2, NearRadius ) then - return true - else - - self:__UnBoarding( 1, ToPointVec2, NearRadius ) - end - return false - end - -end - ---- UnBoard Event. --- @param #CARGO_UNIT self --- @param #string Event --- @param #string From --- @param #string To --- @param Core.Point#POINT_VEC2 ToPointVec2 -function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius ) - self:F( { From, Event, To, ToPointVec2, NearRadius } ) - - NearRadius = NearRadius or 25 - - self.CargoInAir = self.CargoObject:InAir() - - self:T( self.CargoInAir ) - - -- Only unboard the cargo when the carrier is not in the air. - -- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea). - if not self.CargoInAir then - - end - - self:__UnLoad( 1, ToPointVec2, NearRadius ) - -end - - - ---- Enter UnLoaded State. --- @param #CARGO_UNIT self --- @param #string Event --- @param #string From --- @param #string To --- @param Core.Point#POINT_VEC2 -function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 ) - self:F( { ToPointVec2, From, Event, To } ) - - local Angle = 180 - local Speed = 10 - local Distance = 5 - - if From == "Loaded" then - local StartPointVec2 = self.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 CargoDeployCoord = StartPointVec2:Translate( Distance, CargoDeployHeading ) - - ToPointVec2 = ToPointVec2 or POINT_VEC2:New( CargoDeployCoord.x, CargoDeployCoord.z ) - - -- Respawn the group... - if self.CargoObject then - self.CargoObject:ReSpawn( ToPointVec2:GetVec3(), 0 ) - self.CargoCarrier = nil - end - - end - - if self.OnUnLoadedCallBack then - self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) ) - self.OnUnLoadedCallBack = nil - end - -end - ---- Board Event. --- @param #CARGO_UNIT self --- @param #string Event --- @param #string From --- @param #string To -function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... ) - self:F( { From, Event, To, CargoCarrier, NearRadius } ) - - local NearRadius = NearRadius or 25 + self:T( CargoUnit ) + self.CargoObject = CargoUnit + + self:T( self.ClassName ) + + self:SetEventPriority( 5 ) + + return self + end + + --- Enter UnBoarding State. + -- @param #CARGO_UNIT self + -- @param #string Event + -- @param #string From + -- @param #string To + -- @param Core.Point#POINT_VEC2 ToPointVec2 + function CARGO_UNIT:onenterUnBoarding( From, Event, To, ToPointVec2, NearRadius ) + self:F( { From, Event, To, ToPointVec2, NearRadius } ) + + NearRadius = NearRadius or 25 + + local Angle = 180 + local Speed = 60 + local DeployDistance = 9 + local RouteDistance = 60 + + if From == "Loaded" then + + local CargoCarrier = self.CargoCarrier -- Wrapper.Controllable#CONTROLLABLE - self.CargoInAir = self.CargoObject:InAir() - - self:T( self.CargoInAir ) - - -- Only move the group to the carrier when the cargo is not in the air - -- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea). - if not self.CargoInAir then - if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then - self:Load( CargoCarrier, NearRadius, ... ) - else - local Speed = 90 - local Angle = 180 - local Distance = 5 - - NearRadius = NearRadius or 25 - local CargoCarrierPointVec2 = CargoCarrier:GetPointVec2() - local CargoCarrierHeading = CargoCarrier:GetHeading() -- Get Heading of object in degrees. + local CargoCarrierHeading = self.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 CargoRoutePointVec2 = CargoCarrierPointVec2:Translate( RouteDistance, CargoDeployHeading ) + + + -- if there is no ToPointVec2 given, then use the CargoRoutePointVec2 + ToPointVec2 = ToPointVec2 or CargoRoutePointVec2 + local DirectionVec3 = CargoCarrierPointVec2:GetDirectionVec3(ToPointVec2) + local Angle = CargoCarrierPointVec2:GetAngleDegrees(DirectionVec3) + + local CargoDeployPointVec2 = CargoCarrierPointVec2:Translate( DeployDistance, Angle ) + + local FromPointVec2 = CargoCarrierPointVec2 + + -- Respawn the group... + if self.CargoObject then + self.CargoObject:ReSpawn( CargoDeployPointVec2:GetVec3(), CargoDeployHeading ) + self:F( { "CargoUnits:", self.CargoObject:GetGroup():GetName() } ) + self.CargoCarrier = nil + + local Points = {} + Points[#Points+1] = CargoCarrierPointVec2:WaypointGround( Speed ) + + Points[#Points+1] = ToPointVec2:WaypointGround( Speed ) - 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 TaskRoute = self.CargoObject:TaskRoute( Points ) + self.CargoObject:SetTask( TaskRoute, 1 ) + + + self:__UnBoarding( 1, ToPointVec2, NearRadius ) + end end + end -end - - ---- Boarding Event. --- @param #CARGO_UNIT self --- @param #string Event --- @param #string From --- @param #string To --- @param Wrapper.Unit#UNIT CargoCarrier --- @param #number NearRadius -function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... ) - self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } ) + --- Leave UnBoarding State. + -- @param #CARGO_UNIT self + -- @param #string Event + -- @param #string From + -- @param #string To + -- @param Core.Point#POINT_VEC2 ToPointVec2 + function CARGO_UNIT:onleaveUnBoarding( From, Event, To, ToPointVec2, NearRadius ) + self:F( { From, Event, To, ToPointVec2, NearRadius } ) + NearRadius = NearRadius or 25 - if CargoCarrier and CargoCarrier:IsAlive() then - if CargoCarrier:InAir() == false then - if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then - self:__Load( 1, CargoCarrier, ... ) + local Angle = 180 + local Speed = 10 + local Distance = 5 + + if From == "UnBoarding" then + if self:IsNear( ToPointVec2, NearRadius ) then + return true else - self:__Boarding( -1, CargoCarrier, NearRadius, ... ) - self.RunCount = self.RunCount + 1 - if self.RunCount >= 20 then - self.RunCount = 0 - local Speed = 90 - local Angle = 180 - local Distance = 5 + + self:__UnBoarding( 1, ToPointVec2, NearRadius ) + end + return false + end + + end + + --- UnBoard Event. + -- @param #CARGO_UNIT self + -- @param #string Event + -- @param #string From + -- @param #string To + -- @param Core.Point#POINT_VEC2 ToPointVec2 + function CARGO_UNIT:onafterUnBoarding( From, Event, To, ToPointVec2, NearRadius ) + self:F( { From, Event, To, ToPointVec2, NearRadius } ) + + NearRadius = NearRadius or 25 + + self.CargoInAir = self.CargoObject:InAir() + + self:T( self.CargoInAir ) + + -- Only unboard the cargo when the carrier is not in the air. + -- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea). + if not self.CargoInAir then + + end + + self:__UnLoad( 1, ToPointVec2, NearRadius ) + + end + + + + --- Enter UnLoaded State. + -- @param #CARGO_UNIT self + -- @param #string Event + -- @param #string From + -- @param #string To + -- @param Core.Point#POINT_VEC2 + function CARGO_UNIT:onenterUnLoaded( From, Event, To, ToPointVec2 ) + self:F( { ToPointVec2, From, Event, To } ) + + local Angle = 180 + local Speed = 10 + local Distance = 5 + + if From == "Loaded" then + local StartPointVec2 = self.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 CargoDeployCoord = StartPointVec2:Translate( Distance, CargoDeployHeading ) + + ToPointVec2 = ToPointVec2 or COORDINATE:New( CargoDeployCoord.x, CargoDeployCoord.z ) + + -- Respawn the group... + if self.CargoObject then + self.CargoObject:ReSpawn( ToPointVec2:GetVec3(), 0 ) + self.CargoCarrier = nil + end + + end + + if self.OnUnLoadedCallBack then + self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) ) + self.OnUnLoadedCallBack = nil + end + + end + + --- Board Event. + -- @param #CARGO_UNIT self + -- @param #string Event + -- @param #string From + -- @param #string To + function CARGO_UNIT:onafterBoard( From, Event, To, CargoCarrier, NearRadius, ... ) + self:F( { From, Event, To, CargoCarrier, NearRadius } ) + + local NearRadius = NearRadius or 25 + + self.CargoInAir = self.CargoObject:InAir() + + self:T( self.CargoInAir ) + + -- Only move the group to the carrier when the cargo is not in the air + -- (eg. cargo can be on a oil derrick, moving the cargo on the oil derrick will drop the cargo on the sea). + if not self.CargoInAir then + if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then + self:Load( CargoCarrier, NearRadius, ... ) + else + local Speed = 90 + local Angle = 180 + local Distance = 5 + + 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 + end + end + + end + + + --- Boarding Event. + -- @param #CARGO_UNIT self + -- @param #string Event + -- @param #string From + -- @param #string To + -- @param Wrapper.Unit#UNIT CargoCarrier + -- @param #number NearRadius + function CARGO_UNIT:onafterBoarding( From, Event, To, CargoCarrier, NearRadius, ... ) + self:F( { From, Event, To, CargoCarrier.UnitName, NearRadius } ) + + + if CargoCarrier and CargoCarrier:IsAlive() then + if CargoCarrier:InAir() == false then + if self:IsNear( CargoCarrier:GetPointVec2(), NearRadius ) then + self:__Load( 1, CargoCarrier, ... ) + else + self:__Boarding( -1, CargoCarrier, NearRadius, ... ) + self.RunCount = self.RunCount + 1 + if self.RunCount >= 20 then + self.RunCount = 0 + 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, 0.2 ) + 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, 0.2 ) + end end + else + self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() ) + self:CancelBoarding( CargoCarrier, NearRadius, ... ) + self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) ) end else - self.CargoObject:MessageToGroup( "Cancelling Boarding... Get back on the ground!", 5, CargoCarrier:GetGroup(), self:GetName() ) - self:CancelBoarding( CargoCarrier, NearRadius, ... ) - self.CargoObject:SetCommand( self.CargoObject:CommandStopRoute( true ) ) + self:E("Something is wrong") end - else - self:E("Something is wrong") + end -end - - ---- Enter Boarding State. --- @param #CARGO_UNIT self --- @param #string Event --- @param #string From --- @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 } ) - local Speed = 90 - local Angle = 180 - local Distance = 5 - - local NearRadius = NearRadius or 25 - - if From == "UnLoaded" or From == "Boarding" then + --- Enter Boarding State. + -- @param #CARGO_UNIT self + -- @param #string Event + -- @param #string From + -- @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 } ) + + local Speed = 90 + local Angle = 180 + local Distance = 5 + + local NearRadius = NearRadius or 25 + if From == "UnLoaded" or From == "Boarding" then + + end + end -end - ---- Loaded State. --- @param #CARGO_UNIT self --- @param #string Event --- @param #string From --- @param #string To --- @param Wrapper.Unit#UNIT CargoCarrier -function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier ) - self:F( { From, Event, To, CargoCarrier } ) - - self.CargoCarrier = CargoCarrier + --- Loaded State. + -- @param #CARGO_UNIT self + -- @param #string Event + -- @param #string From + -- @param #string To + -- @param Wrapper.Unit#UNIT CargoCarrier + function CARGO_UNIT:onenterLoaded( From, Event, To, CargoCarrier ) + self:F( { From, Event, To, CargoCarrier } ) - -- Only destroy the CargoObject is if there is a CargoObject (packages don't have CargoObjects). - if self.CargoObject then - self:T("Destroying") - self.CargoObject:Destroy() + 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.CargoObject:Destroy() + end + end + +end -- CARGO_UNIT + + +do -- CARGO_CRATE + + --- Models the behaviour of cargo crates, which can be slingloaded and boarded on helicopters using the DCS menus. + -- @type CARGO_CRATE + -- @extends #CARGO_REPRESENTABLE + + --- # CARGO\_CRATE class, extends @{#CARGO_REPRESENTABLE} + -- + -- The CARGO\_CRATE class defines a cargo that is represented by a UNIT object within the simulator, and can be transported by a carrier. + -- Use the event functions as described above to Load, UnLoad, Board, UnBoard the CARGO\_CRATE objects to and from carriers. + -- + -- === + -- + -- @field #CARGO_CRATE + CARGO_CRATE = { + ClassName = "CARGO_CRATE" + } + + --- CARGO_CRATE Constructor. + -- @param #CARGO_CRATE self + -- @param #string CrateName + -- @param #string Type + -- @param #string Name + -- @param #number Weight + -- @param #number ReportRadius (optional) + -- @param #number NearRadius (optional) + -- @return #CARGO_CRATE + function CARGO_CRATE:New( CargoCrateName, Type, Name, NearRadius ) + local self = BASE:Inherit( self, CARGO_REPRESENTABLE:New( CargoCrateName, Type, Name, nil, NearRadius ) ) -- #CARGO_CRATE + self:F( { Type, Name, NearRadius } ) + + self:T( CargoCrateName ) + _DATABASE:AddStatic( CargoCrateName ) + + self.CargoObject = STATIC:FindByName( CargoCrateName ) + + self:T( self.ClassName ) + + self:SetEventPriority( 5 ) + + return self + end + + + + --- Enter UnLoaded State. + -- @param #CARGO_CRATE self + -- @param #string Event + -- @param #string From + -- @param #string To + -- @param Core.Point#POINT_VEC2 + function CARGO_CRATE:onenterUnLoaded( From, Event, To, ToPointVec2 ) + self:F( { ToPointVec2, From, Event, To } ) + + local Angle = 180 + local Speed = 10 + local Distance = 10 + + if From == "Loaded" then + local StartCoordinate = self.CargoCarrier:GetCoordinate() + local CargoCarrierHeading = self.CargoCarrier:GetHeading() -- Get Heading of object in degrees. + local CargoDeployHeading = ( ( CargoCarrierHeading + Angle ) >= 360 ) and ( CargoCarrierHeading + Angle - 360 ) or ( CargoCarrierHeading + Angle ) + local CargoDeployCoord = StartCoordinate:Translate( Distance, CargoDeployHeading ) + + ToPointVec2 = ToPointVec2 or COORDINATE:NewFromVec2( { x= CargoDeployCoord.x, y = CargoDeployCoord.z } ) + + -- Respawn the group... + if self.CargoObject then + self.CargoObject:ReSpawn( ToPointVec2, 0 ) + self.CargoCarrier = nil + end + + end + + if self.OnUnLoadedCallBack then + self.OnUnLoadedCallBack( self, unpack( self.OnUnLoadedParameters ) ) + self.OnUnLoadedCallBack = nil + end + + end + + + --- Loaded State. + -- @param #CARGO_CRATE self + -- @param #string Event + -- @param #string From + -- @param #string To + -- @param Wrapper.Unit#UNIT CargoCarrier + function CARGO_CRATE:onenterLoaded( 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.CargoObject:Destroy() + end end -end end - do -- CARGO_GROUP --- @type CARGO_GROUP diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index 218384985..bf8ef630e 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -522,7 +522,7 @@ function DATABASE:_RegisterStaticTemplate( StaticTemplate, CoalitionID, Category TraceTable[#TraceTable+1] = "Static" - TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].GroupName + TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].StaticName TraceTable[#TraceTable+1] = "Coalition" TraceTable[#TraceTable+1] = self.Templates.Statics[StaticTemplateName].CoalitionID @@ -649,6 +649,7 @@ end function DATABASE:_RegisterStatics() local CoalitionsData = { GroupsRed = coalition.getStaticObjects( coalition.side.RED ), GroupsBlue = coalition.getStaticObjects( coalition.side.BLUE ) } + self:E( { Statics = CoalitionsData } ) for CoalitionId, CoalitionData in pairs( CoalitionsData ) do for DCSStaticId, DCSStatic in pairs( CoalitionData ) do diff --git a/Moose Development/Moose/Core/SpawnStatic.lua b/Moose Development/Moose/Core/SpawnStatic.lua index 2bc29f6c5..533c51e1f 100644 --- a/Moose Development/Moose/Core/SpawnStatic.lua +++ b/Moose Development/Moose/Core/SpawnStatic.lua @@ -157,8 +157,13 @@ function SPAWNSTATIC:SpawnFromPointVec2( PointVec2, Heading, NewName ) --R2.1 local StaticTemplate = _DATABASE:GetStaticUnitTemplate( self.SpawnTemplatePrefix ) - StaticTemplate.x = PointVec2:GetLat() - StaticTemplate.y = PointVec2:GetLon() + StaticTemplate.x = PointVec2.x + StaticTemplate.y = PointVec2.z + + StaticTemplate.units = nil + StaticTemplate.route = nil + StaticTemplate.groupId = nil + StaticTemplate.name = NewName or string.format("%s#%05d", self.SpawnTemplatePrefix, self.SpawnIndex ) StaticTemplate.heading = ( Heading / 180 ) * math.pi diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 59da812ae..c4074bb7c 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -224,6 +224,7 @@ function GROUP:Destroy() for Index, UnitData in pairs( DCSGroup:getUnits() ) do self:CreateEventCrash( timer.getTime(), UnitData ) end + USERFLAG:New( self:GetName() ):Set( 100 ) DCSGroup:destroy() DCSGroup = nil end @@ -231,6 +232,7 @@ function GROUP:Destroy() return nil end + --- Returns category of the DCS Group. -- @param #GROUP self -- @return Dcs.DCSWrapper.Group#Group.Category The category ID diff --git a/Moose Development/Moose/Wrapper/Object.lua b/Moose Development/Moose/Wrapper/Object.lua index 140c94006..68ae6f775 100644 --- a/Moose Development/Moose/Wrapper/Object.lua +++ b/Moose Development/Moose/Wrapper/Object.lua @@ -79,7 +79,6 @@ function OBJECT:Destroy() local DCSObject = self:GetDCSObject() if DCSObject then - USERFLAG:New( self:GetGroup():GetName() ):Set( 100 ) --BASE:CreateEventCrash( timer.getTime(), DCSObject ) DCSObject:destroy() end diff --git a/Moose Development/Moose/Wrapper/Static.lua b/Moose Development/Moose/Wrapper/Static.lua index cc1e1f74c..1a76a869a 100644 --- a/Moose Development/Moose/Wrapper/Static.lua +++ b/Moose Development/Moose/Wrapper/Static.lua @@ -61,7 +61,6 @@ function STATIC:FindByName( StaticName, RaiseError ) if StaticFound then StaticFound:F3( { StaticName } ) - return StaticFound end @@ -92,4 +91,18 @@ end function STATIC:GetThreatLevel() return 1, "Static" -end \ No newline at end of file +end + +--- Respawn the @{Unit} using a (tweaked) template of the parent Group. +-- @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 ) + + + -- todo: need to fix country + local SpawnStatic = SPAWNSTATIC:NewFromStatic( self.StaticName, country.id.USA ) + + SpawnStatic:SpawnFromPointVec2( Coordinate, Heading, self.StaticName ) +end + diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 7f9a34ed2..ec976b0bc 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -159,6 +159,24 @@ function UNIT:GetDCSObject() return nil end +--- Destroys the UNIT. +-- @param #UNIT self +-- @return #nil The DCS Unit is not existing or alive. +function UNIT:Destroy() + self:F2( self.ObjectName ) + + local DCSObject = self:GetDCSObject() + + if DCSObject then + USERFLAG:New( self:GetGroup():GetName() ):Set( 100 ) + --BASE:CreateEventCrash( timer.getTime(), DCSObject ) + DCSObject:destroy() + end + + return nil +end + + --- Respawn the @{Unit} using a (tweaked) template of the parent Group. -- -- This function will: