From 1bd5193786760a838a9134bc39b639b23005f272 Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 1 Dec 2020 16:10:55 +0100 Subject: [PATCH 1/4] Taskinfo.lua - Issue #1388 - don't just assume this is a string fixes the catchall at the end in case a task is unassigned - sometimes it's not a string. #1388 --- Moose Development/Moose/Tasking/TaskInfo.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Tasking/TaskInfo.lua b/Moose Development/Moose/Tasking/TaskInfo.lua index 5ece5f005..8d825e309 100644 --- a/Moose Development/Moose/Tasking/TaskInfo.lua +++ b/Moose Development/Moose/Tasking/TaskInfo.lua @@ -344,7 +344,9 @@ function TASKINFO:Report( Report, Detail, ReportGroup, Task ) Text = DataText else local DataText = Data.Data -- #string - Text = DataText + if type(DataText) == "string" then --Issue #1388 - don't just assume this is a string + Text = DataText + end end if Line < math.floor( Data.Order / 10 ) then From 82bfb0cc55efc6f01150b21d27ce2f823129305d Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Tue, 1 Dec 2020 19:47:29 +0100 Subject: [PATCH 2/4] Issue ##1383 never ending flash messages Messages appears once and then goes away. --- Moose Development/Moose/Tasking/Task.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua index 7efa0962d..1ed3aee09 100644 --- a/Moose Development/Moose/Tasking/Task.lua +++ b/Moose Development/Moose/Tasking/Task.lua @@ -1252,7 +1252,7 @@ function TASK:MenuFlashTaskStatus( TaskGroup, Flash ) self.FlashTaskStatus = Flash if self.FlashTaskStatus then - self.FlashTaskScheduler, self.FlashTaskScheduleID = SCHEDULER:New( self, self.MenuTaskStatus, { TaskGroup }, 0, 60 ) + self.FlashTaskScheduler, self.FlashTaskScheduleID = SCHEDULER:New( self, self.MenuTaskStatus, { TaskGroup }, 0, 60, 0, 61 ) --Issue #1383 never ending flash messages else if self.FlashTaskScheduler then self.FlashTaskScheduler:Stop( self.FlashTaskScheduleID ) From e165cb156c7e960a7bd0c90d9fee9c093e0b7376 Mon Sep 17 00:00:00 2001 From: Applevangelist <72444570+Applevangelist@users.noreply.github.com> Date: Wed, 2 Dec 2020 17:25:57 +0100 Subject: [PATCH 3/4] Update Task.lua -- stop message flashing, if any #1383 & #1312 --- Moose Development/Moose/Tasking/Task.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Moose Development/Moose/Tasking/Task.lua b/Moose Development/Moose/Tasking/Task.lua index 1ed3aee09..7cd79f453 100644 --- a/Moose Development/Moose/Tasking/Task.lua +++ b/Moose Development/Moose/Tasking/Task.lua @@ -881,6 +881,9 @@ do -- Group Assignment local Mission = self:GetMission() local CommandCenter = Mission:GetCommandCenter() CommandCenter:SetMenu() + + self:MenuFlashTaskStatus( TaskGroup, false ) -- stop message flashing, if any #1383 & #1312 + end end @@ -1252,7 +1255,7 @@ function TASK:MenuFlashTaskStatus( TaskGroup, Flash ) self.FlashTaskStatus = Flash if self.FlashTaskStatus then - self.FlashTaskScheduler, self.FlashTaskScheduleID = SCHEDULER:New( self, self.MenuTaskStatus, { TaskGroup }, 0, 60, 0, 61 ) --Issue #1383 never ending flash messages + self.FlashTaskScheduler, self.FlashTaskScheduleID = SCHEDULER:New( self, self.MenuTaskStatus, { TaskGroup }, 0, 60) --Issue #1383 never ending flash messages else if self.FlashTaskScheduler then self.FlashTaskScheduler:Stop( self.FlashTaskScheduleID ) From 2500cfb3c7ea09cfca91feb24086434f4c311487 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 3 Dec 2020 23:17:40 +0100 Subject: [PATCH 4/4] RANGE v2.3.0 - Performance optimizations --- Moose Development/Moose/Core/Point.lua | 12 +- Moose Development/Moose/Functional/Range.lua | 156 +++++++++--------- .../Moose/Wrapper/Positionable.lua | 11 +- 3 files changed, 90 insertions(+), 89 deletions(-) diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index ca1529950..31669d146 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -770,16 +770,14 @@ do -- COORDINATE -- @param #COORDINATE self -- @param #COORDINATE TargetCoordinate The target COORDINATE. Can also be a DCS#Vec3. -- @return DCS#Distance Distance The distance in meters. - function COORDINATE:Get2DDistance( TargetCoordinate ) + function COORDINATE:Get2DDistance(TargetCoordinate) local a={x=TargetCoordinate.x-self.x, y=0, z=TargetCoordinate.z-self.z} - return UTILS.VecNorm(a) - - --local TargetVec3 = TargetCoordinate:GetVec3() - --local SourceVec3 = self:GetVec3() - - --return ( ( TargetVec3.x - SourceVec3.x ) ^ 2 + ( TargetVec3.z - SourceVec3.z ) ^ 2 ) ^ 0.5 + local d=UTILS.VecNorm(a) + + return d + end --- Returns the temperature in Degrees Celsius. diff --git a/Moose Development/Moose/Functional/Range.lua b/Moose Development/Moose/Functional/Range.lua index 0f4b164fe..fc850743c 100644 --- a/Moose Development/Moose/Functional/Range.lua +++ b/Moose Development/Moose/Functional/Range.lua @@ -53,6 +53,7 @@ -- @type RANGE -- @field #string ClassName Name of the Class. -- @field #boolean Debug If true, debug info is send as messages on the screen. +-- @field #boolean verbose Verbosity level. Higher means more output to DCS log file. -- @field #string id String id of range for output in DCS log. -- @field #string rangename Name of the range. -- @field Core.Point#COORDINATE location Coordinate of the range location. @@ -289,6 +290,7 @@ RANGE={ ClassName = "RANGE", Debug = false, + verbose = 0, id = nil, rangename = nil, location = nil, @@ -518,7 +520,7 @@ RANGE.MenuF10Root=nil --- Range script version. -- @field #string version -RANGE.version="2.2.3" +RANGE.version="2.3.0" --TODO list: --TODO: Verbosity level for messages. @@ -556,7 +558,6 @@ function RANGE:New(rangename) -- Debug info. local text=string.format("Script version %s - creating new RANGE object %s.", RANGE.version, self.rangename) self:I(self.id..text) - MESSAGE:New(text, 10):ToAllIf(self.Debug) -- Defaults self:SetDefaultPlayerSmokeBomb() @@ -723,7 +724,6 @@ function RANGE:onafterStart() -- Starting range. local text=string.format("Starting RANGE %s. Number of strafe targets = %d. Number of bomb targets = %d.", self.rangename, self.nstrafetargets, self.nbombtargets) self:I(self.id..text) - MESSAGE:New(text,10):ToAllIf(self.Debug) -- Event handling. if self.eventmoose then @@ -757,6 +757,7 @@ function RANGE:onafterStart() -- Radio queue. self.rangecontrol=RADIOQUEUE:New(self.rangecontrolfreq, nil, self.rangename) + self.rangecontrol.schedonce=true -- Init numbers. self.rangecontrol:SetDigit(0, RANGE.Sound.RC0.filename, RANGE.Sound.RC0.duration, self.soundpath) @@ -781,7 +782,8 @@ function RANGE:onafterStart() if self.instructorfreq then -- Radio queue. - self.instructor=RADIOQUEUE:New(self.instructorfreq, nil, self.rangename) + self.instructor=RADIOQUEUE:New(self.instructorfreq, nil, self.rangename) + self.instructor.schedonce=true -- Init numbers. self.instructor:SetDigit(0, RANGE.Sound.IR0.filename, RANGE.Sound.IR0.duration, self.soundpath) @@ -1148,7 +1150,6 @@ function RANGE:AddStrafePit(targetnames, boxlength, boxwidth, heading, inversehe -- Neither unit nor static object with this name could be found. local text=string.format("ERROR! Could not find ANY strafe target object with name %s.", _name) self:E(self.id..text) - MESSAGE:New(text, 10):ToAllIf(self.Debug) end @@ -1168,7 +1169,6 @@ function RANGE:AddStrafePit(targetnames, boxlength, boxwidth, heading, inversehe if ntargets==0 then local text=string.format("ERROR! No strafe target could be found when calling RANGE:AddStrafePit() for range %s", self.rangename) self:E(self.id..text) - MESSAGE:New(text, 10):ToAllIf(self.Debug) return end @@ -1238,7 +1238,6 @@ function RANGE:AddStrafePit(targetnames, boxlength, boxwidth, heading, inversehe -- Debug info local text=string.format("Adding new strafe target %s with %d targets: heading = %03d, box_L = %.1f, box_W = %.1f, goodpass = %d, foul line = %.1f", _name, ntargets, heading, l, w, goodpass, foulline) self:T(self.id..text) - MESSAGE:New(text, 5):ToAllIf(self.Debug) return self end @@ -1567,13 +1566,13 @@ function RANGE:OnEventBirth(EventData) -- Debug output. local text=string.format("Player %s, callsign %s entered unit %s (UID %d) of group %s (GID %d)", _playername, _callsign, _unitName, _uid, _group:GetName(), _gid) self:T(self.id..text) - MESSAGE:New(text, 5):ToAllIf(self.Debug) -- Reset current strafe status. self.strafeStatus[_uid] = nil -- Add Menu commands after a delay of 0.1 seconds. - SCHEDULER:New(nil, self._AddF10Commands, {self,_unitName}, 0.1) + --SCHEDULER:New(nil, self._AddF10Commands, {self,_unitName}, 0.1) + self:ScheduleOnce(0.1, self._AddF10Commands, self, _unitName) -- By default, some bomb impact points and do not flare each hit on target. self.PlayerSettings[_playername]={} --#RANGE.PlayerData @@ -1591,7 +1590,8 @@ function RANGE:OnEventBirth(EventData) -- Start check in zone timer. if self.planes[_uid] ~= true then - SCHEDULER:New(nil, self._CheckInZone, {self, EventData.IniUnitName}, 1, 1) + --SCHEDULER:New(nil, self._CheckInZone, {self, EventData.IniUnitName}, 1, 1) + self.timerCheckZone=TIMER:New(self._CheckInZone, self, EventData.IniUnitName):Start(1, 1) self.planes[_uid] = true end @@ -1674,15 +1674,12 @@ function RANGE:OnEventHit(EventData) if _unit and _playername then - -- Position of target. - local targetPos = _target:GetCoordinate() - - -- Message to player. - --local text=string.format("%s, direct hit on target %s.", self:_myname(_unitName), targetname) - --self:DisplayMessageToGroup(_unit, text, 10, true) - -- Flare target. if self.PlayerSettings[_playername].flaredirecthits then + + -- Position of target. + local targetPos = _target:GetCoordinate() + targetPos:Flare(self.PlayerSettings[_playername].flarecolor) end @@ -1724,9 +1721,6 @@ function RANGE:OnEventShot(EventData) self:T(self.id.."EVENT SHOT: Weapon name = ".._weaponName) self:T(self.id.."EVENT SHOT: Weapon cate = "..weaponcategory) - -- Special cases: - --local _viggen=string.match(_weapon, "ROBOT") or string.match(_weapon, "RB75") or string.match(_weapon, "BK90") or string.match(_weapon, "RB15") or string.match(_weapon, "RB04") - -- Tracking conditions for bombs, rockets and missiles. local _bombs = weaponcategory==Weapon.Category.BOMB --string.match(_weapon, "weapons.bombs") local _rockets = weaponcategory==Weapon.Category.ROCKET --string.match(_weapon, "weapons.nurs") @@ -1760,7 +1754,7 @@ function RANGE:OnEventShot(EventData) self:T(self.id..string.format("RANGE %s: Tracking %s - %s.", self.rangename, _weapon, EventData.weapon:getName())) -- Init bomb position. - local _lastBombPos = {x=0,y=0,z=0} + local _lastBombPos = {x=0,y=0,z=0} --DCS#Vec3 -- Function monitoring the position of a bomb until impact. local function trackBomb(_ordnance) @@ -1916,35 +1910,39 @@ end -- @param #string To To state. function RANGE:onafterStatus(From, Event, To) - local fsmstate=self:GetState() - - local text=string.format("Range status: %s", fsmstate) - - if self.instructor then - local alive="N/A" - if self.instructorrelayname then - local relay=UNIT:FindByName(self.instructorrelayname) - if relay then - alive=tostring(relay:IsAlive()) - end - end - text=text..string.format(", Instructor %.3f MHz (Relay=%s alive=%s)", self.instructorfreq, tostring(self.instructorrelayname), alive) - end - - if self.rangecontrol then - local alive="N/A" - if self.rangecontrolrelayname then - local relay=UNIT:FindByName(self.rangecontrolrelayname) - if relay then - alive=tostring(relay:IsAlive()) - end - end - text=text..string.format(", Control %.3f MHz (Relay=%s alive=%s)", self.rangecontrolfreq, tostring(self.rangecontrolrelayname), alive) - end + if self.verbose>0 then - - -- Check range status. - self:I(self.id..text) + local fsmstate=self:GetState() + + local text=string.format("Range status: %s", fsmstate) + + if self.instructor then + local alive="N/A" + if self.instructorrelayname then + local relay=UNIT:FindByName(self.instructorrelayname) + if relay then + alive=tostring(relay:IsAlive()) + end + end + text=text..string.format(", Instructor %.3f MHz (Relay=%s alive=%s)", self.instructorfreq, tostring(self.instructorrelayname), alive) + end + + if self.rangecontrol then + local alive="N/A" + if self.rangecontrolrelayname then + local relay=UNIT:FindByName(self.rangecontrolrelayname) + if relay then + alive=tostring(relay:IsAlive()) + end + end + text=text..string.format(", Control %.3f MHz (Relay=%s alive=%s)", self.rangecontrolfreq, tostring(self.rangecontrolrelayname), alive) + end + + + -- Check range status. + self:I(self.id..text) + + end -- Check player status. self:_CheckPlayers() @@ -2736,6 +2734,32 @@ function RANGE:_CheckInZone(_unitName) if _unit and _playername then + --- Function to check if unit is in zone and facing in the right direction and is below the max alt. + local function checkme(targetheading, _zone) + local zone=_zone --Core.Zone#ZONE + + -- Heading check. + local unitheading = _unit:GetHeading() + local pitheading = targetheading-180 + local deltaheading = unitheading-pitheading + local towardspit = math.abs(deltaheading)<=90 or math.abs(deltaheading-360)<=90 + + if towardspit then + + local vec3=_unit:GetVec3() + local vec2={x=vec3.x, y=vec3.z} --DCS#Vec2 + local landheight=land.getHeight(vec2) + local unitalt=vec3.y-landheight + + if unitalt<=self.strafemaxalt then + local unitinzone=zone:IsVec2InZone(vec2) + return unitinzone + end + end + + return false + end + -- Current position of player unit. local _unitID = _unit:GetID() @@ -2747,18 +2771,8 @@ function RANGE:_CheckInZone(_unitName) -- Get the current approach zone and check if player is inside. local zone=_currentStrafeRun.zone.polygon --Core.Zone#ZONE_POLYGON_BASE - local unitheading = _unit:GetHeading() - local pitheading = _currentStrafeRun.zone.heading - 180 - local deltaheading = unitheading-pitheading - local towardspit = math.abs(deltaheading)<=90 or math.abs(deltaheading-360)<=90 - local unitalt=_unit:GetHeight()-_unit:GetCoordinate():GetLandHeight() - - -- Check if unit is inside zone and below max height AGL. - local unitinzone=_unit:IsInZone(zone) and unitalt <= self.strafemaxalt and towardspit - - -- Debug output - local text=string.format("Checking still in zone. Unit = %s, player = %s in zone = %s. alt = %d, delta heading = %d", _unitName, _playername, tostring(unitinzone), unitalt, deltaheading) - self:T2(self.id..text) + -- Check if unit in zone and facing the right direction. + local unitinzone=checkme(_currentStrafeRun.zone.heading, zone) -- Check if player is in strafe zone and below max alt. if unitinzone then @@ -2858,22 +2872,10 @@ function RANGE:_CheckInZone(_unitName) for _,_targetZone in pairs(self.strafeTargets) do -- Get the current approach zone and check if player is inside. - local zonenname=_targetZone.name local zone=_targetZone.polygon --Core.Zone#ZONE_POLYGON_BASE - -- Check if player is in zone and below max alt and flying towards the target. - local unitheading = _unit:GetHeading() - local pitheading = _targetZone.heading - 180 - local deltaheading = unitheading-pitheading - local towardspit = math.abs(deltaheading)<=90 or math.abs(deltaheading-360)<=90 - local unitalt =_unit:GetHeight()-_unit:GetCoordinate():GetLandHeight() - - -- Check if unit is inside zone and below max height AGL. - local unitinzone=_unit:IsInZone(zone) and unitalt <= self.strafemaxalt and towardspit - - -- Debug info. - local text=string.format("Checking zone %s. Unit = %s, player = %s in zone = %s. alt = %d, delta heading = %d", _targetZone.name, _unitName, _playername, tostring(unitinzone), unitalt, deltaheading) - self:T2(self.id..text) + -- Check if unit in zone and facing the right direction. + local unitinzone=checkme(_targetZone.heading, zone) -- Player is inside zone. if unitinzone then @@ -2882,7 +2884,7 @@ function RANGE:_CheckInZone(_unitName) local _ammo=self:_GetAmmo(_unitName) -- Init strafe status for this player. - self.strafeStatus[_unitID] = {hits = 0, zone = _targetZone, time = 1, ammo=_ammo, pastfoulline=false } + self.strafeStatus[_unitID] = {hits = 0, zone = _targetZone, time = 1, ammo=_ammo, pastfoulline=false} -- Rolling in! local _msg=string.format("%s, rolling in on strafe pit %s.", self:_myname(_unitName), _targetZone.name) @@ -3089,11 +3091,9 @@ function RANGE:_GetAmmo(unitname) local text=string.format("Player %s has %d rounds ammo of type %s", playername, Nammo, Tammo) self:T(self.id..text) - MESSAGE:New(text, 10):ToAllIf(self.Debug) else local text=string.format("Player %s has %d ammo of type %s", playername, Nammo, Tammo) self:T(self.id..text) - MESSAGE:New(text, 10):ToAllIf(self.Debug) end end end diff --git a/Moose Development/Moose/Wrapper/Positionable.lua b/Moose Development/Moose/Wrapper/Positionable.lua index f7632d687..00f828cb7 100644 --- a/Moose Development/Moose/Wrapper/Positionable.lua +++ b/Moose Development/Moose/Wrapper/Positionable.lua @@ -590,26 +590,29 @@ end --- Returns the POSITIONABLE heading in degrees. -- @param Wrapper.Positionable#POSITIONABLE self --- @return #number The POSITIONABLE heading --- @return #nil The POSITIONABLE is not existing or alive. +-- @return #number The POSITIONABLE heading in degrees or `nil` if not existing or alive. function POSITIONABLE:GetHeading() + local DCSPositionable = self:GetDCSObject() if DCSPositionable then local PositionablePosition = DCSPositionable:getPosition() + if PositionablePosition then local PositionableHeading = math.atan2( PositionablePosition.x.z, PositionablePosition.x.x ) + if PositionableHeading < 0 then PositionableHeading = PositionableHeading + 2 * math.pi end + PositionableHeading = PositionableHeading * 180 / math.pi - self:T2( PositionableHeading ) + return PositionableHeading end end - BASE:E( { "Cannot GetHeading", Positionable = self, Alive = self:IsAlive() } ) + self:E({"Cannot GetHeading", Positionable = self, Alive = self:IsAlive()}) return nil end