From 8a21fe80def6165d2504307b5b8436768743e882 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Fri, 12 Jul 2024 19:32:55 +0200 Subject: [PATCH 1/4] #CONTROLLABLE - Added combat and direction options in CONTROLLABLE:TaskLandAtVec2( Vec2, Duration , CombatLanding, DirectionAfterLand) --- .../Moose/Wrapper/Controllable.lua | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 2817147e4..365a201d6 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -58,7 +58,7 @@ -- * @{#CONTROLLABLE.TaskFollow}: (AIR) Following another airborne controllable. -- * @{#CONTROLLABLE.TaskHold}: (GROUND) Hold ground controllable from moving. -- * @{#CONTROLLABLE.TaskHoldPosition}: (AIR) Hold position at the current position of the first unit of the controllable. --- * @{#CONTROLLABLE.TaskLand}: (AIR HELICOPTER) Landing at the ground. For helicopters only. +-- * @{#CONTROLLABLE.TaskLandAtVec2}: (AIR HELICOPTER) Landing at the ground. For helicopters only. -- * @{#CONTROLLABLE.TaskLandAtZone}: (AIR) Land the controllable at a @{Core.Zone#ZONE_RADIUS). -- * @{#CONTROLLABLE.TaskOrbitCircle}: (AIR) Orbit at the current position of the first unit of the controllable at a specified altitude. -- * @{#CONTROLLABLE.TaskOrbitCircleAtVec2}: (AIR) Orbit at a specified position at a specified altitude during a specified duration with a specified speed. @@ -1516,8 +1516,10 @@ end -- @param #CONTROLLABLE self -- @param DCS#Vec2 Vec2 The point where to land. -- @param #number Duration The duration in seconds to stay on the ground. +-- @param #boolean CombatLanding (optional) If true, set the Combat Landing option. +-- @param #number DirectionAfterLand (optional) Heading after landing in degrees. -- @return #CONTROLLABLE self -function CONTROLLABLE:TaskLandAtVec2( Vec2, Duration ) +function CONTROLLABLE:TaskLandAtVec2( Vec2, Duration , CombatLanding, DirectionAfterLand) local DCSTask = { id = 'Land', @@ -1525,9 +1527,15 @@ function CONTROLLABLE:TaskLandAtVec2( Vec2, Duration ) point = Vec2, durationFlag = Duration and true or false, duration = Duration, + combatLandingFlag = CombatLanding == true and true or false, }, } - + + if DirectionAfterLand ~= nil and type(DirectionAfterLand) == "number" then + DCSTask.params.directionEnabled = true + DCSTask.params.direction = math.rad(DirectionAfterLand) + end + return DCSTask end @@ -1535,13 +1543,16 @@ end -- @param #CONTROLLABLE self -- @param Core.Zone#ZONE Zone The zone where to land. -- @param #number Duration The duration in seconds to stay on the ground. +-- @param #boolean RandomPoint (optional) If true,land at a random point inside of the zone. +-- @param #boolean CombatLanding (optional) If true, set the Combat Landing option. +-- @param #number DirectionAfterLand (optional) Heading after landing in degrees. -- @return DCS#Task The DCS task structure. -function CONTROLLABLE:TaskLandAtZone( Zone, Duration, RandomPoint ) +function CONTROLLABLE:TaskLandAtZone( Zone, Duration, RandomPoint, CombatLanding, DirectionAfterLand ) -- Get landing point local Point = RandomPoint and Zone:GetRandomVec2() or Zone:GetVec2() - local DCSTask = CONTROLLABLE.TaskLandAtVec2( self, Point, Duration ) + local DCSTask = CONTROLLABLE.TaskLandAtVec2( self, Point, Duration, CombatLanding, DirectionAfterLand) return DCSTask end From 0b21cb687e39a1c8e4aa2ed3a5dd65f82f8b0379 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sat, 13 Jul 2024 15:21:35 +0200 Subject: [PATCH 2/4] Various fixes --- Moose Development/Moose/Core/Database.lua | 11 ++++---- Moose Development/Moose/Core/Event.lua | 29 +++++++++++---------- Moose Development/Moose/Core/Point.lua | 4 +-- Moose Development/Moose/Core/Set.lua | 4 +++ Moose Development/Moose/Core/Spawn.lua | 19 +++++++++----- Moose Development/Moose/Wrapper/Storage.lua | 22 +++++++++------- 6 files changed, 53 insertions(+), 36 deletions(-) diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index dec6bd64c..b4931a644 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -135,7 +135,7 @@ function DATABASE:New() self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) - --self:HandleEvent( EVENTS.UnitLost, self._EventOnDeadOrCrash ) -- DCS 2.7.1 for Aerial units no dead event ATM + self:HandleEvent( EVENTS.UnitLost, self._EventOnDeadOrCrash ) -- DCS 2.7.1 for Aerial units no dead event ATM self:HandleEvent( EVENTS.Hit, self.AccountHits ) self:HandleEvent( EVENTS.NewCargo ) self:HandleEvent( EVENTS.DeleteCargo ) @@ -188,6 +188,7 @@ end --- Deletes a Unit from the DATABASE based on the Unit Name. -- @param #DATABASE self function DATABASE:DeleteUnit( DCSUnitName ) + self:T("DeleteUnit "..tostring(DCSUnitName)) self.UNITS[DCSUnitName] = nil end @@ -1569,7 +1570,6 @@ end -- @param #DATABASE self -- @param Core.Event#EVENTDATA Event function DATABASE:_EventOnDeadOrCrash( Event ) - if Event.IniDCSUnit then local name=Event.IniDCSUnitName @@ -1577,7 +1577,7 @@ function DATABASE:_EventOnDeadOrCrash( Event ) if Event.IniObjectCategory == 3 then --- - -- STATICS + -- STATICS --- if self.STATICS[Event.IniDCSUnitName] then @@ -1587,7 +1587,7 @@ function DATABASE:_EventOnDeadOrCrash( Event ) --- -- Maybe a UNIT? --- - + -- Delete unit. if self.UNITS[Event.IniDCSUnitName] then self:T("STATIC Event for UNIT "..tostring(Event.IniDCSUnitName)) @@ -1610,7 +1610,8 @@ function DATABASE:_EventOnDeadOrCrash( Event ) -- Delete unit. if self.UNITS[Event.IniDCSUnitName] then - self:DeleteUnit(Event.IniDCSUnitName) + self:ScheduleOnce(1,self.DeleteUnit,self,Event.IniDCSUnitName) + --self:DeleteUnit(Event.IniDCSUnitName) end -- Remove client players. diff --git a/Moose Development/Moose/Core/Event.lua b/Moose Development/Moose/Core/Event.lua index b6bbe84a4..6df0cd70e 100644 --- a/Moose Development/Moose/Core/Event.lua +++ b/Moose Development/Moose/Core/Event.lua @@ -262,9 +262,10 @@ EVENTS = { WeaponRearm = world.event.S_EVENT_WEAPON_REARM or -1, WeaponDrop = world.event.S_EVENT_WEAPON_DROP or -1, -- Added with DCS 2.9.x - UnitTaskTimeout = world.event.S_EVENT_UNIT_TASK_TIMEOUT or -1, + --UnitTaskTimeout = world.event.S_EVENT_UNIT_TASK_TIMEOUT or -1, + UnitTaskComplete = world.event.S_EVENT_UNIT_TASK_COMPLETE or -1, UnitTaskStage = world.event.S_EVENT_UNIT_TASK_STAGE or -1, - MacSubtaskScore = world.event.S_EVENT_MAC_SUBTASK_SCORE or -1, + --MacSubtaskScore = world.event.S_EVENT_MAC_SUBTASK_SCORE or -1, MacExtraScore = world.event.S_EVENT_MAC_EXTRA_SCORE or -1, MissionRestart = world.event.S_EVENT_MISSION_RESTART or -1, MissionWinner = world.event.S_EVENT_MISSION_WINNER or -1, @@ -652,24 +653,24 @@ local _EVENTMETA = { Text = "S_EVENT_WEAPON_DROP" }, -- DCS 2.9 - [EVENTS.UnitTaskTimeout] = { - Order = 1, - Side = "I", - Event = "OnEventUnitTaskTimeout", - Text = "S_EVENT_UNIT_TASK_TIMEOUT " - }, + --[EVENTS.UnitTaskTimeout] = { + -- Order = 1, + -- Side = "I", + -- Event = "OnEventUnitTaskTimeout", + -- Text = "S_EVENT_UNIT_TASK_TIMEOUT " + --}, [EVENTS.UnitTaskStage] = { Order = 1, Side = "I", Event = "OnEventUnitTaskStage", Text = "S_EVENT_UNIT_TASK_STAGE " }, - [EVENTS.MacSubtaskScore] = { - Order = 1, - Side = "I", - Event = "OnEventMacSubtaskScore", - Text = "S_EVENT_MAC_SUBTASK_SCORE" - }, + --[EVENTS.MacSubtaskScore] = { + -- Order = 1, + --Side = "I", + --Event = "OnEventMacSubtaskScore", + --Text = "S_EVENT_MAC_SUBTASK_SCORE" + --}, [EVENTS.MacExtraScore] = { Order = 1, Side = "I", diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index 875d71ce8..c5272252e 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -3414,7 +3414,7 @@ do -- COORDINATE -- @param #COORDINATE self -- @param #number Radius (Optional) Radius to check around the coordinate, defaults to 50m (100m diameter) -- @param #number Minelevation (Optional) Elevation from which on a area is defined as steep, defaults to 8% (8m height gain across 100 meters) - -- @return #boolen IsSteep If true, area is steep + -- @return #boolean IsSteep If true, area is steep -- @return #number MaxElevation Elevation in meters measured over 100m function COORDINATE:IsInSteepArea(Radius,Minelevation) local steep = false @@ -3446,7 +3446,7 @@ do -- COORDINATE -- @param #COORDINATE self -- @param #number Radius (Optional) Radius to check around the coordinate, defaults to 50m (100m diameter) -- @param #number Minelevation (Optional) Elevation from which on a area is defined as steep, defaults to 8% (8m height gain across 100 meters) - -- @return #boolen IsFlat If true, area is flat + -- @return #boolean IsFlat If true, area is flat -- @return #number MaxElevation Elevation in meters measured over 100m function COORDINATE:IsInFlatArea(Radius,Minelevation) local steep, elev = self:IsInSteepArea(Radius,Minelevation) diff --git a/Moose Development/Moose/Core/Set.lua b/Moose Development/Moose/Core/Set.lua index ca82b1ada..798f4c4cd 100644 --- a/Moose Development/Moose/Core/Set.lua +++ b/Moose Development/Moose/Core/Set.lua @@ -1516,6 +1516,7 @@ do self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) + self:HandleEvent( EVENTS.UnitLost, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.PlayerLeaveUnit, self._EventOnDeadOrCrash ) if self.Filter.Zones then self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) @@ -1548,6 +1549,7 @@ do self:UnHandleEvent(EVENTS.Dead) self:UnHandleEvent(EVENTS.Crash) self:UnHandleEvent(EVENTS.RemoveUnit) + self:UnHandleEvent(EVENTS.UnitLost) if self.Filter.Zones and self.ZoneTimer and self.ZoneTimer:IsRunning() then self.ZoneTimer:Stop() @@ -2622,6 +2624,7 @@ do -- SET_UNIT self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) + self:HandleEvent( EVENTS.UnitLost, self._EventOnDeadOrCrash ) if self.Filter.Zones then self.ZoneTimer = TIMER:New(self._ContinousZoneFilter,self) local timing = self.ZoneTimerInterval or 30 @@ -7845,6 +7848,7 @@ do -- SET_OPSGROUP self:HandleEvent( EVENTS.Dead, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._EventOnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._EventOnDeadOrCrash ) + self:HandleEvent( EVENTS.UnitLost, self._EventOnDeadOrCrash ) end return self diff --git a/Moose Development/Moose/Core/Spawn.lua b/Moose Development/Moose/Core/Spawn.lua index 75664cee9..ad430a33a 100644 --- a/Moose Development/Moose/Core/Spawn.lua +++ b/Moose Development/Moose/Core/Spawn.lua @@ -1238,7 +1238,7 @@ function SPAWN:InitPositionVec2(Vec2) self:T( { self.SpawnTemplatePrefix, Vec2} ) self.SpawnInitPosition = Vec2 self.SpawnFromNewPosition = true - self:I("MaxGroups:"..self.SpawnMaxGroups) + self:T("MaxGroups:"..self.SpawnMaxGroups) for SpawnGroupID = 1, self.SpawnMaxGroups do self:_SetInitialPosition( SpawnGroupID ) end @@ -1390,9 +1390,10 @@ function SPAWN:InitArray( SpawnAngle, SpawnWidth, SpawnDeltaX, SpawnDeltaY ) self.SpawnGroups[SpawnGroupID].Visible = true self:HandleEvent( EVENTS.Birth, self._OnBirth ) - self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash ) + --self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._OnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._OnDeadOrCrash ) + self:HandleEvent( EVENTS.UnitLost, self._OnDeadOrCrash ) if self.Repeat then self:HandleEvent( EVENTS.Takeoff, self._OnTakeOff ) self:HandleEvent( EVENTS.Land, self._OnLand ) @@ -1797,8 +1798,9 @@ function SPAWN:SpawnWithIndex( SpawnIndex, NoBirth ) if not NoBirth then self:HandleEvent( EVENTS.Birth, self._OnBirth ) end - self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash ) + --self:HandleEvent( EVENTS.Dead, self._OnDeadOrCrash ) self:HandleEvent( EVENTS.Crash, self._OnDeadOrCrash ) + self:HandleEvent( EVENTS.UnitLost, self._OnDeadOrCrash ) self:HandleEvent( EVENTS.RemoveUnit, self._OnDeadOrCrash ) if self.Repeat then self:HandleEvent( EVENTS.Takeoff, self._OnTakeOff ) @@ -3853,11 +3855,11 @@ end -- @param #number SpawnIndex Spawn index. -- @return #number self.SpawnIndex function SPAWN:_GetSpawnIndex( SpawnIndex ) - self:F2( { self.SpawnTemplatePrefix, SpawnIndex, self.SpawnMaxGroups, self.SpawnMaxUnitsAlive, self.AliveUnits, #self.SpawnTemplate.units } ) + self:T( { template=self.SpawnTemplatePrefix, SpawnIndex=SpawnIndex, SpawnMaxGroups=self.SpawnMaxGroups, SpawnMaxUnitsAlive=self.SpawnMaxUnitsAlive, AliveUnits=self.AliveUnits, TemplateUnits=#self.SpawnTemplate.units } ) if (self.SpawnMaxGroups == 0) or (SpawnIndex <= self.SpawnMaxGroups) then if (self.SpawnMaxUnitsAlive == 0) or (self.AliveUnits + #self.SpawnTemplate.units <= self.SpawnMaxUnitsAlive) or self.UnControlled == true then - self:F( { SpawnCount = self.SpawnCount, SpawnIndex = SpawnIndex } ) + self:T( { SpawnCount = self.SpawnCount, SpawnIndex = SpawnIndex } ) if SpawnIndex and SpawnIndex >= self.SpawnCount + 1 then self.SpawnCount = self.SpawnCount + 1 SpawnIndex = self.SpawnCount @@ -3898,12 +3900,17 @@ function SPAWN:_OnBirth( EventData ) end +--- -- @param #SPAWN self -- @param Core.Event#EVENTDATA EventData function SPAWN:_OnDeadOrCrash( EventData ) - self:F( self.SpawnTemplatePrefix ) + self:T( "Dead or crash event ID "..EventData.id) + self:T( "Dead or crash event for "..self.SpawnTemplatePrefix ) + + if EventData.id == EVENTS.Dead then return end local unit=UNIT:FindByName(EventData.IniUnitName) + --local group=GROUP:FindByName(EventData.IniGroupName) if unit then diff --git a/Moose Development/Moose/Wrapper/Storage.lua b/Moose Development/Moose/Wrapper/Storage.lua index 04210136a..8e45df179 100644 --- a/Moose Development/Moose/Wrapper/Storage.lua +++ b/Moose Development/Moose/Wrapper/Storage.lua @@ -124,6 +124,10 @@ -- UTILS.PrintTableToLog(liquids) -- UTILS.PrintTableToLog(weapons) -- +-- # Weapons Helper Enumerater +-- +-- The currently available weapon items are available in the `ENUMS.Storage.weapons`, e.g. `ENUMS.Storage.weapons.bombs.Mk_82Y`. +-- -- @field #STORAGE STORAGE = { ClassName = "STORAGE", @@ -406,7 +410,7 @@ end --- Returns whether a given type of aircraft, liquid, weapon is set to be unlimited. -- @param #STORAGE self -- @param #string Type Name of aircraft, weapon or equipment or type of liquid (as `#number`). --- @return #boolen If `true` the given type is unlimited or `false` otherwise. +-- @return #boolean If `true` the given type is unlimited or `false` otherwise. function STORAGE:IsUnlimited(Type) -- Get current amount of type. @@ -423,7 +427,7 @@ function STORAGE:IsUnlimited(Type) local n=self:GetAmount(Type) -- If amount did not change, it is unlimited. - unlimited=n==N + unlimited=unlimited or n > 2^29 or n==N -- Add item back. if not unlimited then @@ -440,7 +444,7 @@ end --- Returns whether a given type of aircraft, liquid, weapon is set to be limited. -- @param #STORAGE self -- @param #number Type Type of liquid or name of aircraft, weapon or equipment. --- @return #boolen If `true` the given type is limited or `false` otherwise. +-- @return #boolean If `true` the given type is limited or `false` otherwise. function STORAGE:IsLimited(Type) local limited=not self:IsUnlimited(Type) @@ -450,7 +454,7 @@ end --- Returns whether aircraft are unlimited. -- @param #STORAGE self --- @return #boolen If `true` aircraft are unlimited or `false` otherwise. +-- @return #boolean If `true` aircraft are unlimited or `false` otherwise. function STORAGE:IsUnlimitedAircraft() -- We test with a specific type but if it is unlimited, than all aircraft are. @@ -461,7 +465,7 @@ end --- Returns whether liquids are unlimited. -- @param #STORAGE self --- @return #boolen If `true` liquids are unlimited or `false` otherwise. +-- @return #boolean If `true` liquids are unlimited or `false` otherwise. function STORAGE:IsUnlimitedLiquids() -- We test with a specific type but if it is unlimited, than all are. @@ -472,7 +476,7 @@ end --- Returns whether weapons and equipment are unlimited. -- @param #STORAGE self --- @return #boolen If `true` weapons and equipment are unlimited or `false` otherwise. +-- @return #boolean If `true` weapons and equipment are unlimited or `false` otherwise. function STORAGE:IsUnlimitedWeapons() -- We test with a specific type but if it is unlimited, than all are. @@ -483,7 +487,7 @@ end --- Returns whether aircraft are limited. -- @param #STORAGE self --- @return #boolen If `true` aircraft are limited or `false` otherwise. +-- @return #boolean If `true` aircraft are limited or `false` otherwise. function STORAGE:IsLimitedAircraft() -- We test with a specific type but if it is limited, than all are. @@ -494,7 +498,7 @@ end --- Returns whether liquids are limited. -- @param #STORAGE self --- @return #boolen If `true` liquids are limited or `false` otherwise. +-- @return #boolean If `true` liquids are limited or `false` otherwise. function STORAGE:IsLimitedLiquids() -- We test with a specific type but if it is limited, than all are. @@ -505,7 +509,7 @@ end --- Returns whether weapons and equipment are limited. -- @param #STORAGE self --- @return #boolen If `true` liquids are limited or `false` otherwise. +-- @return #boolean If `true` liquids are limited or `false` otherwise. function STORAGE:IsLimitedWeapons() -- We test with a specific type but if it is limited, than all are. From 3595afe0cc4017e3b807e694edaebffdcbcb7457 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 14 Jul 2024 17:49:25 +0200 Subject: [PATCH 3/4] #DATABASE- stage 1 fix for dynamic client slots --- Moose Development/Moose/Core/Database.lua | 77 ++++++++++++++++++----- Moose Development/Moose/Core/Settings.lua | 2 +- 2 files changed, 63 insertions(+), 16 deletions(-) diff --git a/Moose Development/Moose/Core/Database.lua b/Moose Development/Moose/Core/Database.lua index b4931a644..e79dea2df 100644 --- a/Moose Development/Moose/Core/Database.lua +++ b/Moose Development/Moose/Core/Database.lua @@ -170,10 +170,11 @@ end --- Adds a Unit based on the Unit Name in the DATABASE. -- @param #DATABASE self -- @param #string DCSUnitName Unit name. +-- @param #boolean force -- @return Wrapper.Unit#UNIT The added unit. -function DATABASE:AddUnit( DCSUnitName ) +function DATABASE:AddUnit( DCSUnitName, force ) - if not self.UNITS[DCSUnitName] then + if not self.UNITS[DCSUnitName] or force == true then -- Debug info. self:T( { "Add UNIT:", DCSUnitName } ) @@ -832,15 +833,25 @@ end function DATABASE:FindGroup( GroupName ) local GroupFound = self.GROUPS[GroupName] + + if GroupFound == nil and GroupName ~= nil then + -- see if the group exists in the API, maybe a dynamic slot + self:_RegisterDynamicGroup(GroupName) + return self.GROUPS[GroupName] + end + return GroupFound end --- Adds a GROUP based on the GroupName in the DATABASE. -- @param #DATABASE self -function DATABASE:AddGroup( GroupName ) +-- @param #string GroupName +-- @param #boolean force +-- @return Wrapper.Group#GROUP The Group +function DATABASE:AddGroup( GroupName, force ) - if not self.GROUPS[GroupName] then + if not self.GROUPS[GroupName] or force == true then self:T( { "Add GROUP:", GroupName } ) self.GROUPS[GroupName] = GROUP:Register( GroupName ) end @@ -1346,6 +1357,36 @@ function DATABASE:_RegisterPlayers() return self end +--- Private method that registers a single dynamic slot Group and Units within in the mission. +-- @param #DATABASE self +-- @return #DATABASE self +function DATABASE:_RegisterDynamicGroup(Groupname) + local DCSGroup = Group.getByName(Groupname) + if DCSGroup:isExist() then + + -- Group name. + local DCSGroupName = DCSGroup:getName() + + -- Add group. + self:I(string.format("Register Group: %s", tostring(DCSGroupName))) + self:AddGroup( DCSGroupName, true ) + + -- Loop over units in group. + for DCSUnitId, DCSUnit in pairs( DCSGroup:getUnits() ) do + + -- Get unit name. + local DCSUnitName = DCSUnit:getName() + + -- Add unit. + self:I(string.format("Register Unit: %s", tostring(DCSUnitName))) + self:AddUnit( DCSUnitName, true ) + + end + else + self:E({"Group does not exist: ", DCSGroup}) + end + return self +end --- Private method that registers all Groups and Units within in the mission. -- @param #DATABASE self @@ -1518,9 +1559,9 @@ function DATABASE:_EventOnBirth( Event ) end if Event.IniObjectCategory == Object.Category.UNIT then - - Event.IniUnit = self:FindUnit( Event.IniDCSUnitName ) + Event.IniGroup = self:FindGroup( Event.IniDCSGroupName ) + Event.IniUnit = self:FindUnit( Event.IniDCSUnitName ) -- Client local client=self.CLIENTS[Event.IniDCSUnitName] --Wrapper.Client#CLIENT @@ -1536,7 +1577,7 @@ function DATABASE:_EventOnBirth( Event ) -- Debug info. self:I(string.format("Player '%s' joined unit '%s' of group '%s'", tostring(PlayerName), tostring(Event.IniDCSUnitName), tostring(Event.IniDCSGroupName))) - + -- Add client in case it does not exist already. if not client then client=self:AddClient(Event.IniDCSUnitName) @@ -1549,14 +1590,19 @@ function DATABASE:_EventOnBirth( Event ) if not self.PLAYERS[PlayerName] then self:AddPlayer( Event.IniUnitName, PlayerName ) end - - -- Player settings. - local Settings = SETTINGS:Set( PlayerName ) - Settings:SetPlayerMenu(Event.IniUnit) - - -- Create an event. - self:CreateEventPlayerEnterAircraft(Event.IniUnit) - + + local function SetPlayerSettings(self,PlayerName,IniUnit) + -- Player settings. + local Settings = SETTINGS:Set( PlayerName ) + --Settings:SetPlayerMenu(Event.IniUnit) + Settings:SetPlayerMenu(IniUnit) + -- Create an event. + self:CreateEventPlayerEnterAircraft(IniUnit) + --self:CreateEventPlayerEnterAircraft(Event.IniUnit) + end + + self:ScheduleOnce(1,SetPlayerSettings,self,PlayerName,Event.IniUnit) + end end @@ -1719,6 +1765,7 @@ function DATABASE:_EventOnPlayerLeaveUnit( Event ) local client=self.CLIENTS[Event.IniDCSUnitName] --Wrapper.Client#CLIENT if client then client:RemovePlayer(PlayerName) + --self.PLAYERSETTINGS[PlayerName] = nil end end diff --git a/Moose Development/Moose/Core/Settings.lua b/Moose Development/Moose/Core/Settings.lua index 017bfda9b..a7732a169 100644 --- a/Moose Development/Moose/Core/Settings.lua +++ b/Moose Development/Moose/Core/Settings.lua @@ -738,7 +738,7 @@ do -- SETTINGS local PlayerGroup = PlayerUnit:GetGroup() local PlayerName = PlayerUnit:GetPlayerName() - local PlayerNames = PlayerGroup:GetPlayerNames() + --local PlayerNames = PlayerGroup:GetPlayerNames() local PlayerMenu = MENU_GROUP:New( PlayerGroup, 'Settings "' .. PlayerName .. '"' ) From e6aa34186339f05ef42a07358fca3e59d7ba7478 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sun, 14 Jul 2024 18:48:07 +0200 Subject: [PATCH 4/4] Dynamic Slots - fixes for #GROUP, #UNIT, #CSAR and #CTLD --- Moose Development/Moose/Ops/CSAR.lua | 10 +++++----- Moose Development/Moose/Ops/CTLD.lua | 6 +++--- Moose Development/Moose/Wrapper/Group.lua | 5 ++++- Moose Development/Moose/Wrapper/Unit.lua | 9 ++++++++- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 7b716ed5c..fd1eda22b 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -31,7 +31,7 @@ -- @image OPS_CSAR.jpg --- --- Last Update April 2024 +-- Last Update July 2024 ------------------------------------------------------------------------- --- **CSAR** class, extends Core.Base#BASE, Core.Fsm#FSM @@ -296,7 +296,7 @@ CSAR.AircraftType["OH58D"] = 2 --- CSAR class version. -- @field #string version -CSAR.version="1.0.24" +CSAR.version="1.0.25" ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -- ToDo list @@ -2111,12 +2111,12 @@ function CSAR:_AddMedevacMenuItem() local coalition = self.coalition local allheligroupset = self.allheligroupset -- Core.Set#SET_GROUP local _allHeliGroups = allheligroupset:GetSetObjects() - -- rebuild units table local _UnitList = {} for _key, _group in pairs (_allHeliGroups) do - local _unit = _group:GetUnit(1) -- Asume that there is only one unit in the flight for players - if _unit then + local _unit = _group:GetFirstUnitAlive() -- Asume that there is only one unit in the flight for players + if _unit then + --self:T("Unitname ".._unit:GetName().." IsAlive "..tostring(_unit:IsAlive()).." IsPlayer "..tostring(_unit:IsPlayer())) if _unit:IsAlive() and _unit:IsPlayer() then local unitName = _unit:GetName() _UnitList[unitName] = unitName diff --git a/Moose Development/Moose/Ops/CTLD.lua b/Moose Development/Moose/Ops/CTLD.lua index 037446ea4..16a87ca11 100644 --- a/Moose Development/Moose/Ops/CTLD.lua +++ b/Moose Development/Moose/Ops/CTLD.lua @@ -24,7 +24,7 @@ -- @module Ops.CTLD -- @image OPS_CTLD.jpg --- Last Update April 2024 +-- Last Update July 2024 do @@ -1255,7 +1255,7 @@ CTLD.UnitTypeCapabilities = { --- CTLD class version. -- @field #string version -CTLD.version="1.0.54" +CTLD.version="1.0.55" --- Instantiate a new CTLD. -- @param #CTLD self @@ -3670,7 +3670,7 @@ function CTLD:_RefreshF10Menus() -- rebuild units table local _UnitList = {} for _key, _group in pairs (PlayerTable) do - local _unit = _group:GetUnit(1) -- Wrapper.Unit#UNIT Asume that there is only one unit in the flight for players + local _unit = _group:GetFirstUnitAlive() -- Wrapper.Unit#UNIT Asume that there is only one unit in the flight for players if _unit then if _unit:IsAlive() and _unit:IsPlayer() then if _unit:IsHelicopter() or (self:IsHercules(_unit) and self.enableHercules) then --ensure no stupid unit entries here diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 5122d2b9c..633eb5a32 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -359,12 +359,15 @@ end -- @param #GROUP self -- @return DCS#Group The DCS Group. function GROUP:GetDCSObject() + + -- Get DCS group. local DCSGroup = Group.getByName( self.GroupName ) if DCSGroup then return DCSGroup end + self:T2(string.format("ERROR: Could not get DCS group object of group %s because DCS object could not be found!", tostring(self.GroupName))) return nil end @@ -2742,7 +2745,7 @@ do -- Players local PlayerNames = {} local Units = self:GetUnits() - for UnitID, UnitData in pairs( Units ) do + for UnitID, UnitData in pairs( Units or {}) do local Unit = UnitData -- Wrapper.Unit#UNIT local PlayerName = Unit:GetPlayerName() if PlayerName and PlayerName ~= "" then diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 497d9fb1a..c7f3f02be 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -447,7 +447,14 @@ function UNIT:IsPlayer() -- Units of template group. local template = group:GetTemplate() - if (template == nil) or (template.units == nil ) then return false end + if (template == nil) or (template.units == nil ) then + local DCSObject = self:GetDCSObject() + if DCSObject then + if DCSObject:getPlayerName() ~= nil then return true else return false end + else + return false + end + end local units=template.units