Merge pull request #905 from FlightControl-Master/FF/Develop

RANGE v1.2 and "Speed"
This commit is contained in:
Frank
2018-05-27 22:21:33 +02:00
committed by GitHub
8 changed files with 307 additions and 202 deletions

View File

@@ -601,8 +601,6 @@ end
-- @param Event -- @param Event
-- @param To -- @param To
-- @param Core.Point#COORDINATE Coordinate -- @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 ) function AI_CARGO_APC:onafterPickup( APC, From, Event, To, Coordinate )
if APC and APC:IsAlive() then if APC and APC:IsAlive() then
@@ -610,7 +608,7 @@ function AI_CARGO_APC:onafterPickup( APC, From, Event, To, Coordinate )
if Coordinate then if Coordinate then
self.RoutePickup = true self.RoutePickup = 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._Pickup", self ) local TaskFunction = APC:TaskFunction( "AI_CARGO_APC._Pickup", self )
@@ -635,15 +633,13 @@ end
-- @param Event -- @param Event
-- @param To -- @param To
-- @param Core.Point#COORDINATE Coordinate -- @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 ) function AI_CARGO_APC:onafterDeploy( APC, From, Event, To, Coordinate )
if APC and APC:IsAlive() then if APC and APC:IsAlive() then
self.RouteDeploy = true 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 ) local TaskFunction = APC:TaskFunction( "AI_CARGO_APC._Deploy", self )
@@ -663,14 +659,13 @@ end
-- @param Event -- @param Event
-- @param To -- @param To
-- @param Core.Point#COORDINATE Coordinate -- @param Core.Point#COORDINATE Coordinate
-- @param #number Speed
function AI_CARGO_APC:onafterHome( APC, From, Event, To, Coordinate ) function AI_CARGO_APC:onafterHome( APC, From, Event, To, Coordinate )
if APC and APC:IsAlive() ~= nil then if APC and APC:IsAlive() ~= nil then
self.RouteHome = true 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}) self:F({Waypoints = Waypoints})
local Waypoint = Waypoints[#Waypoints] local Waypoint = Waypoints[#Waypoints]

View File

@@ -773,7 +773,7 @@ do -- COORDINATE
-- @param #COORDINATE.WaypointAltType AltType The altitude type. -- @param #COORDINATE.WaypointAltType AltType The altitude type.
-- @param #COORDINATE.WaypointType Type The route point type. -- @param #COORDINATE.WaypointType Type The route point type.
-- @param #COORDINATE.WaypointAction Action The route point action. -- @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. -- @param #boolean SpeedLocked true means the speed is locked.
-- @return #table The route point. -- @return #table The route point.
function COORDINATE:WaypointAir( AltType, Type, Action, Speed, SpeedLocked ) function COORDINATE:WaypointAir( AltType, Type, Action, Speed, SpeedLocked )
@@ -883,7 +883,7 @@ do -- COORDINATE
--- Build an ground type route point. --- Build an ground type route point.
-- @param #COORDINATE self -- @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". -- @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. -- @return #table The route point.
function COORDINATE:WaypointGround( Speed, Formation ) function COORDINATE:WaypointGround( Speed, Formation )
@@ -931,22 +931,30 @@ do -- COORDINATE
return COORDINATE:NewFromVec2(vec2) return COORDINATE:NewFromVec2(vec2)
end 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 self
-- @param #COORDINATE ToCoord Coordinate of destination. -- @param #COORDINATE ToCoord Coordinate of destination.
-- @return #table Table of coordinates on road. -- @return #table Table of coordinates on road.
function COORDINATE:GetPathOnRoad(ToCoord) 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) 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. -- 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. -- Just the beginning and the end point is sufficient.
-- for i, v in ipairs(path) do
-- self:I(v) local Path={}
-- local coord=COORDINATE:NewFromVec2(v) --Path[#Path+1]=self
-- Path[#Path+1]=COORDINATE:NewFromVec2(v) for i, v in ipairs(path) do
-- end Path[#Path+1]=COORDINATE:NewFromVec2(v)
end
--Path[#Path+1]=ToCoord
return Path return Path
end end

View File

@@ -426,8 +426,9 @@ end
--- Bounds the zone with tires. --- Bounds the zone with tires.
-- @param #ZONE_RADIUS self -- @param #ZONE_RADIUS self
-- @param #number Points (optional) The amount of points in the circle. -- @param #number Points (optional) The amount of points in the circle. Default 360.
-- @param #boolean UnBound If true the tyres will be destroyed. -- @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 -- @return #ZONE_RADIUS self
function ZONE_RADIUS:BoundZone( Points, CountryID, UnBound ) function ZONE_RADIUS:BoundZone( Points, CountryID, UnBound )

View File

@@ -449,6 +449,8 @@ function ARTY:New(group)
local DCSunit=DCSgroup:getUnit(1) local DCSunit=DCSgroup:getUnit(1)
self.DCSdesc=DCSunit:getDesc() self.DCSdesc=DCSunit:getDesc()
--self.DCSdesc=group:GetDesc()
-- DCS descriptors. -- DCS descriptors.
self:T3(ARTY.id.."DCS descriptors for group "..group:GetName()) self:T3(ARTY.id.."DCS descriptors for group "..group:GetName())
for id,desc in pairs(self.DCSdesc) do for id,desc in pairs(self.DCSdesc) do
@@ -456,7 +458,8 @@ function ARTY:New(group)
end end
-- Maximum speed in km/h. -- 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. -- Set speed to 0.7 of maximum.
self.Speed=self.SpeedMax * 0.7 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. --- 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 #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 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 radius (Optional) Radius. Default is 100 m.
-- @param #number nshells (Optional) How many shells (or rockets) are fired on target per engagement. Default 5. -- @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 unique=false
end end
weapontype=weapontype or ARTY.WeaponType.Auto 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. -- Name of the target.
local _name=name or coord:ToStringLLDMS() local _name=name or coord:ToStringLLDMS()
@@ -575,7 +601,7 @@ end
--- Assign coordinate to where the ARTY group should move. --- Assign coordinate to where the ARTY group should move.
-- @param #ARTY self -- @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 #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 #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. -- @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. --- 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 #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) function ARTY:SetRearmingPlace(coord)
self:F({coord=coord}) self:F({coord=coord})
self.RearmingPlaceCoord=coord self.RearmingPlaceCoord=coord
@@ -848,6 +874,10 @@ function ARTY:onafterStart(Controllable, From, Event, To)
text=text..string.format("Targets:\n") text=text..string.format("Targets:\n")
for _, target in pairs(self.targets) do for _, target in pairs(self.targets) do
text=text..string.format("- %s\n", self:_TargetInfo(target)) 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 end
text=text..string.format("Moves:\n") text=text..string.format("Moves:\n")
for i=1,#self.moves do for i=1,#self.moves do
@@ -867,7 +897,11 @@ function ARTY:onafterStart(Controllable, From, Event, To)
text=text..string.format("- %s\n", _type) text=text..string.format("- %s\n", _type)
end end
text=text..string.format("******************************************************") 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. -- Add event handler.
self:HandleEvent(EVENTS.Shot, self._OnEventShot) self:HandleEvent(EVENTS.Shot, self._OnEventShot)
@@ -1510,7 +1544,7 @@ end
-- @param #string From From state. -- @param #string From From state.
-- @param #string Event Event. -- @param #string Event Event.
-- @param #string To To state. -- @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. -- @param #boolean OnRoad If true group should move on road mainly.
-- @return #boolean If true, proceed to onafterMove. -- @return #boolean If true, proceed to onafterMove.
function ARTY:onbeforeMove(Controllable, From, Event, To, ToCoord, OnRoad) function ARTY:onbeforeMove(Controllable, From, Event, To, ToCoord, OnRoad)
@@ -1961,7 +1995,7 @@ function ARTY:GetAmmo(display)
end end
end end
else else
if Category==Weapon.Category.ROCKET then if Category==Weapon.Category.MISSILE then
_gotmissile=true _gotmissile=true
end end
end end
@@ -2400,16 +2434,18 @@ function ARTY:_Move(group, ToCoord, Speed, OnRoad)
-- Route group on road if requested. -- Route group on road if requested.
if OnRoad then if OnRoad then
-- Path on road (only first and last points)
local _first=cpini:GetClosestPointToRoad() local _first=cpini:GetClosestPointToRoad()
local _last=ToCoord:GetClosestPointToRoad() local _last=ToCoord:GetClosestPointToRoad()
local _onroad=_first:GetPathOnRoad(_last)
-- Points on road. -- First point on road.
for i=1,#_onroad do path[#path+1]=_first:WaypointGround(Speed, "On road")
path[#path+1]=_onroad[i]:WaypointGround(Speed, "On road") task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false)
task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false)
end -- Last point on road.
path[#path+1]=_last:WaypointGround(Speed, "On road")
task[#task+1]=group:TaskFunction("ARTY._PassingWaypoint", self, #path-1, false)
end end
-- Last waypoint at ToCoord. -- Last waypoint at ToCoord.

View File

@@ -70,6 +70,7 @@
-- @field #table bombPlayerResults Table containing the bombing results of each player. -- @field #table bombPlayerResults Table containing the bombing results of each player.
-- @field #table PlayerSettings Indiviual player settings. -- @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 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 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 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. -- @field #number ndisplayresult Number of (player) results that a displayed. Default is 10.
@@ -236,6 +237,7 @@ RANGE={
bombPlayerResults = {}, bombPlayerResults = {},
PlayerSettings = {}, PlayerSettings = {},
dtBombtrack=0.005, dtBombtrack=0.005,
BombtrackThreshold=25000,
Tmsg=30, Tmsg=30,
strafemaxalt=914, strafemaxalt=914,
ndisplayresult=10, ndisplayresult=10,
@@ -283,7 +285,7 @@ RANGE.id="RANGE | "
--- Range script version. --- Range script version.
-- @field #number version -- @field #number version
RANGE.version="1.1.1" RANGE.version="1.2.0"
--TODO list: --TODO list:
--TODO: Add custom weapons, which can be specified by the user. --TODO: Add custom weapons, which can be specified by the user.
@@ -314,7 +316,7 @@ function RANGE:New(rangename)
self.rangename=rangename or "Practice Range" self.rangename=rangename or "Practice Range"
-- Debug info. -- 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) self:E(RANGE.id..text)
MESSAGE:New(text, 10):ToAllIf(self.Debug) MESSAGE:New(text, 10):ToAllIf(self.Debug)
@@ -451,6 +453,13 @@ function RANGE:SetRangeRadius(radius)
self.rangeradius=radius*1000 or RANGE.Defaults.rangeradius self.rangeradius=radius*1000 or RANGE.Defaults.rangeradius
end 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. --- 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 #RANGE self
-- @param Core.Point#COORDINATE coordinate Coordinate of the center of the range. -- @param Core.Point#COORDINATE coordinate Coordinate of the center of the range.
@@ -1081,6 +1090,7 @@ function RANGE:OnEventShot(EventData)
local _weaponName = _weaponStrArray[#_weaponStrArray] local _weaponName = _weaponStrArray[#_weaponStrArray]
-- Debug info. -- 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 unit = "..EventData.IniUnitName)
self:T(RANGE.id.."EVENT SHOT: Ini group = "..EventData.IniGroupName) self:T(RANGE.id.."EVENT SHOT: Ini group = "..EventData.IniGroupName)
self:T(RANGE.id.."EVENT SHOT: Weapon type = ".._weapon) self:T(RANGE.id.."EVENT SHOT: Weapon type = ".._weapon)
@@ -1097,129 +1107,141 @@ function RANGE:OnEventShot(EventData)
-- Check if any condition applies here. -- Check if any condition applies here.
local _track = (_bombs and self.trackbombs) or (_rockets and self.trackrockets) or (_missiles and self.trackmissiles) 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 -- Set this to larger value than the threshold.
local _ordnance = EventData.weapon 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. -- 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. -- Init bomb position.
local _lastBombPos = {x=0,y=0,z=0} local _lastBombPos = {x=0,y=0,z=0}
-- Get unit name.
local _unitName = EventData.IniUnitName
-- Function monitoring the position of a bomb until impact. -- 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. -- Still in the air. Remember this position.
local _unit, _playername = self:_GetPlayerUnitAndName(_unitName) _lastBombPos = {x = _bombPos.x, y = _bombPos.y, z= _bombPos.z }
local _callsign=self:_myname(_unitName)
if _unit and _playername then -- Check again in 0.005 seconds.
return timer.getTime() + self.dtBombtrack
-- When the pcall returns a failure the weapon has hit.
local _status,_bombPos = pcall(
function()
return _ordnance:getPoint()
end)
if _status then
-- Still in the air. Remember this position. else
_lastBombPos = {x = _bombPos.x, y = _bombPos.y, z= _bombPos.z }
-- Bomb did hit the ground.
-- Check again in 0.005 seconds. -- Get closet target to last position.
return timer.getTime() + self.dtBombtrack local _closetTarget = nil
local _distance = nil
else local _hitquality = "POOR"
-- Bomb did hit the ground. -- Get callsign.
-- Get closet target to last position. local _callsign=self:_myname(_unitName)
local _closetTarget = nil
local _distance = nil -- Coordinate of impact point.
local _hitquality = "POOR" local impactcoord=COORDINATE:NewFromVec3(_lastBombPos)
-- Coordinate of impact point. -- Distance from range. We dont want to smoke targets outside of the range.
local impactcoord=COORDINATE:NewFromVec3(_lastBombPos) local impactdist=impactcoord:Get2DDistance(self.location)
-- Distance from range. We dont want to smoke targets outside of the range. -- Smoke impact point of bomb.
local impactdist=impactcoord:Get2DDistance(self.location) if self.PlayerSettings[_playername].smokebombimpact and impactdist<self.rangeradius then
if self.PlayerSettings[_playername].delaysmoke then
-- Smoke impact point of bomb. timer.scheduleFunction(self._DelayedSmoke, {coord=impactcoord, color=self.PlayerSettings[_playername].smokecolor}, timer.getTime() + self.TdelaySmoke)
if self.PlayerSettings[_playername].smokebombimpact and impactdist<self.rangeradius then else
if self.PlayerSettings[_playername].delaysmoke then impactcoord:Smoke(self.PlayerSettings[_playername].smokecolor)
timer.scheduleFunction(self._DelayedSmoke, {coord=impactcoord, color=self.PlayerSettings[_playername].smokecolor}, timer.getTime() + self.TdelaySmoke)
else
impactcoord:Smoke(self.PlayerSettings[_playername].smokecolor)
end
end 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
if _target and _target:IsAlive() then
-- Distance between bomb and target.
local _temp = impactcoord:Get2DDistance(_target:GetCoordinate())
local _target=_bombtarget.target --Wrapper.Positionable#POSITIONABLE -- Find closest target to last known position of the bomb.
if _distance == nil or _temp < _distance then
if _target and _target:IsAlive() then _distance = _temp
_closetTarget = _bombtarget
-- Distance between bomb and target. if _distance <= 0.5*_bombtarget.goodhitrange then
local _temp = impactcoord:Get2DDistance(_target:GetCoordinate()) _hitquality = "EXCELLENT"
elseif _distance <= _bombtarget.goodhitrange then
-- Find closest target to last known position of the bomb. _hitquality = "GOOD"
if _distance == nil or _temp < _distance then elseif _distance <= 2*_bombtarget.goodhitrange then
_distance = _temp _hitquality = "INEFFECTIVE"
_closetTarget = _bombtarget else
if _distance <= 0.5*_bombtarget.goodhitrange then _hitquality = "POOR"
_hitquality = "EXCELLENT"
elseif _distance <= _bombtarget.goodhitrange then
_hitquality = "GOOD"
elseif _distance <= 2*_bombtarget.goodhitrange then
_hitquality = "INEFFECTIVE"
else
_hitquality = "POOR"
end
end end
end end
end end
end
-- Count if bomb fell less than 1 km away from the target. -- Count if bomb fell less than 1 km away from the target.
if _distance <= self.scorebombdistance then 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. -- Init bomb player results.
local _message = string.format("%s, impact %d m from bullseye of target %s. %s hit.", _callsign, _distance, _closetTarget.name, _hitquality) if not self.bombPlayerResults[_playername] then
self.bombPlayerResults[_playername] = {}
-- 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 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
timer.scheduleFunction(trackBomb, nil, timer.getTime() + 1) -- 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)
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 string.match end --if _track (string.match) and player-range distance < threshold.
end 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. --- (AIR) Orbit at a specified position at a specified alititude during a specified duration with a specified speed.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param Dcs.DCSTypes#Vec2 Point The point to hold the position. -- @param Dcs.DCSTypes#Vec2 Point The point to hold the position.
-- @param #number Altitude The altitude to hold the position. -- @param #number Altitude The altitude [m] to hold the position.
-- @param #number Speed The speed flying when holding the position. -- @param #number Speed The speed [m/s] flying when holding the position.
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:TaskOrbitCircleAtVec2( Point, Altitude, Speed ) function CONTROLLABLE:TaskOrbitCircleAtVec2( Point, Altitude, Speed )
self:F2( { self.ControllableName, 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. --- (AIR) Orbit at the current position of the first unit of the controllable at a specified alititude.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param #number Altitude The altitude to hold the position. -- @param #number Altitude The altitude [m] to hold the position.
-- @param #number Speed The speed flying when holding the position. -- @param #number Speed The speed [m/s] flying when holding the position.
-- @param Core.Point#COORDINATE Coordinate The coordinate where to orbit. -- @param Core.Point#COORDINATE Coordinate The coordinate where to orbit.
-- @return #CONTROLLABLE self -- @return #CONTROLLABLE self
function CONTROLLABLE:TaskOrbitCircle( Altitude, Speed, Coordinate ) function CONTROLLABLE:TaskOrbitCircle( Altitude, Speed, Coordinate )
@@ -1660,6 +1660,9 @@ do -- Patrol methods
--- (GROUND) Patrol randomly to the waypoints the for the (parent) group. --- (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. -- A random waypoint will be picked and the group will move towards that point.
-- @param #CONTROLLABLE self -- @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 -- @return #CONTROLLABLE
function CONTROLLABLE:PatrolRouteRandom( Speed, Formation, ToWaypoint ) function CONTROLLABLE:PatrolRouteRandom( Speed, Formation, ToWaypoint )
@@ -1711,6 +1714,9 @@ do -- Patrol methods
--- (GROUND) Patrol randomly to the waypoints the for the (parent) group. --- (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. -- A random waypoint will be picked and the group will move towards that point.
-- @param #CONTROLLABLE self -- @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 -- @return #CONTROLLABLE
function CONTROLLABLE:PatrolZones( ZoneList, Speed, Formation ) 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 -- Create a "ground route point", which is a "point" structure that can be given as a parameter to a Task
local Route = {} local Route = {}
Route[#Route+1] = FromCoord:WaypointGround( 120 ) Route[#Route+1] = FromCoord:WaypointGround( 20 )
Route[#Route+1] = ToCoord:WaypointGround( Speed, Formation ) 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. --- (AIR + GROUND) Make the Controllable move to fly to a given point.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param Dcs.DCSTypes#Vec3 Point The destination point in Vec3 format. -- @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 -- @return #CONTROLLABLE self
function CONTROLLABLE:RouteToVec2( Point, Speed ) function CONTROLLABLE:RouteToVec2( Point, Speed )
self:F2( { Point, Speed } ) self:F2( { Point, Speed } )
@@ -1825,7 +1831,7 @@ do -- Route methods
--- (AIR + GROUND) Make the Controllable move to a given point. --- (AIR + GROUND) Make the Controllable move to a given point.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param Dcs.DCSTypes#Vec3 Point The destination point in Vec3 format. -- @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 -- @return #CONTROLLABLE self
function CONTROLLABLE:RouteToVec3( Point, Speed ) function CONTROLLABLE:RouteToVec3( Point, Speed )
self:F2( { Point, Speed } ) self:F2( { Point, Speed } )
@@ -1882,7 +1888,7 @@ do -- Route methods
--- Make the controllable to follow a given route. --- Make the controllable to follow a given route.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param #table Route A table of Route Points. -- @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. -- @return #CONTROLLABLE The CONTROLLABLE.
function CONTROLLABLE:Route( Route, DelaySeconds ) function CONTROLLABLE:Route( Route, DelaySeconds )
self:F2( Route ) self:F2( Route )
@@ -1923,7 +1929,7 @@ do -- Route methods
--- Make the GROUND Controllable to drive towards a specific point. --- Make the GROUND Controllable to drive towards a specific point.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. -- @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 #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. -- @param #number DelaySeconds Wait for the specified seconds before executing the Route.
-- @return #CONTROLLABLE The CONTROLLABLE. -- @return #CONTROLLABLE The CONTROLLABLE.
@@ -1939,37 +1945,22 @@ do -- Route methods
return self return self
end 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 #CONTROLLABLE self
-- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. -- @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 #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.
-- @param #string OffRoadFormation (Optional) The formation at initial and final waypoint. Default is "Off Road".
-- @return #CONTROLLABLE The CONTROLLABLE. -- @return #CONTROLLABLE The CONTROLLABLE.
function CONTROLLABLE:RouteGroundOnRoad( ToCoordinate, Speed, DelaySeconds ) function CONTROLLABLE:RouteGroundOnRoad( ToCoordinate, Speed, DelaySeconds, OffRoadFormation )
-- Current coordinate. -- Defaults.
local FromCoordinate = self:GetCoordinate() Speed=Speed or 20
DelaySeconds=DelaySeconds or 1
-- Formation is set to on road. OffRoadFormation=OffRoadFormation or "Off Road"
local Formation="On Road"
-- Get the route task.
-- Path on road from current position to destination coordinate. local route=self:TaskGroundOnRoad(ToCoordinate, Speed, OffRoadFormation)
local path=FromCoordinate:GetPathOnRoad(ToCoordinate)
-- Route, ground waypoints along roads.
local route={}
table.insert(route, FromCoordinate:WaypointGround(Speed, Formation))
-- 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])
if dist>10 then
table.insert(route, ToCoordinate:WaypointGround(Speed, "Vee"))
end
-- Route controllable to destination. -- Route controllable to destination.
self:Route( route, DelaySeconds ) self:Route( route, DelaySeconds )
@@ -1978,39 +1969,43 @@ do -- Route methods
end 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 #CONTROLLABLE self
-- @param Core.Point#COORDINATE ToCoordinate A Coordinate to drive to. -- @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 EndPointFormation The formation to achieve at the end point. -- @param #string OffRoadFormation (Optional) The formation at initial and final waypoint. Default is "Off Road".
-- @return Task -- @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. -- Current coordinate.
local FromCoordinate = self:GetCoordinate() local FromCoordinate = self:GetCoordinate()
-- Formation is set to on road. -- First point on road.
local Formation="On Road" local FromOnRoad = FromCoordinate:GetClosestPointToRoad()
-- Path on road from current position to destination coordinate.
local path=FromCoordinate:GetPathOnRoad( ToCoordinate )
-- Route, ground waypoints along roads. -- Last Point on road.
local Route = {} local ToOnRoad = ToCoordinate:GetClosestPointToRoad()
table.insert( Route, FromCoordinate:WaypointGround( Speed, Formation ) )
-- Route, ground waypoints along road.
local route={}
-- Convert coordinates to ground waypoints and insert into table. -- Create waypoints.
for _, coord in ipairs(path) do table.insert(route, FromCoordinate:WaypointGround(Speed, OffRoadFormation))
table.insert( Route, coord:WaypointGround( Speed, Formation ) ) table.insert(route, FromOnRoad:WaypointGround(Speed, "On Road"))
end table.insert(route, ToOnRoad:WaypointGround(Speed, "On Road"))
-- Add the final coordinate because the final coordinate in path is last point on road. -- Add the final coordinate because the final might not be on the road.
local dist=ToCoordinate:Get2DDistance(path[#path]) local dist=ToCoordinate:Get2DDistance(ToOnRoad)
if dist>10 then if dist>10 then
table.insert( Route, ToCoordinate:WaypointGround( Speed, EndPointFormation ) ) table.insert(route, ToCoordinate:WaypointGround(Speed, OffRoadFormation))
end end
return Route return route
end end
@@ -2020,7 +2015,7 @@ do -- Route methods
-- @param Core.Point#COORDINATE.RoutePointAltType AltType The altitude type. -- @param Core.Point#COORDINATE.RoutePointAltType AltType The altitude type.
-- @param Core.Point#COORDINATE.RoutePointType Type The route point type. -- @param Core.Point#COORDINATE.RoutePointType Type The route point type.
-- @param Core.Point#COORDINATE.RoutePointAction Action The route point action. -- @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. -- @param #number DelaySeconds Wait for the specified seconds before executing the Route.
-- @return #CONTROLLABLE The CONTROLLABLE. -- @return #CONTROLLABLE The CONTROLLABLE.
function CONTROLLABLE:RouteAirTo( ToCoordinate, AltType, Type, Action, Speed, DelaySeconds ) function CONTROLLABLE:RouteAirTo( ToCoordinate, AltType, Type, Action, Speed, DelaySeconds )
@@ -2043,7 +2038,7 @@ do -- Route methods
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param Core.Zone#ZONE Zone The zone where to route to. -- @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 #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. -- @param Base#FORMATION Formation The formation string.
function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation ) function CONTROLLABLE:TaskRouteToZone( Zone, Randomize, Speed, Formation )
self:F2( Zone ) self:F2( Zone )
@@ -2059,7 +2054,7 @@ do -- Route methods
PointFrom.y = ControllablePoint.y PointFrom.y = ControllablePoint.y
PointFrom.type = "Turning Point" PointFrom.type = "Turning Point"
PointFrom.action = Formation or "Cone" PointFrom.action = Formation or "Cone"
PointFrom.speed = 20 / 1.6 PointFrom.speed = 20 / 3.6
local PointTo = {} local PointTo = {}
@@ -2084,7 +2079,7 @@ do -- Route methods
if Speed then if Speed then
PointTo.speed = Speed PointTo.speed = Speed
else else
PointTo.speed = 20 / 1.6 PointTo.speed = 20 / 3.6
end end
local Points = { PointFrom, PointTo } local Points = { PointFrom, PointTo }
@@ -2104,7 +2099,7 @@ do -- Route methods
-- A given formation can be given. -- A given formation can be given.
-- @param #CONTROLLABLE self -- @param #CONTROLLABLE self
-- @param #Vec2 Vec2 The Vec2 where to route to. -- @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. -- @param Base#FORMATION Formation The formation string.
function CONTROLLABLE:TaskRouteToVec2( Vec2, Speed, Formation ) function CONTROLLABLE:TaskRouteToVec2( Vec2, Speed, Formation )
@@ -2119,7 +2114,7 @@ do -- Route methods
PointFrom.y = ControllablePoint.y PointFrom.y = ControllablePoint.y
PointFrom.type = "Turning Point" PointFrom.type = "Turning Point"
PointFrom.action = Formation or "Cone" PointFrom.action = Formation or "Cone"
PointFrom.speed = 20 / 1.6 PointFrom.speed = 20 / 3.6
local PointTo = {} local PointTo = {}
@@ -2137,7 +2132,7 @@ do -- Route methods
if Speed then if Speed then
PointTo.speed = Speed PointTo.speed = Speed
else else
PointTo.speed = 60 / 3.6 PointTo.speed = 20 / 3.6
end end
local Points = { PointFrom, PointTo } local Points = { PointFrom, PointTo }

View File

@@ -350,6 +350,37 @@ function GROUP:GetCountry()
return nil return nil
end 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<speedmax then
speedmax=speed
end
end
return speedmax
end
return nil
end
--- Returns a list of @{Wrapper.Unit} objects of the @{Wrapper.Group}. --- Returns a list of @{Wrapper.Unit} objects of the @{Wrapper.Group}.
-- @param #GROUP self -- @param #GROUP self
-- @return #list<Wrapper.Unit#UNIT> The list of @{Wrapper.Unit} objects of the @{Wrapper.Group}. -- @return #list<Wrapper.Unit#UNIT> The list of @{Wrapper.Unit} objects of the @{Wrapper.Group}.

View File

@@ -401,6 +401,23 @@ function UNIT:GetNumber()
return nil return nil
end 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. --- Returns the unit's group if it exist and nil otherwise.
-- @param Wrapper.Unit#UNIT self -- @param Wrapper.Unit#UNIT self
-- @return Wrapper.Group#GROUP The Group of the Unit. -- @return Wrapper.Group#GROUP The Group of the Unit.