diff --git a/Moose/Base.lua b/Moose/Base.lua index 216b02e76..1d54ac663 100644 --- a/Moose/Base.lua +++ b/Moose/Base.lua @@ -303,6 +303,10 @@ end -- @param #string Class -- @param #string Method function BASE:TraceClassMethod( Class, Method ) + if not _TraceClassMethod[Class] then + _TraceClassMethod[Class] = {} + _TraceClassMethod[Class].Method = {} + end _TraceClassMethod[Class].Method[Method] = true end diff --git a/Moose/Database.lua b/Moose/Database.lua index 479483ec4..b1ac948de 100644 --- a/Moose/Database.lua +++ b/Moose/Database.lua @@ -936,6 +936,6 @@ function LogClose() end end -_Database = DATABASE:New() +_Database = DATABASE:New() -- Database#DATABASE _Database:ScoreOpen() diff --git a/Moose/Escort.lua b/Moose/Escort.lua index 7be1f92fa..60b6c4e6d 100644 --- a/Moose/Escort.lua +++ b/Moose/Escort.lua @@ -29,23 +29,31 @@ -- * **"Scan targets 30 seconds":** Scan 30 seconds for targets. -- * **"Scan targets 60 seconds":** Scan 60 seconds for targets. -- --- **4. Attack nearby targets ...:** This menu item will list all detected targets within an 8km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed. +-- **4. Attack targets ...:** This menu item will list all detected targets within a 15km range. Depending on the level of detection (known/unknown) and visuality, the targets type will also be listed. -- --- **5. ROE ...:** Defines the Rules of Engagement of the escort group when in flight. +-- **5. Request assistance from ...:** This menu item will list all detected targets within a 15km range, as with the menu item **Attack Targets**. +-- This menu item allows to request attack support from other escorts supporting the current client group. +-- eg. the function allows a player to request support from the Ship escort to attack a target identified by the Plane escort with its Tomahawk missiles. +-- eg. the function allows a player to request support from other Planes escorting to bomb the unit with illumination missiles or bombs, so that the main plane escort can attack the area. +-- +-- **6. ROE ...:** Defines the Rules of Engagement of the escort group when in flight. -- -- * **"Hold Fire":** The escort group will hold fire. -- * **"Return Fire":** The escort group will return fire. -- * **"Open Fire":** The escort group will open fire on designated targets. -- * **"Weapon Free":** The escort group will engage with any target. -- --- **6. Evasion ...:** Will define the evasion techniques that the escort group will perform during flight or combat. +-- **7. Evasion ...:** Will define the evasion techniques that the escort group will perform during flight or combat. -- -- * **"Fight until death":** The escort group will have no reaction to threats. -- * **"Use flares, chaff and jammers":** The escort group will use passive defense using flares and jammers. No evasive manoeuvres are executed. -- * **"Evade enemy fire":** The rescort group will evade enemy fire before firing. -- * **"Go below radar and evade fire":** The escort group will perform evasive vertical manoeuvres. -- --- **7. Resume Mission ...:** Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint. Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission. +-- **8. Resume Mission ...:** Escort groups can have their own mission. This menu item will allow the escort group to resume their Mission from a given waypoint. +-- Note that this is really fantastic, as you now have the dynamic of taking control of the escort groups, and allowing them to resume their path or mission. +-- +-- **9. Abort Current Task:** Cancel the current task and rejoin formation. -- -- 1. ESCORT object construction methods. -- -------------------------------------- @@ -112,6 +120,8 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) self.EscortGroup = EscortGroup -- Group#GROUP self.EscortName = EscortName self.EscortBriefing = EscortBriefing + + self:T( EscortGroup:GetClassNameAndID() ) -- Set EscortGroup known at EscortClient. if not self.EscortClient._EscortGroups then @@ -170,7 +180,12 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) end -- Attack Targets - self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack nearby targets", self.EscortMenu ) + self.EscortMenuAttackNearbyTargets = MENU_CLIENT:New( self.EscortClient, "Attack targets", self.EscortMenu ) + + -- Request assistance from other escorts. + -- This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane... + self.EscortMenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, "Request assistance from", self.EscortMenu ) + -- Rules of Engagement self.EscortMenuROE = MENU_CLIENT:New( self.EscortClient, "ROE", self.EscortMenu ) @@ -205,9 +220,6 @@ function ESCORT:New( EscortClient, EscortGroup, EscortName, EscortBriefing ) -- Mission Resume Menu Root self.EscortMenuResumeMission = MENU_CLIENT:New( self.EscortClient, "Resume the escort mission", self.EscortMenu ) - -- Exchange targets with other escorts of the CLIENT. This is very useful to let f.e. an escorting ship attack a target detected by an escorting plane... - self.EscortMenuTargetAssistance = MENU_CLIENT:New( self.EscortClient, "Target assistance from other escorts", self.EscortMenu ) - -- Initialize the EscortGroup EscortGroup:OptionROTVertical() @@ -284,13 +296,27 @@ function ESCORT._JoinUpAndFollow( MenuParam ) local Distance = MenuParam.ParamDistance + self:JoinUpAndFollow( EscortGroup, EscortClient, Distance ) +end + +--- JoinsUp and Follows a CLIENT. +-- @param Escort#ESCORT self +-- @param Group#GROUP EscortGroup +-- @param Client#CLIENT EscortClient +-- @param DCSTypes#Distance Distance +function ESCORT:JoinUpAndFollow( EscortGroup, EscortClient, Distance ) + self:F( { EscortGroup, EscortClient, Distance } ) + if self.FollowScheduler then routines.removeFunction( self.FollowScheduler ) end + EscortGroup:OptionROEHoldFire() + EscortGroup:OptionROTVertical() + self.CT1 = 0 self.GT1 = 0 - self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, 1 ) + self.FollowScheduler = routines.scheduleFunction( self._FollowScheduler, { self, Distance }, timer.getTime() + 1, .5 ) EscortGroup:MessageToClient( "Rejoining and Following at " .. Distance .. "!", 30, EscortClient ) end @@ -631,7 +657,7 @@ function ESCORT:_FollowScheduler( FollowDistance ) local DVu = { x = DV.x / FollowDistance, y = DV.y / FollowDistance, z = DV.z / FollowDistance } -- Now we can calculate the group destination vector GDV. - local GDV = { x = DVu.x * CS * 2 + CVI.x, y = CVI.y, z = DVu.z * CS * 2 + CVI.z } + local GDV = { x = DVu.x * CS * 8 + CVI.x, y = CVI.y, z = DVu.z * CS * 8 + CVI.z } self:T2( { "CV2:", CV2 } ) self:T2( { "CVI:", CVI } ) self:T2( { "GDV:", GDV } ) @@ -642,7 +668,7 @@ function ESCORT:_FollowScheduler( FollowDistance ) -- The calculation of the Speed would simulate that the group would take 30 seconds to overcome -- the requested Distance). local Time = 10 - local CatchUpSpeed = ( CatchUpDistance - ( CS * 2 ) ) / Time + local CatchUpSpeed = ( CatchUpDistance - ( CS * 8.4 ) ) / Time local Speed = CS + CatchUpSpeed if Speed < 0 then @@ -664,10 +690,9 @@ end --- Report Targets Scheduler. -- @param #ESCORT self function ESCORT:_ReportTargetsScheduler() - self:F() + self:F( self.EscortGroup:GetName() ) - - if self.EscortGroup:IsAlive() then + if self.EscortGroup:IsAlive() and self.EscortClient:IsAlive() then local EscortGroupName = self.EscortGroup:GetName() local EscortTargets = self.EscortGroup:GetDetectedTargets() @@ -720,7 +745,10 @@ function ESCORT:_ReportTargetsScheduler() ClientEscortTargets[EscortTargetUnitName].visible = EscortTarget.visible ClientEscortTargets[EscortTargetUnitName].type = EscortTarget.type ClientEscortTargets[EscortTargetUnitName].distance = EscortTarget.distance - + else + if ClientEscortTargets[EscortTargetUnitName] then + ClientEscortTargets[EscortTargetUnitName] = nil + end end end end diff --git a/Moose/Group.lua b/Moose/Group.lua index 9deb1242f..a654a751a 100644 --- a/Moose/Group.lua +++ b/Moose/Group.lua @@ -201,10 +201,11 @@ function GROUP:Destroy() self:F( self.GroupName ) for Index, UnitData in pairs( self.DCSGroup:getUnits() ) do - self:CreateEventCrash( timer.getTime(), UnitData ) + self:CreateEventDead( timer.getTime(), UnitData ) end self.DCSGroup:destroy() + self.DCSGroup = nil end --- Gets the DCS Unit. @@ -752,15 +753,37 @@ function GROUP:TaskRouteToVec3( Point, Speed ) PointFrom.x = GroupPoint.x PointFrom.y = GroupPoint.z PointFrom.alt = GroupPoint.y + PointFrom.alt_type = "BARO" PointFrom.type = "Turning Point" + PointFrom.action = "Turning Point" + PointFrom.speed = Speed + PointFrom.speed_locked = true + PointFrom.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + local PointTo = {} PointTo.x = Point.x PointTo.y = Point.z - PointTo.alt = Point.y + PointTo.alt = Point.y + PointTo.alt_type = "BARO" PointTo.type = "Turning Point" + PointTo.action = "Fly Over Point" PointTo.speed = Speed PointTo.speed_locked = true + PointTo.properties = { + ["vnav"] = 1, + ["scale"] = 0, + ["angle"] = 0, + ["vangle"] = 0, + ["steer"] = 2, + } + local Points = { PointFrom, PointTo } @@ -1002,8 +1025,8 @@ function GROUP:OptionROEHoldFirePossible() end --- Holding weapons. --- @param #GROUP self --- @return #GROUP self +-- @param Group#GROUP self +-- @return Group#GROUP self function GROUP:OptionROEHoldFire() self:F( { self.GroupName } ) diff --git a/Moose/Menu.lua b/Moose/Menu.lua index c6e6ee7df..f386e118d 100644 --- a/Moose/Menu.lua +++ b/Moose/Menu.lua @@ -120,13 +120,14 @@ function MENU_CLIENT:New( MenuClient, MenuText, ParentMenu ) self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText } ) - if not MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] then - self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath ) - MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] = self.MenuPath - else - self.MenuPath = MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] + local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText + if MenuPath[MenuPathID] then + missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] ) end + self.MenuPath = missionCommands.addSubMenuForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath ) + MenuPath[MenuPathID] = self.MenuPath + self:T( { MenuClient:GetClientGroupName(), self.MenuPath } ) if ParentMenu and ParentMenu.Menus then @@ -211,13 +212,14 @@ function MENU_CLIENT_COMMAND:New( MenuClient, MenuText, ParentMenu, CommandMenuF self:T( { MenuClient:GetClientGroupName(), MenuPath[table.concat(MenuParentPath)], MenuParentPath, MenuText, CommandMenuFunction, CommandMenuArgument } ) - if not MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] then - self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument ) - MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] = self.MenuPath - else - self.MenuPath = MenuPath[table.concat(MenuParentPath) .. "/" .. MenuText] + local MenuPathID = table.concat(MenuParentPath) .. "/" .. MenuText + if MenuPath[MenuPathID] then + missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), MenuPath[MenuPathID] ) end - + + self.MenuPath = missionCommands.addCommandForGroup( self.MenuClient:GetClientGroupID(), MenuText, MenuParentPath, CommandMenuFunction, CommandMenuArgument ) + MenuPath[MenuPathID] = self.MenuPath + self.CommandMenuFunction = CommandMenuFunction self.CommandMenuArgument = CommandMenuArgument @@ -238,6 +240,7 @@ function MENU_CLIENT_COMMAND:Remove() if MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] then MenuPath[table.concat(self.MenuParentPath) .. "/" .. self.MenuText] = nil end + missionCommands.removeItemForGroup( self.MenuClient:GetClientGroupID(), self.MenuPath ) self.ParentMenu.Menus[self.MenuPath] = nil return nil diff --git a/Moose/Spawn.lua b/Moose/Spawn.lua index c30a4b83f..eff339882 100644 --- a/Moose/Spawn.lua +++ b/Moose/Spawn.lua @@ -418,12 +418,15 @@ function SPAWN:ReSpawn( SpawnIndex ) SpawnIndex = 1 end - local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) - local SpawnDCSGroup = SpawnGroup:GetDCSGroup() - if SpawnDCSGroup then - SpawnGroup:Destroy() - end - +-- TODO: This logic makes DCS crash and i don't know why (yet). +-- local SpawnGroup = self:GetGroupFromIndex( SpawnIndex ) +-- if SpawnGroup then +-- local SpawnDCSGroup = SpawnGroup:GetDCSGroup() +-- if SpawnDCSGroup then +-- SpawnGroup:Destroy() +-- end +-- end + return self:SpawnWithIndex( SpawnIndex ) end @@ -762,12 +765,15 @@ end function SPAWN:GetGroupFromIndex( SpawnIndex ) self:F( { self.SpawnTemplatePrefix, self.SpawnAliasPrefix, SpawnIndex } ) - if SpawnIndex then + if not SpawnIndex then + SpawnIndex = 1 + end + + if self.SpawnGroups and self.SpawnGroups[SpawnIndex] then local SpawnGroup = self.SpawnGroups[SpawnIndex].Group return SpawnGroup else - local SpawnGroup = self.SpawnGroups[1].Group - return SpawnGroup + return nil end end diff --git a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua index 9cee0fa40..fa4516e7a 100644 --- a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua +++ b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.lua @@ -7,33 +7,32 @@ Include.File( "Escort" ) do local function EventAliveHelicopter( Client ) - local SpawnEscortHeli = SPAWN:New( "Escort Helicopter" ) - local SpawnEscortPlane = SPAWN:New( "Escort Plane" ) - local SpawnEscortGround = SPAWN:New( "Escort Ground" ) - local EscortGroupHeli1 = SpawnEscortHeli:Spawn() + local EscortGroupHeli1 = SpawnEscortHeli:ReSpawn(1) local EscortHeli1 = ESCORT:New( Client, EscortGroupHeli1, "Escort Alpha" ) - local EscortGroupPlane = SpawnEscortPlane:Spawn() + local EscortGroupPlane = SpawnEscortPlane:ReSpawn(1) local EscortPlane = ESCORT:New( Client, EscortGroupPlane, "Escort Test Plane" ) - local EscortGroupGround = SpawnEscortGround:Spawn() + local EscortGroupGround = SpawnEscortGround:ReSpawn(1) local EscortGround = ESCORT:New( Client, EscortGroupGround, "Test Ground" ) end local function EventAlivePlane( Client ) - local SpawnEscortPlane = SPAWN:New( "Escort Plane" ) - local EscortGroupPlane = SpawnEscortPlane:Spawn() + local EscortGroupPlane = SpawnEscortPlane:ReSpawn(1) local EscortPlane = ESCORT:New( Client, EscortGroupPlane, "Escort Test Plane" ) - local SpawnEscortGround = SPAWN:New( "Escort Ground" ) - local EscortGroupGround = SpawnEscortGround:Spawn() + local EscortGroupGround = SpawnEscortGround:ReSpawn(1) local EscortGround = ESCORT:New( Client, EscortGroupGround, "Test Ground" ) - local SpawnEscortShip = SPAWN:New( "Escort Ship" ) - local EscortGroupShip = SpawnEscortShip:Spawn() + local EscortGroupShip = SpawnEscortShip:ReSpawn(1) local EscortShip = ESCORT:New( Client, EscortGroupShip, "Test Ship" ) end - local EscortClientHeli = CLIENT:New( "Lead Helicopter", "Fly around and observe the behaviour of the escort helicopter" ):Alive( EventAliveHelicopter ) - local EscortClientPlane = CLIENT:New( "Lead Plane", "Fly around and observe the behaviour of the escort airplane. Select Navigate->Joun-Up and airplane should follow you. Change speed and directions." ) + SpawnEscortHeli = SPAWN:New( "Escort Helicopter" ) + SpawnEscortPlane = SPAWN:New( "Escort Plane" ) + SpawnEscortGround = SPAWN:New( "Escort Ground" ) + SpawnEscortShip = SPAWN:New( "Escort Ship" ) + + EscortClientHeli = CLIENT:New( "Lead Helicopter", "Fly around and observe the behaviour of the escort helicopter" ):Alive( EventAliveHelicopter ) + EscortClientPlane = CLIENT:New( "Lead Plane", "Fly around and observe the behaviour of the escort airplane. Select Navigate->Joun-Up and airplane should follow you. Change speed and directions." ) :Alive( EventAlivePlane ) end diff --git a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz index d8593f8d4..b644553bd 100644 Binary files a/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz and b/Test Missions/Moose_Test_ESCORT/MOOSE_Test_ESCORT.miz differ