From 25e4d171ab92904d84fb24ce001866468d3ef137 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 21 May 2018 21:43:19 +0200 Subject: [PATCH 1/3] Added GetSpeedMax function --- Moose Development/Moose/AI/AI_Cargo_APC.lua | 2 +- .../Moose/Wrapper/Controllable.lua | 10 +++---- Moose Development/Moose/Wrapper/Group.lua | 30 +++++++++++++++++++ Moose Development/Moose/Wrapper/Unit.lua | 17 +++++++++++ 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo_APC.lua b/Moose Development/Moose/AI/AI_Cargo_APC.lua index 0cb8aed9b..95a5ba04d 100644 --- a/Moose Development/Moose/AI/AI_Cargo_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_APC.lua @@ -609,7 +609,7 @@ function AI_CARGO_APC:onafterPickup( APC, From, Event, To, Coordinate ) if Coordinate then self.RoutePickup = true - local Waypoints = APC:TaskGroundOnRoad( Coordinate, 150, "Line abreast" ) + local Waypoints = APC:TaskGroundOnRoad( Coordinate, APC:GetSpeedMax()*0.8, "Line abreast" ) local TaskFunction = APC:TaskFunction( "AI_CARGO_APC._Pickup", self ) diff --git a/Moose Development/Moose/Wrapper/Controllable.lua b/Moose Development/Moose/Wrapper/Controllable.lua index 04576498f..0318c6c47 100644 --- a/Moose Development/Moose/Wrapper/Controllable.lua +++ b/Moose Development/Moose/Wrapper/Controllable.lua @@ -1958,17 +1958,17 @@ do -- Route methods -- Route, ground waypoints along roads. local route={} - table.insert(route, FromCoordinate:WaypointGround(Speed, Formation)) + table.insert(route, FromCoordinate:WaypointGround(Speed, "Off Road")) -- Convert coordinates to ground waypoints and insert into table. for _, coord in ipairs(path) do - table.insert(route, coord:WaypointGround(Speed, Formation)) + table.insert(route, coord:WaypointGround(Speed, "On Road")) end -- Add the final coordinate because the final coordinate in path is last point on road. local dist=ToCoordinate:Get2DDistance(path[#path]) if dist>10 then - table.insert(route, ToCoordinate:WaypointGround(Speed, "Vee")) + table.insert(route, ToCoordinate:WaypointGround(Speed, "Off Road")) end -- Route controllable to destination. @@ -2059,7 +2059,7 @@ do -- Route methods PointFrom.y = ControllablePoint.y PointFrom.type = "Turning Point" PointFrom.action = Formation or "Cone" - PointFrom.speed = 20 / 1.6 + PointFrom.speed = 20 / 3.6 local PointTo = {} @@ -2084,7 +2084,7 @@ do -- Route methods if Speed then PointTo.speed = Speed else - PointTo.speed = 20 / 1.6 + PointTo.speed = 20 / 3.6 end local Points = { PointFrom, PointTo } diff --git a/Moose Development/Moose/Wrapper/Group.lua b/Moose Development/Moose/Wrapper/Group.lua index 6f45f873d..dcbee2b90 100644 --- a/Moose Development/Moose/Wrapper/Group.lua +++ b/Moose Development/Moose/Wrapper/Group.lua @@ -350,6 +350,36 @@ function GROUP:GetCountry() return nil end +--- Returns the maximum speed of the group. +-- If the group is heterogenious and consists of different units, the max speed of the slowest unit is returned. +-- @param #GROUP self +-- @return #number Speed in km/h. +function GROUP:GetSpeedMax() + self:F2( self.GroupName ) + + local DCSGroup = self:GetDCSObject() + if DCSGroup then + + local Units=self:GetUnits() + + local speedmax=nil + + for _,unit in pairs(Units) do + local unit=unit --Wrapper.Unit#UNIT + local speed=unit:GetSpeedMax() + if speedmax==nil then + speedmax=speed + elseif speed The list of @{Unit} objects of the @{Group}. diff --git a/Moose Development/Moose/Wrapper/Unit.lua b/Moose Development/Moose/Wrapper/Unit.lua index 1c4236dc3..bc5a89e3f 100644 --- a/Moose Development/Moose/Wrapper/Unit.lua +++ b/Moose Development/Moose/Wrapper/Unit.lua @@ -401,6 +401,23 @@ function UNIT:GetNumber() return nil end + +--- Returns the unit's max speed in km/h derived from the DCS descriptors. +-- @param #UNIT self +-- @return #number Speed in km/h. +function UNIT:GetSpeedMax() + self:F2( self.UnitName ) + + local Desc = self:GetDesc() + + if Desc then + local SpeedMax = Desc.speedMax + return SpeedMax*3.6 + end + + return nil +end + --- Returns the unit's group if it exist and nil otherwise. -- @param Wrapper.Unit#UNIT self -- @return Wrapper.Group#GROUP The Group of the Unit. From 369ea08fd10935a942c38ac7dbb532fef79463ee Mon Sep 17 00:00:00 2001 From: funkyfranky Date: Thu, 24 May 2018 19:36:53 +0200 Subject: [PATCH 2/3] Minor changes ARTY corrected MISSILE category. --- Moose Development/Moose/Core/Zone.lua | 5 +- .../Moose/Functional/Artillery.lua | 48 ++++++++++++++++--- Moose Development/Moose/Functional/Range.lua | 2 +- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/Moose Development/Moose/Core/Zone.lua b/Moose Development/Moose/Core/Zone.lua index a8dc2f641..fafde4e43 100644 --- a/Moose Development/Moose/Core/Zone.lua +++ b/Moose Development/Moose/Core/Zone.lua @@ -431,8 +431,9 @@ end --- Bounds the zone with tires. -- @param #ZONE_RADIUS self --- @param #number Points (optional) The amount of points in the circle. --- @param #boolean UnBound If true the tyres will be destroyed. +-- @param #number Points (optional) The amount of points in the circle. Default 360. +-- @param Dcs.DCScountry#country.id CountryID The country id of the tire objects, e.g. country.id.USA for blue or country.id.RUSSIA for red. +-- @param #boolean UnBound (Optional) If true the tyres will be destroyed. -- @return #ZONE_RADIUS self function ZONE_RADIUS:BoundZone( Points, CountryID, UnBound ) diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index c38ee1fad..b14699798 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -449,6 +449,8 @@ function ARTY:New(group) local DCSunit=DCSgroup:getUnit(1) self.DCSdesc=DCSunit:getDesc() + --self.DCSdesc=group:GetDesc() + -- DCS descriptors. self:T3(ARTY.id.."DCS descriptors for group "..group:GetName()) for id,desc in pairs(self.DCSdesc) do @@ -456,7 +458,8 @@ function ARTY:New(group) end -- Maximum speed in km/h. - self.SpeedMax=self.DCSdesc.speedMax*3.6 + self.SpeedMax=group:GetSpeedMax() + --self.SpeedMax=self.DCSdesc.speedMax*3.6 -- Set speed to 0.7 of maximum. self.Speed=self.SpeedMax * 0.7 @@ -517,7 +520,7 @@ end --- Assign target coordinates to the ARTY group. Only the first parameter, i.e. the coordinate of the target is mandatory. The remaining parameters are optional and can be used to fine tune the engagement. -- @param #ARTY self --- @param Wrapper.Point#COORDINATE coord Coordinates of the target. +-- @param Core.Point#COORDINATE coord Coordinates of the target. -- @param #number prio (Optional) Priority of target. Number between 1 (high) and 100 (low). Default 50. -- @param #number radius (Optional) Radius. Default is 100 m. -- @param #number nshells (Optional) How many shells (or rockets) are fired on target per engagement. Default 5. @@ -544,6 +547,29 @@ function ARTY:AssignTargetCoord(coord, prio, radius, nshells, maxengage, time, w unique=false end weapontype=weapontype or ARTY.WeaponType.Auto + + -- Check if we have a coordinate object. + local text=nil + if coord:IsInstanceOf("GROUP") then + text="WARNING: ARTY:AssignTargetCoordinate(coord, ...) needs a COORDINATE object as first parameter - you gave a GROUP. Converting to COORDINATE..." + coord=coord:GetCoordinate() + elseif coord:IsInstanceOf("UNIT") then + text="WARNING: ARTY:AssignTargetCoordinate(coord, ...) needs a COORDINATE object as first parameter - you gave a UNIT. Converting to COORDINATE..." + coord=coord:GetCoordinate() + elseif coord:IsInstanceOf("POSITIONABLE") then + text="WARNING: ARTY:AssignTargetCoordinate(coord, ...) needs a COORDINATE object as first parameter - you gave a POSITIONABLE. Converting to COORDINATE..." + coord=coord:GetCoordinate() + elseif coord:IsInstanceOf("COORDINATE") then + -- Nothing to do here. + else + text="ERROR: ARTY:AssignTargetCoordinate(coord, ...) needs a COORDINATE object as first parameter!" + MESSAGE:New(text, 30):ToAll() + self:E(ARTY.id..text) + return nil + end + if text~=nil then + self:E(ARTY.id..text) + end -- Name of the target. local _name=name or coord:ToStringLLDMS() @@ -575,7 +601,7 @@ end --- Assign coordinate to where the ARTY group should move. -- @param #ARTY self --- @param Wrapper.Point#COORDINATE coord Coordinates of the target. +-- @param Core.Point#COORDINATE coord Coordinates of the target. -- @param #string time (Optional) Day time at which the group should start moving. Passed as a string in format "08:13:45". -- @param #number speed (Optinal) Speed in km/h the group should move at. Default 50 km/h. -- @param #boolean onroad (Optional) If true, group will mainly use roads. Default off, i.e. go directly towards the specified coordinate. @@ -698,7 +724,7 @@ end --- Defines the rearming place of the ARTY group. If the place is too far away from the ARTY group it will be routed to the place. -- @param #ARTY self --- @param Wrapper.Point#COORDINATE coord Coordinates of the rearming place. +-- @param Core.Point#COORDINATE coord Coordinates of the rearming place. function ARTY:SetRearmingPlace(coord) self:F({coord=coord}) self.RearmingPlaceCoord=coord @@ -848,6 +874,10 @@ function ARTY:onafterStart(Controllable, From, Event, To) text=text..string.format("Targets:\n") for _, target in pairs(self.targets) do text=text..string.format("- %s\n", self:_TargetInfo(target)) + if self.Debug then + local zone=ZONE_RADIUS:New(target.name, target.coord:GetVec2(), target.radius) + zone:BoundZone(180, coalition.side.NEUTRAL) + end end text=text..string.format("Moves:\n") for i=1,#self.moves do @@ -867,7 +897,11 @@ function ARTY:onafterStart(Controllable, From, Event, To) text=text..string.format("- %s\n", _type) end text=text..string.format("******************************************************") - self:T(ARTY.id..text) + if self.Debug then + self:E(ARTY.id..text) + else + self:T(ARTY.id..text) + end -- Add event handler. self:HandleEvent(EVENTS.Shot, self._OnEventShot) @@ -1510,7 +1544,7 @@ end -- @param #string From From state. -- @param #string Event Event. -- @param #string To To state. --- @param Wrapper.Point#COORDINATE ToCoord Coordinate to which the ARTY group should move. +-- @param Core.Point#COORDINATE ToCoord Coordinate to which the ARTY group should move. -- @param #boolean OnRoad If true group should move on road mainly. -- @return #boolean If true, proceed to onafterMove. function ARTY:onbeforeMove(Controllable, From, Event, To, ToCoord, OnRoad) @@ -1961,7 +1995,7 @@ function ARTY:GetAmmo(display) end end else - if Category==Weapon.Category.ROCKET then + if Category==Weapon.Category.MISSILE then _gotmissile=true end end diff --git a/Moose Development/Moose/Functional/Range.lua b/Moose Development/Moose/Functional/Range.lua index bce0b8ef1..f815a6520 100644 --- a/Moose Development/Moose/Functional/Range.lua +++ b/Moose Development/Moose/Functional/Range.lua @@ -314,7 +314,7 @@ function RANGE:New(rangename) self.rangename=rangename or "Practice Range" -- Debug info. - local text=string.format("RANGE script version %s. Creating new RANGE object. Range name: %s.", RANGE.version, self.rangename) + local text=string.format("RANGE script version %s - creating new RANGE object of name: %s.", RANGE.version, self.rangename) self:E(RANGE.id..text) MESSAGE:New(text, 10):ToAllIf(self.Debug) From ad75a7ddb5ebb15fc4667f5243df92a39bbea466 Mon Sep 17 00:00:00 2001 From: funkyfranky Date: Sat, 26 May 2018 14:46:23 +0200 Subject: [PATCH 3/3] RANGE v1.2 and other changes RANGE: -Optimized performance. Bombs are now only tracked if the player is within a certain distance of the range. CONTROLLABLE: - Added speed unit to @param description. Sometimes it was unclear if speed needs to be given in m/s or km/h. - Fixed some default speed and conversions. COORDINATE: - Cleaned up some speed unit stuff. - Reintroduced PathOnRoad function to contain the full path. Useful as interface to DCS API function. - Fixed some default speed and conversions. AI_CARGO_APC: Speed is not fixed any more but set to 50% of the max speed a given unit can move at. --- Moose Development/Moose/AI/AI_Cargo_APC.lua | 11 +- Moose Development/Moose/Core/Point.lua | 30 ++- .../Moose/Functional/Artillery.lua | 16 +- Moose Development/Moose/Functional/Range.lua | 224 ++++++++++-------- .../Moose/Wrapper/Controllable.lua | 121 +++++----- 5 files changed, 212 insertions(+), 190 deletions(-) diff --git a/Moose Development/Moose/AI/AI_Cargo_APC.lua b/Moose Development/Moose/AI/AI_Cargo_APC.lua index 51f94e4c9..9fbf1566a 100644 --- a/Moose Development/Moose/AI/AI_Cargo_APC.lua +++ b/Moose Development/Moose/AI/AI_Cargo_APC.lua @@ -600,8 +600,6 @@ end -- @param Event -- @param To -- @param Core.Point#COORDINATE Coordinate --- @param #number Speed --- @param #string EndPointFormation The formation at the end point of the action. function AI_CARGO_APC:onafterPickup( APC, From, Event, To, Coordinate ) if APC and APC:IsAlive() then @@ -609,7 +607,7 @@ function AI_CARGO_APC:onafterPickup( APC, From, Event, To, Coordinate ) if Coordinate then self.RoutePickup = true - local Waypoints = APC:TaskGroundOnRoad( Coordinate, APC:GetSpeedMax()*0.8, "Line abreast" ) + local Waypoints = APC:TaskGroundOnRoad( Coordinate, APC:GetSpeedMax()*0.5, "Line abreast" ) local TaskFunction = APC:TaskFunction( "AI_CARGO_APC._Pickup", self ) @@ -634,15 +632,13 @@ end -- @param Event -- @param To -- @param Core.Point#COORDINATE Coordinate --- @param #number Speed --- @param #string EndPointFormation The formation at the end point of the action. function AI_CARGO_APC:onafterDeploy( APC, From, Event, To, Coordinate ) if APC and APC:IsAlive() then self.RouteDeploy = true - local Waypoints = APC:TaskGroundOnRoad( Coordinate, 150, "Line abreast" ) + local Waypoints = APC:TaskGroundOnRoad( Coordinate, APC:GetSpeedMax()*0.5, "Line abreast" ) local TaskFunction = APC:TaskFunction( "AI_CARGO_APC._Deploy", self ) @@ -662,14 +658,13 @@ end -- @param Event -- @param To -- @param Core.Point#COORDINATE Coordinate --- @param #number Speed function AI_CARGO_APC:onafterHome( APC, From, Event, To, Coordinate ) if APC and APC:IsAlive() ~= nil then self.RouteHome = true - local Waypoints = APC:TaskGroundOnRoad( Coordinate, 120, "Line abreast" ) + local Waypoints = APC:TaskGroundOnRoad( Coordinate, APC:GetSpeedMax()*0.5, "Line abreast" ) self:F({Waypoints = Waypoints}) local Waypoint = Waypoints[#Waypoints] diff --git a/Moose Development/Moose/Core/Point.lua b/Moose Development/Moose/Core/Point.lua index cd8390f7b..286e4f79f 100644 --- a/Moose Development/Moose/Core/Point.lua +++ b/Moose Development/Moose/Core/Point.lua @@ -777,7 +777,7 @@ do -- COORDINATE -- @param #COORDINATE.WaypointAltType AltType The altitude type. -- @param #COORDINATE.WaypointType Type The route point type. -- @param #COORDINATE.WaypointAction Action The route point action. - -- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h. + -- @param Dcs.DCSTypes#Speed Speed Airspeed in km/h. Default is 500 km/h. -- @param #boolean SpeedLocked true means the speed is locked. -- @return #table The route point. function COORDINATE:WaypointAir( AltType, Type, Action, Speed, SpeedLocked ) @@ -887,7 +887,7 @@ do -- COORDINATE --- Build an ground type route point. -- @param #COORDINATE self - -- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. + -- @param #number Speed (optional) Speed in km/h. The default speed is 20 km/h. -- @param #string Formation (optional) The route point Formation, which is a text string that specifies exactly the Text in the Type of the route point, like "Vee", "Echelon Right". -- @return #table The route point. function COORDINATE:WaypointGround( Speed, Formation ) @@ -935,22 +935,30 @@ do -- COORDINATE return COORDINATE:NewFromVec2(vec2) end - --- Returns a table of coordinates to a destination. + --- Returns a table of coordinates to a destination using only roads. + -- The first point is the closest point on road of the given coordinate. The last point is the closest point on road of the ToCoord. Hence, the coordinate itself and the final ToCoord are not necessarily included in the path. -- @param #COORDINATE self -- @param #COORDINATE ToCoord Coordinate of destination. -- @return #table Table of coordinates on road. function COORDINATE:GetPathOnRoad(ToCoord) - local Path={} + + -- DCS API function returning a table of vec2. local path = land.findPathOnRoads("roads", self.x, self.z, ToCoord.x, ToCoord.z) - Path[#Path+1]=COORDINATE:NewFromVec2(path[1]) - Path[#Path+1]=COORDINATE:NewFromVec2(path[#path]) + + --Path[#Path+1]=COORDINATE:NewFromVec2(path[1]) + --Path[#Path+1]=COORDINATE:NewFromVec2(path[#path]) + --Path[#Path+1]=self:GetClosestPointToRoad() + --Path[#Path+1]=ToCoord:GetClosestPointToRoad() -- I've removed this stuff because it severely slows down DCS in case of paths with a lot of segments. -- Just the beginning and the end point is sufficient. --- for i, v in ipairs(path) do --- self:I(v) --- local coord=COORDINATE:NewFromVec2(v) --- Path[#Path+1]=COORDINATE:NewFromVec2(v) --- end + + local Path={} + --Path[#Path+1]=self + for i, v in ipairs(path) do + Path[#Path+1]=COORDINATE:NewFromVec2(v) + end + --Path[#Path+1]=ToCoord + return Path end diff --git a/Moose Development/Moose/Functional/Artillery.lua b/Moose Development/Moose/Functional/Artillery.lua index 1921787ae..f8a210b8e 100644 --- a/Moose Development/Moose/Functional/Artillery.lua +++ b/Moose Development/Moose/Functional/Artillery.lua @@ -2434,16 +2434,18 @@ function ARTY:_Move(group, ToCoord, Speed, OnRoad) -- Route group on road if requested. if OnRoad then + -- Path on road (only first and last points) local _first=cpini:GetClosestPointToRoad() local _last=ToCoord:GetClosestPointToRoad() - local _onroad=_first:GetPathOnRoad(_last) - -- Points on road. - for i=1,#_onroad do - path[#path+1]=_onroad[i]:WaypointGround(Speed, "On road") - task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false) - end - + -- First point on road. + path[#path+1]=_first:WaypointGround(Speed, "On road") + task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false) + + -- Last point on road. + path[#path+1]=_last:WaypointGround(Speed, "On road") + task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false) + end -- Last waypoint at ToCoord. diff --git a/Moose Development/Moose/Functional/Range.lua b/Moose Development/Moose/Functional/Range.lua index 65614ebf5..c21f6656f 100644 --- a/Moose Development/Moose/Functional/Range.lua +++ b/Moose Development/Moose/Functional/Range.lua @@ -70,6 +70,7 @@ -- @field #table bombPlayerResults Table containing the bombing results of each player. -- @field #table PlayerSettings Indiviual player settings. -- @field #number dtBombtrack Time step [sec] used for tracking released bomb/rocket positions. Default 0.005 seconds. +-- @field #number BombtrackThreshold Bombs/rockets/missiles are only tracked if player-range distance is smaller than this threashold [m]. Default 25000 m. -- @field #number Tmsg Time [sec] messages to players are displayed. Default 30 sec. -- @field #number strafemaxalt Maximum altitude above ground for registering for a strafe run. Default is 914 m = 3000 ft. -- @field #number ndisplayresult Number of (player) results that a displayed. Default is 10. @@ -236,6 +237,7 @@ RANGE={ bombPlayerResults = {}, PlayerSettings = {}, dtBombtrack=0.005, + BombtrackThreshold=25000, Tmsg=30, strafemaxalt=914, ndisplayresult=10, @@ -283,7 +285,7 @@ RANGE.id="RANGE | " --- Range script version. -- @field #number version -RANGE.version="1.1.1" +RANGE.version="1.2.0" --TODO list: --TODO: Add custom weapons, which can be specified by the user. @@ -451,6 +453,13 @@ function RANGE:SetRangeRadius(radius) self.rangeradius=radius*1000 or RANGE.Defaults.rangeradius end +--- Set bomb track threshold distance. Bombs/rockets/missiles are only tracked if player-range distance is less than this distance. Default 25 km. +-- @param #RANGE self +-- @param #number distance Threshold distance in km. Default 25 km. +function RANGE:SetBombtrackThreshold(distance) + self.BombtrackThreshold=distance*1000 or 25*1000 +end + --- Set range location. If this is not done, one (random) unit position of the range is used to determine the center of the range. -- @param #RANGE self -- @param Core.Point#COORDINATE coordinate Coordinate of the center of the range. @@ -1081,6 +1090,7 @@ function RANGE:OnEventShot(EventData) local _weaponName = _weaponStrArray[#_weaponStrArray] -- Debug info. + self:T(RANGE.id.."EVENT SHOT: Range "..self.rangename) self:T(RANGE.id.."EVENT SHOT: Ini unit = "..EventData.IniUnitName) self:T(RANGE.id.."EVENT SHOT: Ini group = "..EventData.IniGroupName) self:T(RANGE.id.."EVENT SHOT: Weapon type = ".._weapon) @@ -1097,129 +1107,141 @@ function RANGE:OnEventShot(EventData) -- Check if any condition applies here. local _track = (_bombs and self.trackbombs) or (_rockets and self.trackrockets) or (_missiles and self.trackmissiles) - if _track then + -- Get unit name. + local _unitName = EventData.IniUnitName + + -- Get player unit and name. + local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) - -- Weapon - local _ordnance = EventData.weapon + -- Set this to larger value than the threshold. + local dPR=self.BombtrackThreshold*2 + + -- Distance player to range. + if _unit and _playername then + dPR=_unit:GetCoordinate():Get2DDistance(self.location) + self:T(RANGE.id..string.format("Range %s, player %s, player-range distance = %d km.", self.rangename, _playername, dPR/1000)) + end + + -- Only track if distance player to range is < 25 km. + if _track and dPR<=self.BombtrackThreshold then -- Tracking info and init of last bomb position. - self:T(RANGE.id..string.format("Tracking %s - %s.", _weapon, _ordnance:getName())) + self:T(RANGE.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} - - -- Get unit name. - local _unitName = EventData.IniUnitName -- Function monitoring the position of a bomb until impact. - local function trackBomb(_previousPos) + local function trackBomb(_ordnance) + + -- When the pcall returns a failure the weapon has hit. + local _status,_bombPos = pcall( + function() + return _ordnance:getPoint() + end) + + self:T3(RANGE.id..string.format("Range %s: Bomb still in air: %s", self.rangename, tostring(_status))) + if _status then - -- Get player unit and name. - local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) - local _callsign=self:_myname(_unitName) + -- Still in the air. Remember this position. + _lastBombPos = {x = _bombPos.x, y = _bombPos.y, z= _bombPos.z } - if _unit and _playername then - - -- When the pcall returns a failure the weapon has hit. - local _status,_bombPos = pcall( - function() - return _ordnance:getPoint() - end) - - if _status then + -- Check again in 0.005 seconds. + return timer.getTime() + self.dtBombtrack - -- Still in the air. Remember this position. - _lastBombPos = {x = _bombPos.x, y = _bombPos.y, z= _bombPos.z } - - -- Check again in 0.005 seconds. - return timer.getTime() + self.dtBombtrack - - else + else + + -- Bomb did hit the ground. + -- Get closet target to last position. + local _closetTarget = nil + local _distance = nil + local _hitquality = "POOR" - -- Bomb did hit the ground. - -- Get closet target to last position. - local _closetTarget = nil - local _distance = nil - local _hitquality = "POOR" - - -- Coordinate of impact point. - local impactcoord=COORDINATE:NewFromVec3(_lastBombPos) - - -- Distance from range. We dont want to smoke targets outside of the range. - local impactdist=impactcoord:Get2DDistance(self.location) - - -- Smoke impact point of bomb. - if self.PlayerSettings[_playername].smokebombimpact and impactdist10 then - table.insert(route, ToCoordinate:WaypointGround(Speed, "Off Road")) - end + -- Defaults. + Speed=Speed or 20 + DelaySeconds=DelaySeconds or 1 + OffRoadFormation=OffRoadFormation or "Off Road" + + -- Get the route task. + local route=self:TaskGroundOnRoad(ToCoordinate, Speed, OffRoadFormation) -- Route controllable to destination. self:Route( route, DelaySeconds ) @@ -1978,39 +1969,43 @@ do -- Route methods end - --- Make a task for a GROUND Controllable to drive towards a specific point using (only) roads. + --- Make a task for a GROUND Controllable to drive towards a specific point using (mostly) roads. -- @param #CONTROLLABLE self -- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. - -- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. - -- @param #string EndPointFormation The formation to achieve at the end point. + -- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h. + -- @param #string OffRoadFormation (Optional) The formation at initial and final waypoint. Default is "Off Road". -- @return Task - function CONTROLLABLE:TaskGroundOnRoad( ToCoordinate, Speed, EndPointFormation ) + function CONTROLLABLE:TaskGroundOnRoad( ToCoordinate, Speed, OffRoadFormation ) + self:F2({ToCoordinate=ToCoordinate, Speed=Speed, OffRoadFormation=OffRoadFormation}) + + -- Defaults. + Speed=Speed or 20 + OffRoadFormation=OffRoadFormation or "Off Road" -- Current coordinate. local FromCoordinate = self:GetCoordinate() - -- Formation is set to on road. - local Formation="On Road" - - -- Path on road from current position to destination coordinate. - local path=FromCoordinate:GetPathOnRoad( ToCoordinate ) + -- First point on road. + local FromOnRoad = FromCoordinate:GetClosestPointToRoad() - -- Route, ground waypoints along roads. - local Route = {} - table.insert( Route, FromCoordinate:WaypointGround( Speed, Formation ) ) + -- Last Point on road. + local ToOnRoad = ToCoordinate:GetClosestPointToRoad() + + -- Route, ground waypoints along road. + local route={} - -- Convert coordinates to ground waypoints and insert into table. - for _, coord in ipairs(path) do - table.insert( Route, coord:WaypointGround( Speed, Formation ) ) - end - - -- Add the final coordinate because the final coordinate in path is last point on road. - local dist=ToCoordinate:Get2DDistance(path[#path]) + -- Create waypoints. + table.insert(route, FromCoordinate:WaypointGround(Speed, OffRoadFormation)) + table.insert(route, FromOnRoad:WaypointGround(Speed, "On Road")) + table.insert(route, ToOnRoad:WaypointGround(Speed, "On Road")) + + -- Add the final coordinate because the final might not be on the road. + local dist=ToCoordinate:Get2DDistance(ToOnRoad) if dist>10 then - table.insert( Route, ToCoordinate:WaypointGround( Speed, EndPointFormation ) ) - end + table.insert(route, ToCoordinate:WaypointGround(Speed, OffRoadFormation)) + end - return Route + return route end @@ -2020,7 +2015,7 @@ do -- Route methods -- @param Core.Point#COORDINATE.RoutePointAltType AltType The altitude type. -- @param Core.Point#COORDINATE.RoutePointType Type The route point type. -- @param Core.Point#COORDINATE.RoutePointAction Action The route point action. - -- @param #number Speed (optional) Speed in km/h. The default speed is 999 km/h. + -- @param #number Speed (optional) Speed in km/h. The default speed is 500 km/h. -- @param #number DelaySeconds Wait for the specified seconds before executing the Route. -- @return #CONTROLLABLE The CONTROLLABLE. function CONTROLLABLE:RouteAirTo( ToCoordinate, AltType, Type, Action, Speed, DelaySeconds ) @@ -2043,7 +2038,7 @@ do -- Route methods -- @param #CONTROLLABLE self -- @param Core.Zone#ZONE Zone The zone where to route to. -- @param #boolean Randomize Defines whether to target point gets randomized within the Zone. - -- @param #number Speed The speed. + -- @param #number Speed The speed in m/s. Default is 5.555 m/s = 20 km/h. -- @param Base#FORMATION Formation The formation string. function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation ) self:F2( Zone ) @@ -2104,7 +2099,7 @@ do -- Route methods -- A given formation can be given. -- @param #CONTROLLABLE self -- @param #Vec2 Vec2 The Vec2 where to route to. - -- @param #number Speed The speed. + -- @param #number Speed The speed in m/s. Default is 5.555 m/s = 20 km/h. -- @param Base#FORMATION Formation The formation string. function CONTROLLABLE:TaskRouteToVec2( Vec2, Speed, Formation ) @@ -2119,7 +2114,7 @@ do -- Route methods PointFrom.y = ControllablePoint.y PointFrom.type = "Turning Point" PointFrom.action = Formation or "Cone" - PointFrom.speed = 20 / 1.6 + PointFrom.speed = 20 / 3.6 local PointTo = {} @@ -2137,7 +2132,7 @@ do -- Route methods if Speed then PointTo.speed = Speed else - PointTo.speed = 60 / 3.6 + PointTo.speed = 20 / 3.6 end local Points = { PointFrom, PointTo }