From b522b38d31e5e4c0373cd83a9a644bc3806a8141 Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Fri, 17 Jan 2025 09:21:48 +0100 Subject: [PATCH 1/3] #SCENERY - Some fixes for kissing getLife function on some objects, and life points being zero on some objects --- Moose Development/Moose/Wrapper/Scenery.lua | 25 ++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/Moose Development/Moose/Wrapper/Scenery.lua b/Moose Development/Moose/Wrapper/Scenery.lua index 2706aad71..eb69e7ab4 100644 --- a/Moose Development/Moose/Wrapper/Scenery.lua +++ b/Moose Development/Moose/Wrapper/Scenery.lua @@ -48,8 +48,8 @@ function SCENERY:Register( SceneryName, SceneryObject ) self.SceneryObject = SceneryObject - if self.SceneryObject then - self.Life0 = self.SceneryObject:getLife() + if self.SceneryObject and self.SceneryObject.getLife then -- fix some objects do not have all functions + self.Life0 = self.SceneryObject:getLife() or 0 else self.Life0 = 0 end @@ -59,7 +59,7 @@ function SCENERY:Register( SceneryName, SceneryObject ) return self end ---- Returns the Value of the zone with the given PropertyName, or nil if no matching property exists. +--- Returns the value of the scenery with the given PropertyName, or nil if no matching property exists. -- @param #SCENERY self -- @param #string PropertyName The name of a the QuadZone Property from the scenery assignment to be retrieved. -- @return #string The Value of the QuadZone Property from the scenery assignment with the given PropertyName, or nil if absent. @@ -67,6 +67,14 @@ function SCENERY:GetProperty(PropertyName) return self.Properties[PropertyName] end +--- Checks if the value of the scenery with the given PropertyName exists. +-- @param #SCENERY self +-- @param #string PropertyName The name of a the QuadZone Property from the scenery assignment to be retrieved. +-- @return #boolean Outcome True if it exists, else false. +function SCENERY:HasProperty(PropertyName) + return self.Properties[PropertyName] ~= nil and true or false +end + --- Returns the scenery Properties table. -- @param #SCENERY self -- @return #table The Key:Value table of QuadZone properties of the zone from the scenery assignment . @@ -97,7 +105,7 @@ function SCENERY:GetDCSObject() return self.SceneryObject end ---- Get current life points from the SCENERY Object. +--- Get current life points from the SCENERY Object. Note - Some scenery objects always have 0 life points. -- **CAVEAT**: Some objects change their life value or "hitpoints" **after** the first hit. Hence we will adjust the life0 value to 120% -- of the last life value if life exceeds life0 (initial life) at any point. Thus will will get a smooth percentage decrease, if you use this e.g. as success -- criteria for a bombing task. @@ -105,7 +113,7 @@ end --@return #number life function SCENERY:GetLife() local life = 0 - if self.SceneryObject then + if self.SceneryObject and self.SceneryObject.getLife then life = self.SceneryObject:getLife() if life > self.Life0 then self.Life0 = math.floor(life * 1.2) @@ -121,7 +129,7 @@ function SCENERY:GetLife0() return self.Life0 or 0 end ---- Check if SCENERY Object is alive. +--- Check if SCENERY Object is alive. Note - Some scenery objects always have 0 life points. --@param #SCENERY self --@param #number Threshold (Optional) If given, SCENERY counts as alive above this relative life in percent (1..100). --@return #number life @@ -133,7 +141,7 @@ function SCENERY:IsAlive(Threshold) end end ---- Check if SCENERY Object is dead. +--- Check if SCENERY Object is dead. Note - Some scenery objects always have 0 life points. --@param #SCENERY self --@param #number Threshold (Optional) If given, SCENERY counts as dead below this relative life in percent (1..100). --@return #number life @@ -145,12 +153,13 @@ function SCENERY:IsDead(Threshold) end end ---- Get SCENERY relative life in percent, e.g. 75. +--- Get SCENERY relative life in percent, e.g. 75. Note - Some scenery objects always have 0 life points. --@param #SCENERY self --@return #number rlife function SCENERY:GetRelativeLife() local life = self:GetLife() local life0 = self:GetLife0() + if life == 0 or life0 == 0 then return 0 end local rlife = math.floor((life/life0)*100) return rlife end From 7f7999e3e5264800fc8cf1e07c0d05aa4a8ec53b Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Fri, 17 Jan 2025 09:54:41 +0100 Subject: [PATCH 2/3] #CSAR - Make the list of downed pilots' coordinate dependent on _SETTINGS global or pilot --- Moose Development/Moose/Ops/CSAR.lua | 35 ++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/Ops/CSAR.lua b/Moose Development/Moose/Ops/CSAR.lua index 8cc55125c..e7805f25a 100644 --- a/Moose Development/Moose/Ops/CSAR.lua +++ b/Moose Development/Moose/Ops/CSAR.lua @@ -809,6 +809,8 @@ end -- @param #boolean noMessage -- @param #string _description Description -- @param #boolean forcedesc Use the description only for the pilot track entry +-- @return Wrapper.Group#GROUP PilotInField Pilot GROUP object +-- @return #string AliasName Alias display name function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description, forcedesc ) self:T(self.lid .. " _AddCsar") self:T({_coalition , _country, _point, _typeName, _unitName, _playerName, _freq, noMessage, _description}) @@ -878,7 +880,7 @@ function CSAR:_AddCsar(_coalition , _country, _point, _typeName, _unitName, _pla self:_InitSARForPilot(_spawnedGroup, _unitName, _freq, noMessage, _playerName) --shagrat use unitName to have the aircraft callsign / descriptive "name" etc. - return self + return _spawnedGroup, _alias end --- (Internal) Function to add a CSAR object into the scene at a zone coordinate. For mission designers wanting to add e.g. PoWs to the scene. @@ -1829,8 +1831,9 @@ end --- (Internal) Function to get string of a group\'s position. -- @param #CSAR self -- @param Wrapper.Controllable#CONTROLLABLE _woundedGroup Group or Unit object. +-- @param Wrapper.Unit#UNIT _Unit Requesting helo pilot unit -- @return #string Coordinates as Text -function CSAR:_GetPositionOfWounded(_woundedGroup) +function CSAR:_GetPositionOfWounded(_woundedGroup,_Unit) self:T(self.lid .. " _GetPositionOfWounded") local _coordinate = _woundedGroup:GetCoordinate() local _coordinatesText = "None" @@ -1845,6 +1848,26 @@ function CSAR:_GetPositionOfWounded(_woundedGroup) _coordinatesText = _coordinate:ToStringBULLS(self.coalition) end end + if _Unit and _Unit:GetPlayerName() then + local playername = _Unit:GetPlayerName() + if playername then + local settings = _DATABASE:GetPlayerSettings(playername) or _SETTINGS + if settings then + self:T("Get Settings ok!") + if settings:IsA2G_MGRS() then + _coordinatesText = _coordinate:ToStringMGRS(settings) + elseif settings:IsA2G_LL_DMS() then + _coordinatesText = _coordinate:ToStringLLDMS(settings) + elseif settings:IsA2G_LL_DDM() then + _coordinatesText = _coordinate:ToStringLLDDM(settings) + elseif settings:IsA2G_BR() then + -- attention this is the distance from the ASKING unit to target, not from RECCE to target! + local startcoordinate = _Unit:GetCoordinate() + _coordinatesText = _coordinate:ToStringBR(startcoordinate,settings) + end + end + end + end return _coordinatesText end @@ -1870,13 +1893,17 @@ function CSAR:_DisplayActiveSAR(_unitName) self:T({Table=_value}) local _woundedGroup = _value.group if _woundedGroup and _value.alive then - local _coordinatesText = self:_GetPositionOfWounded(_woundedGroup) + local _coordinatesText = self:_GetPositionOfWounded(_woundedGroup,_heli) local _helicoord = _heli:GetCoordinate() local _woundcoord = _woundedGroup:GetCoordinate() local _distance = self:_GetDistance(_helicoord, _woundcoord) self:T({_distance = _distance}) local distancetext = "" - if _SETTINGS:IsImperial() then + local settings = _SETTINGS + if _heli:GetPlayerName() then + settings = _DATABASE:GetPlayerSettings(_heli:GetPlayerName()) or _SETTINGS + end + if settings:IsImperial() then distancetext = string.format("%.1fnm",UTILS.MetersToNM(_distance)) else distancetext = string.format("%.1fkm", _distance/1000.0) From 61b7b3ead66cf4416dbb8d4a3e599740ed9f529e Mon Sep 17 00:00:00 2001 From: Applevangelist Date: Sat, 18 Jan 2025 15:30:03 +0100 Subject: [PATCH 3/3] Smaller fixes --- Moose Development/Moose/Functional/Fox.lua | 2 +- Moose Development/Moose/Wrapper/Group.lua | 8 ++++++-- Moose Development/Moose/Wrapper/Positionable.lua | 9 ++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/Moose Development/Moose/Functional/Fox.lua b/Moose Development/Moose/Functional/Fox.lua index 5ca6d4e51..38d8eb585 100644 --- a/Moose Development/Moose/Functional/Fox.lua +++ b/Moose Development/Moose/Functional/Fox.lua @@ -1060,7 +1060,7 @@ function FOX:onafterMissileLaunch(From, Event, To, missile) -- Tracking info and init of last bomb position. local text=string.format("FOX: Tracking missile %s(%s) - target %s - shooter %s", missile.missileType, missile.missileName, tostring(missile.targetName), missile.shooterName) - self:I(FOX.lid..text) + self:T(FOX.lid..text) MESSAGE:New(text, 10):ToAllIf(self.Debug) -- Loop over players. diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 3760a84fc..ef0561f84 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -3003,7 +3003,7 @@ end -- local callsign = mygroup:GetCustomCallSign(true,false,nil,function(groupname,playername) return string.match(playername,"([%a]+)$") end) -- function GROUP:GetCustomCallSign(ShortCallsign,Keepnumber,CallsignTranslations,CustomFunction,...) - --self:I("GetCustomCallSign") + self:T("GetCustomCallSign") local callsign = "Ghost 1" if self:IsAlive() then @@ -3016,8 +3016,12 @@ function GROUP:GetCustomCallSign(ShortCallsign,Keepnumber,CallsignTranslations,C local callnumbermajor = string.char(string.byte(callnumber,1)) -- 9 local callnumberminor = string.char(string.byte(callnumber,2)) -- 1 local personalized = false - local playername = IsPlayer == true and self:GetPlayerName() or shortcallsign + --local playername = IsPlayer == true and self:GetPlayerName() or shortcallsign + local playername = shortcallsign + if IsPlayer then playername = self:GetPlayerName() end + + self:T2("GetCustomCallSign outcome = "..playername) if CustomFunction and IsPlayer then local arguments = arg or {} local callsign = CustomFunction(groupname,playername,unpack(arguments)) diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index 9d8c77873..df5fdcb37 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -110,14 +110,17 @@ function POSITIONABLE:Destroy( GenerateEvent ) if GenerateEvent and GenerateEvent == true then if self:IsAir() then + --self:ScheduleOnce(1,self.CreateEventCrash,self,timer.getTime(),DCSObject) self:CreateEventCrash( timer.getTime(), DCSObject ) else + --self:ScheduleOnce(1,self.CreateEventDead,self,timer.getTime(),DCSObject) self:CreateEventDead( timer.getTime(), DCSObject ) end elseif GenerateEvent == false then -- Do nothing! else self:CreateEventRemoveUnit( timer.getTime(), DCSObject ) + --self:ScheduleOnce(1,self.CreateEventRemoveUnit,self,timer.getTime(),DCSObject) end USERFLAG:New( UnitGroupName ):Set( 100 ) @@ -142,7 +145,11 @@ function POSITIONABLE:GetPosition() self:F2( self.PositionableName ) local DCSPositionable = self:GetDCSObject() - + + if self:IsInstanceOf("GROUP") then + DCSPositionable = self:GetFirstUnitAlive():GetDCSObject() + end + if DCSPositionable then local PositionablePosition = DCSPositionable:getPosition() self:T3( PositionablePosition )