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.
This commit is contained in:
funkyfranky 2018-05-26 14:46:23 +02:00
parent d98f207bcf
commit ad75a7ddb5
5 changed files with 212 additions and 190 deletions

View File

@ -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]

View File

@ -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

View File

@ -2434,15 +2434,17 @@ 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

View File

@ -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
-- Weapon
local _ordnance = EventData.weapon
-- Get player unit and name.
local _unit, _playername = self:_GetPlayerUnitAndName(_unitName)
-- 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)
-- Get player unit and name.
local _unit, _playername = self:_GetPlayerUnitAndName(_unitName)
local _callsign=self:_myname(_unitName)
-- When the pcall returns a failure the weapon has hit.
local _status,_bombPos = pcall(
function()
return _ordnance:getPoint()
end)
if _unit and _playername then
self:T3(RANGE.id..string.format("Range %s: Bomb still in air: %s", self.rangename, tostring(_status)))
if _status then
-- When the pcall returns a failure the weapon has hit.
local _status,_bombPos = pcall(
function()
return _ordnance:getPoint()
end)
-- Still in the air. Remember this position.
_lastBombPos = {x = _bombPos.x, y = _bombPos.y, z= _bombPos.z }
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 }
else
-- Check again in 0.005 seconds.
return timer.getTime() + self.dtBombtrack
-- Bomb did hit the ground.
-- Get closet target to last position.
local _closetTarget = nil
local _distance = nil
local _hitquality = "POOR"
else
-- Get callsign.
local _callsign=self:_myname(_unitName)
-- 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)
-- 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)
-- 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 impactdist<self.rangeradius then
if self.PlayerSettings[_playername].delaysmoke then
timer.scheduleFunction(self._DelayedSmoke, {coord=impactcoord, color=self.PlayerSettings[_playername].smokecolor}, timer.getTime() + self.TdelaySmoke)
else
impactcoord:Smoke(self.PlayerSettings[_playername].smokecolor)
end
-- Smoke impact point of bomb.
if self.PlayerSettings[_playername].smokebombimpact and impactdist<self.rangeradius then
if self.PlayerSettings[_playername].delaysmoke then
timer.scheduleFunction(self._DelayedSmoke, {coord=impactcoord, color=self.PlayerSettings[_playername].smokecolor}, timer.getTime() + self.TdelaySmoke)
else
impactcoord:Smoke(self.PlayerSettings[_playername].smokecolor)
end
end
-- Loop over defined bombing targets.
for _,_bombtarget in pairs(self.bombingTargets) do
-- Loop over defined bombing targets.
for _,_bombtarget in pairs(self.bombingTargets) do
local _target=_bombtarget.target --Wrapper.Positionable#POSITIONABLE
local _target=_bombtarget.target --Wrapper.Positionable#POSITIONABLE
if _target and _target:IsAlive() then
if _target and _target:IsAlive() then
-- Distance between bomb and target.
local _temp = impactcoord:Get2DDistance(_target:GetCoordinate())
-- Find closest target to last known position of the bomb.
if _distance == nil or _temp < _distance then
_distance = _temp
_closetTarget = _bombtarget
if _distance <= 0.5*_bombtarget.goodhitrange then
_hitquality = "EXCELLENT"
elseif _distance <= _bombtarget.goodhitrange then
_hitquality = "GOOD"
elseif _distance <= 2*_bombtarget.goodhitrange then
_hitquality = "INEFFECTIVE"
else
_hitquality = "POOR"
end
-- Distance between bomb and target.
local _temp = impactcoord:Get2DDistance(_target:GetCoordinate())
-- Find closest target to last known position of the bomb.
if _distance == nil or _temp < _distance then
_distance = _temp
_closetTarget = _bombtarget
if _distance <= 0.5*_bombtarget.goodhitrange then
_hitquality = "EXCELLENT"
elseif _distance <= _bombtarget.goodhitrange then
_hitquality = "GOOD"
elseif _distance <= 2*_bombtarget.goodhitrange then
_hitquality = "INEFFECTIVE"
else
_hitquality = "POOR"
end
end
end
end
-- Count if bomb fell less than 1 km away from the target.
if _distance <= self.scorebombdistance then
-- Count if bomb fell less than 1 km away from the target.
if _distance <= self.scorebombdistance then
-- Init bomb player results.
if not self.bombPlayerResults[_playername] then
self.bombPlayerResults[_playername] = {}
end
-- Local results.
local _results = self.bombPlayerResults[_playername]
-- Add to table.
table.insert(_results, {name=_closetTarget.name, distance =_distance, weapon = _weaponName, quality=_hitquality })
-- Send message to player.
local _message = string.format("%s, impact %d m from bullseye of target %s. %s hit.", _callsign, _distance, _closetTarget.name, _hitquality)
-- Send message.
self:_DisplayMessageToGroup(_unit, _message, nil, true)
elseif _distance <= self.rangeradius then
-- Send message
local _message=string.format("%s, weapon fell more than %.1f km away from nearest range target. No score!", _callsign, self.scorebombdistance/1000)
self:_DisplayMessageToGroup(_unit, _message, nil, true)
-- Init bomb player results.
if not self.bombPlayerResults[_playername] then
self.bombPlayerResults[_playername] = {}
end
end -- _status
-- Local results.
local _results = self.bombPlayerResults[_playername]
end -- end unit ~= nil
-- Add to table.
table.insert(_results, {name=_closetTarget.name, distance =_distance, weapon = _weaponName, quality=_hitquality })
return nil --Terminate the timer
end -- end function bombtrack
-- Send message to player.
local _message = string.format("%s, impact %d m from bullseye of target %s. %s hit.", _callsign, _distance, _closetTarget.name, _hitquality)
timer.scheduleFunction(trackBomb, nil, timer.getTime() + 1)
-- Send message.
self:_DisplayMessageToGroup(_unit, _message, nil, true)
elseif _distance <= self.rangeradius then
-- Send message
local _message=string.format("%s, weapon fell more than %.1f km away from nearest range target. No score!", _callsign, self.scorebombdistance/1000)
self:_DisplayMessageToGroup(_unit, _message, nil, true)
end
--Terminate the timer
self:T(RANGE.id..string.format("Range %s, player %s: Terminating bomb track timer.", self.rangename, _playername))
return nil
end -- _status check
end -- end function trackBomb
-- Weapon is not yet "alife" just yet. Start timer in one second.
self:T(RANGE.id..string.format("Range %s, player %s: Tracking of weapon starts in one second.", self.rangename, _playername))
timer.scheduleFunction(trackBomb, EventData.weapon, timer.getTime() + 1.0)
end --if _track (string.match) and player-range distance < threshold.
end --if string.match
end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -752,8 +752,8 @@ end
--- (AIR) Orbit at a specified position at a specified alititude during a specified duration with a specified speed.
-- @param #CONTROLLABLE self
-- @param Dcs.DCSTypes#Vec2 Point The point to hold the position.
-- @param #number Altitude The altitude to hold the position.
-- @param #number Speed The speed flying when holding the position.
-- @param #number Altitude The altitude [m] to hold the position.
-- @param #number Speed The speed [m/s] flying when holding the position.
-- @return #CONTROLLABLE self
function CONTROLLABLE:TaskOrbitCircleAtVec2( Point, Altitude, Speed )
self:F2( { self.ControllableName, Point, Altitude, Speed } )
@ -796,8 +796,8 @@ end
--- (AIR) Orbit at the current position of the first unit of the controllable at a specified alititude.
-- @param #CONTROLLABLE self
-- @param #number Altitude The altitude to hold the position.
-- @param #number Speed The speed flying when holding the position.
-- @param #number Altitude The altitude [m] to hold the position.
-- @param #number Speed The speed [m/s] flying when holding the position.
-- @param Core.Point#COORDINATE Coordinate The coordinate where to orbit.
-- @return #CONTROLLABLE self
function CONTROLLABLE:TaskOrbitCircle( Altitude, Speed, Coordinate )
@ -1660,6 +1660,9 @@ do -- Patrol methods
--- (GROUND) Patrol randomly to the waypoints the for the (parent) group.
-- A random waypoint will be picked and the group will move towards that point.
-- @param #CONTROLLABLE self
-- @param #number Speed Speed in km/h.
-- @param #string Formation The formation the group uses.
-- @param Core.Point#COORDINATE ToWaypoint The waypoint where the group should move to.
-- @return #CONTROLLABLE
function CONTROLLABLE:PatrolRouteRandom( Speed, Formation, ToWaypoint )
@ -1711,6 +1714,9 @@ do -- Patrol methods
--- (GROUND) Patrol randomly to the waypoints the for the (parent) group.
-- A random waypoint will be picked and the group will move towards that point.
-- @param #CONTROLLABLE self
-- @param #table ZoneList Table of zones.
-- @param #number Speed Speed in km/h the group moves at.
-- @param #string Formation (Optional) Formation the group should use.
-- @return #CONTROLLABLE
function CONTROLLABLE:PatrolZones( ZoneList, Speed, Formation )
@ -1740,7 +1746,7 @@ do -- Patrol methods
-- Create a "ground route point", which is a "point" structure that can be given as a parameter to a Task
local Route = {}
Route[#Route+1] = FromCoord:WaypointGround( 120 )
Route[#Route+1] = FromCoord:WaypointGround( 20 )
Route[#Route+1] = ToCoord:WaypointGround( Speed, Formation )
@ -1774,7 +1780,7 @@ do -- Route methods
--- (AIR + GROUND) Make the Controllable move to fly to a given point.
-- @param #CONTROLLABLE self
-- @param Dcs.DCSTypes#Vec3 Point The destination point in Vec3 format.
-- @param #number Speed The speed to travel.
-- @param #number Speed The speed [m/s] to travel.
-- @return #CONTROLLABLE self
function CONTROLLABLE:RouteToVec2( Point, Speed )
self:F2( { Point, Speed } )
@ -1825,7 +1831,7 @@ do -- Route methods
--- (AIR + GROUND) Make the Controllable move to a given point.
-- @param #CONTROLLABLE self
-- @param Dcs.DCSTypes#Vec3 Point The destination point in Vec3 format.
-- @param #number Speed The speed to travel.
-- @param #number Speed The speed [m/s] to travel.
-- @return #CONTROLLABLE self
function CONTROLLABLE:RouteToVec3( Point, Speed )
self:F2( { Point, Speed } )
@ -1882,7 +1888,7 @@ do -- Route methods
--- Make the controllable to follow a given route.
-- @param #CONTROLLABLE self
-- @param #table Route A table of Route Points.
-- @param #number DelaySeconds Wait for the specified seconds before executing the Route.
-- @param #number DelaySeconds (Optional) Wait for the specified seconds before executing the Route. Default is one second.
-- @return #CONTROLLABLE The CONTROLLABLE.
function CONTROLLABLE:Route( Route, DelaySeconds )
self:F2( Route )
@ -1923,7 +1929,7 @@ do -- Route methods
--- Make the GROUND Controllable to drive towards a specific point.
-- @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 #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".
-- @param #number DelaySeconds Wait for the specified seconds before executing the Route.
-- @return #CONTROLLABLE The CONTROLLABLE.
@ -1939,37 +1945,22 @@ do -- Route methods
return self
end
--- Make the GROUND Controllable to drive towards a specific point using (only) roads.
--- Make the 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 #number DelaySeconds Wait for the specified seconds before executing the Route.
-- @param #number Speed (Optional) Speed in km/h. The default speed is 20 km/h.
-- @param #number DelaySeconds (Optional) Wait for the specified seconds before executing the Route. Default is one second.
-- @param #string OffRoadFormation (Optional) The formation at initial and final waypoint. Default is "Off Road".
-- @return #CONTROLLABLE The CONTROLLABLE.
function CONTROLLABLE:RouteGroundOnRoad( ToCoordinate, Speed, DelaySeconds )
function CONTROLLABLE:RouteGroundOnRoad( ToCoordinate, Speed, DelaySeconds, OffRoadFormation )
-- Current coordinate.
local FromCoordinate = self:GetCoordinate()
-- Defaults.
Speed=Speed or 20
DelaySeconds=DelaySeconds or 1
OffRoadFormation=OffRoadFormation or "Off Road"
-- Formation is set to on road.
local Formation="On Road"
-- Path on road from current position to destination coordinate.
local path=FromCoordinate:GetPathOnRoad(ToCoordinate)
-- Route, ground waypoints along roads.
local route={}
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, "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, "Off Road"))
end
-- 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"
-- First point on road.
local FromOnRoad = FromCoordinate:GetClosestPointToRoad()
-- Path on road from current position to destination coordinate.
local path=FromCoordinate:GetPathOnRoad( ToCoordinate )
-- Last Point on road.
local ToOnRoad = ToCoordinate:GetClosestPointToRoad()
-- Route, ground waypoints along roads.
local Route = {}
table.insert( Route, FromCoordinate:WaypointGround( Speed, Formation ) )
-- 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
-- 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 coordinate in path is last point on road.
local dist=ToCoordinate:Get2DDistance(path[#path])
-- 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 ) )
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 }