mirror of
https://github.com/FlightControl-Master/MOOSE.git
synced 2025-10-29 16:58:06 +00:00
Improvements and Fixes from FF/Develop
This commit is contained in:
@@ -216,7 +216,7 @@
|
||||
-- One way to determin which types of ammo the unit carries, one can use the debug mode of the arty class via @{#ARTY.SetDebugON}().
|
||||
-- In debug mode, the all ammo types of the group are printed to the monitor as message and can be found in the DCS.log file.
|
||||
--
|
||||
-- ## Empoying Selected Weapons
|
||||
-- ## Employing Selected Weapons
|
||||
--
|
||||
-- If an ARTY group carries multiple weapons, which can be used for artillery task, a certain weapon type can be selected to attack the target.
|
||||
-- This is done via the *weapontype* parameter of the @{#ARTY.AssignTargetCoord}(..., *weapontype*, ...) function.
|
||||
@@ -674,11 +674,13 @@ ARTY.id="ARTY | "
|
||||
|
||||
--- Arty script version.
|
||||
-- @field #string version
|
||||
ARTY.version="1.0.6"
|
||||
ARTY.version="1.0.7"
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
-- TODO list:
|
||||
-- TODO: Add hit event and make the arty group relocate.
|
||||
-- TODO: Handle rearming for ships. How?
|
||||
-- DONE: Delete targets from queue user function.
|
||||
-- DONE: Delete entire target queue user function.
|
||||
-- DONE: Add weapon types. Done but needs improvements.
|
||||
@@ -697,11 +699,9 @@ ARTY.version="1.0.6"
|
||||
-- DONE: Add command move to make arty group move.
|
||||
-- DONE: remove schedulers for status event.
|
||||
-- DONE: Improve handling of special weapons. When winchester if using selected weapons?
|
||||
-- TODO: Handle rearming for ships. How?
|
||||
-- DONE: Make coordinate after rearming general, i.e. also work after the group has moved to anonther location.
|
||||
-- DONE: Add set commands via markers. E.g. set rearming place.
|
||||
-- DONE: Test stationary types like mortas ==> rearming etc.
|
||||
-- TODO: Add hit event and make the arty group relocate.
|
||||
-- DONE: Add illumination and smoke.
|
||||
|
||||
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
@@ -2878,7 +2878,7 @@ function ARTY:onafterCeaseFire(Controllable, From, Event, To, target)
|
||||
self.Controllable:ClearTasks()
|
||||
|
||||
else
|
||||
self:E(ARTY.id.."ERROR: No target in cease fire for group %s.", self.groupname)
|
||||
self:E(ARTY.id..string.format("ERROR: No target in cease fire for group %s.", self.groupname))
|
||||
end
|
||||
|
||||
-- Set number of shots to zero.
|
||||
@@ -4253,101 +4253,116 @@ end
|
||||
-- @param #ARTY self
|
||||
function ARTY:_CheckTargetsInRange()
|
||||
|
||||
local targets2delete={}
|
||||
|
||||
for i=1,#self.targets do
|
||||
local _target=self.targets[i]
|
||||
|
||||
self:T3(ARTY.id..string.format("Before: Target %s - in range = %s", _target.name, tostring(_target.inrange)))
|
||||
|
||||
-- Check if target is in range.
|
||||
local _inrange,_toofar,_tooclose=self:_TargetInRange(_target)
|
||||
local _inrange,_toofar,_tooclose,_remove=self:_TargetInRange(_target)
|
||||
self:T3(ARTY.id..string.format("Inbetw: Target %s - in range = %s, toofar = %s, tooclose = %s", _target.name, tostring(_target.inrange), tostring(_toofar), tostring(_tooclose)))
|
||||
|
||||
-- Init default for assigning moves into range.
|
||||
local _movetowards=false
|
||||
local _moveaway=false
|
||||
if _remove then
|
||||
|
||||
if _target.inrange==nil then
|
||||
|
||||
-- First time the check is performed. We call the function again and send a message.
|
||||
_target.inrange,_toofar,_tooclose=self:_TargetInRange(_target, self.report or self.Debug)
|
||||
-- The ARTY group is immobile and not cargo but the target is not in range!
|
||||
table.insert(targets2delete, _target.name)
|
||||
|
||||
-- Send group towards/away from target.
|
||||
if _toofar then
|
||||
_movetowards=true
|
||||
elseif _tooclose then
|
||||
_moveaway=true
|
||||
end
|
||||
else
|
||||
|
||||
elseif _target.inrange==true then
|
||||
|
||||
-- Target was in range at previous check...
|
||||
|
||||
if _toofar then --...but is now too far away.
|
||||
_movetowards=true
|
||||
elseif _tooclose then --...but is now too close.
|
||||
_moveaway=true
|
||||
end
|
||||
|
||||
elseif _target.inrange==false then
|
||||
|
||||
-- Target was out of range at previous check.
|
||||
-- Init default for assigning moves into range.
|
||||
local _movetowards=false
|
||||
local _moveaway=false
|
||||
|
||||
if _inrange then
|
||||
-- Inform coalition that target is now in range.
|
||||
local text=string.format("%s, target %s is now in range.", self.alias, _target.name)
|
||||
self:T(ARTY.id..text)
|
||||
MESSAGE:New(text,10):ToCoalitionIf(self.Controllable:GetCoalition(), self.report or self.Debug)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Assign a relocation command so that the unit will be in range of the requested target.
|
||||
if self.autorelocate and (_movetowards or _moveaway) then
|
||||
|
||||
-- Get current position.
|
||||
local _from=self.Controllable:GetCoordinate()
|
||||
local _dist=_from:Get2DDistance(_target.coord)
|
||||
if _target.inrange==nil then
|
||||
|
||||
if _dist<=self.autorelocatemaxdist then
|
||||
|
||||
local _tocoord --Core.Point#COORDINATE
|
||||
local _name=""
|
||||
local _safetymargin=500
|
||||
|
||||
if _movetowards then
|
||||
-- First time the check is performed. We call the function again and send a message.
|
||||
_target.inrange,_toofar,_tooclose=self:_TargetInRange(_target, self.report or self.Debug)
|
||||
|
||||
-- Target was in range on previous check but now we are too far away.
|
||||
local _waytogo=_dist-self.maxrange+_safetymargin
|
||||
local _heading=self:_GetHeading(_from,_target.coord)
|
||||
_tocoord=_from:Translate(_waytogo, _heading)
|
||||
_name=string.format("%s, relocation to within max firing range of target %s", self.alias, _target.name)
|
||||
|
||||
elseif _moveaway then
|
||||
|
||||
-- Target was in range on previous check but now we are too far away.
|
||||
local _waytogo=_dist-self.minrange+_safetymargin
|
||||
local _heading=self:_GetHeading(_target.coord,_from)
|
||||
_tocoord=_from:Translate(_waytogo, _heading)
|
||||
_name=string.format("%s, relocation to within min firing range of target %s", self.alias, _target.name)
|
||||
|
||||
-- Send group towards/away from target.
|
||||
if _toofar then
|
||||
_movetowards=true
|
||||
elseif _tooclose then
|
||||
_moveaway=true
|
||||
end
|
||||
|
||||
-- Send info message.
|
||||
MESSAGE:New(_name.." assigned.", 10):ToCoalitionIf(self.Controllable:GetCoalition(), self.report or self.Debug)
|
||||
|
||||
-- Assign relocation move.
|
||||
self:AssignMoveCoord(_tocoord, nil, nil, self.autorelocateonroad, false, _name, true)
|
||||
|
||||
elseif _target.inrange==true then
|
||||
|
||||
-- Target was in range at previous check...
|
||||
|
||||
if _toofar then --...but is now too far away.
|
||||
_movetowards=true
|
||||
elseif _tooclose then --...but is now too close.
|
||||
_moveaway=true
|
||||
end
|
||||
|
||||
elseif _target.inrange==false then
|
||||
|
||||
-- Target was out of range at previous check.
|
||||
|
||||
if _inrange then
|
||||
-- Inform coalition that target is now in range.
|
||||
local text=string.format("%s, target %s is now in range.", self.alias, _target.name)
|
||||
self:T(ARTY.id..text)
|
||||
MESSAGE:New(text,10):ToCoalitionIf(self.Controllable:GetCoalition(), self.report or self.Debug)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Assign a relocation command so that the unit will be in range of the requested target.
|
||||
if self.autorelocate and (_movetowards or _moveaway) then
|
||||
|
||||
-- Get current position.
|
||||
local _from=self.Controllable:GetCoordinate()
|
||||
local _dist=_from:Get2DDistance(_target.coord)
|
||||
|
||||
if _dist<=self.autorelocatemaxdist then
|
||||
|
||||
local _tocoord --Core.Point#COORDINATE
|
||||
local _name=""
|
||||
local _safetymargin=500
|
||||
|
||||
if _movetowards then
|
||||
|
||||
-- Target was in range on previous check but now we are too far away.
|
||||
local _waytogo=_dist-self.maxrange+_safetymargin
|
||||
local _heading=self:_GetHeading(_from,_target.coord)
|
||||
_tocoord=_from:Translate(_waytogo, _heading)
|
||||
_name=string.format("%s, relocation to within max firing range of target %s", self.alias, _target.name)
|
||||
|
||||
elseif _moveaway then
|
||||
|
||||
-- Target was in range on previous check but now we are too far away.
|
||||
local _waytogo=_dist-self.minrange+_safetymargin
|
||||
local _heading=self:_GetHeading(_target.coord,_from)
|
||||
_tocoord=_from:Translate(_waytogo, _heading)
|
||||
_name=string.format("%s, relocation to within min firing range of target %s", self.alias, _target.name)
|
||||
|
||||
end
|
||||
|
||||
-- Send info message.
|
||||
MESSAGE:New(_name.." assigned.", 10):ToCoalitionIf(self.Controllable:GetCoalition(), self.report or self.Debug)
|
||||
|
||||
-- Assign relocation move.
|
||||
self:AssignMoveCoord(_tocoord, nil, nil, self.autorelocateonroad, false, _name, true)
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- Update value.
|
||||
_target.inrange=_inrange
|
||||
|
||||
self:T3(ARTY.id..string.format("After: Target %s - in range = %s", _target.name, tostring(_target.inrange)))
|
||||
end
|
||||
|
||||
-- Update value.
|
||||
_target.inrange=_inrange
|
||||
|
||||
self:T3(ARTY.id..string.format("After: Target %s - in range = %s", _target.name, tostring(_target.inrange)))
|
||||
|
||||
end
|
||||
|
||||
-- Remove targets not in range.
|
||||
for _,targetname in pairs(targets2delete) do
|
||||
self:RemoveTarget(targetname)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
--- Check all normal (untimed) targets and return the target with the highest priority which has been engaged the fewest times.
|
||||
@@ -4728,6 +4743,7 @@ end
|
||||
-- @return #boolean True if target is in range, false otherwise.
|
||||
-- @return #boolean True if ARTY group is too far away from the target, i.e. distance > max firing range.
|
||||
-- @return #boolean True if ARTY group is too close to the target, i.e. distance < min finring range.
|
||||
-- @return #boolean True if target should be removed since ARTY group is immobile and not cargo.
|
||||
function ARTY:_TargetInRange(target, message)
|
||||
self:F3(target)
|
||||
|
||||
@@ -4763,11 +4779,13 @@ function ARTY:_TargetInRange(target, message)
|
||||
end
|
||||
|
||||
-- Remove target if ARTY group cannot move, e.g. Mortas. No chance to be ever in range - unless they are cargo.
|
||||
local _remove=false
|
||||
if not (self.ismobile or self.iscargo) and _inrange==false then
|
||||
self:RemoveTarget(target.name)
|
||||
--self:RemoveTarget(target.name)
|
||||
_remove=true
|
||||
end
|
||||
|
||||
return _inrange,_toofar,_tooclose
|
||||
return _inrange,_toofar,_tooclose,_remove
|
||||
end
|
||||
|
||||
--- Get the weapon type name, which should be used to attack the target.
|
||||
|
||||
@@ -1012,7 +1012,7 @@ do -- DETECTION_BASE
|
||||
--- Set the parameters to calculate to optimal intercept point.
|
||||
-- @param #DETECTION_BASE self
|
||||
-- @param #boolean Intercept Intercept is true if an intercept point is calculated. Intercept is false if it is disabled. The default Intercept is false.
|
||||
-- @param #number IntereptDelay If Intercept is true, then InterceptDelay is the average time it takes to get airplanes airborne.
|
||||
-- @param #number InterceptDelay If Intercept is true, then InterceptDelay is the average time it takes to get airplanes airborne.
|
||||
-- @return #DETECTION_BASE self
|
||||
function DETECTION_BASE:SetIntercept( Intercept, InterceptDelay )
|
||||
self:F2()
|
||||
|
||||
@@ -5435,7 +5435,7 @@ function RAT:_ATCInit(airports_map)
|
||||
if not RAT.ATC.init then
|
||||
local text
|
||||
text="Starting RAT ATC.\nSimultanious = "..RAT.ATC.Nclearance.."\n".."Delay = "..RAT.ATC.delay
|
||||
self:T(RAT.id..text)
|
||||
BASE:T(RAT.id..text)
|
||||
RAT.ATC.init=true
|
||||
for _,ap in pairs(airports_map) do
|
||||
local name=ap:GetName()
|
||||
@@ -5458,7 +5458,7 @@ end
|
||||
-- @param #string name Group name of the flight.
|
||||
-- @param #string dest Name of the destination airport.
|
||||
function RAT:_ATCAddFlight(name, dest)
|
||||
self:T(string.format("%sATC %s: Adding flight %s with destination %s.", RAT.id, dest, name, dest))
|
||||
BASE:T(string.format("%sATC %s: Adding flight %s with destination %s.", RAT.id, dest, name, dest))
|
||||
RAT.ATC.flight[name]={}
|
||||
RAT.ATC.flight[name].destination=dest
|
||||
RAT.ATC.flight[name].Tarrive=-1
|
||||
@@ -5483,7 +5483,7 @@ end
|
||||
-- @param #string name Group name of the flight.
|
||||
-- @param #number time Time the fight first registered.
|
||||
function RAT:_ATCRegisterFlight(name, time)
|
||||
self:T(RAT.id.."Flight ".. name.." registered at ATC for landing clearance.")
|
||||
BASE:T(RAT.id.."Flight ".. name.." registered at ATC for landing clearance.")
|
||||
RAT.ATC.flight[name].Tarrive=time
|
||||
RAT.ATC.flight[name].holding=0
|
||||
end
|
||||
@@ -5514,7 +5514,7 @@ function RAT:_ATCStatus()
|
||||
|
||||
-- Aircraft is holding.
|
||||
local text=string.format("ATC %s: Flight %s is holding for %i:%02d. %s.", dest, name, hold/60, hold%60, busy)
|
||||
self:T(RAT.id..text)
|
||||
BASE:T(RAT.id..text)
|
||||
|
||||
elseif hold==RAT.ATC.onfinal then
|
||||
|
||||
@@ -5522,7 +5522,7 @@ function RAT:_ATCStatus()
|
||||
local Tfinal=Tnow-RAT.ATC.flight[name].Tonfinal
|
||||
|
||||
local text=string.format("ATC %s: Flight %s is on final. Waiting %i:%02d for landing event.", dest, name, Tfinal/60, Tfinal%60)
|
||||
self:T(RAT.id..text)
|
||||
BASE:T(RAT.id..text)
|
||||
|
||||
elseif hold==RAT.ATC.unregistered then
|
||||
|
||||
@@ -5530,7 +5530,7 @@ function RAT:_ATCStatus()
|
||||
--self:T(string.format("ATC %s: Flight %s is not registered yet (hold %d).", dest, name, hold))
|
||||
|
||||
else
|
||||
self:E(RAT.id.."ERROR: Unknown holding time in RAT:_ATCStatus().")
|
||||
BASE:E(RAT.id.."ERROR: Unknown holding time in RAT:_ATCStatus().")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5572,12 +5572,12 @@ function RAT:_ATCCheck()
|
||||
|
||||
-- Debug message.
|
||||
local text=string.format("ATC %s: Flight %s runway is busy. You are #%d of %d in landing queue. Your holding time is %i:%02d.", name, flight,qID, nqueue, RAT.ATC.flight[flight].holding/60, RAT.ATC.flight[flight].holding%60)
|
||||
self:T(RAT.id..text)
|
||||
BASE:T(RAT.id..text)
|
||||
|
||||
else
|
||||
|
||||
local text=string.format("ATC %s: Flight %s was cleared for landing. Your holding time was %i:%02d.", name, flight, RAT.ATC.flight[flight].holding/60, RAT.ATC.flight[flight].holding%60)
|
||||
self:T(RAT.id..text)
|
||||
BASE:T(RAT.id..text)
|
||||
|
||||
-- Clear flight for landing.
|
||||
RAT:_ATCClearForLanding(name, flight)
|
||||
@@ -5705,12 +5705,7 @@ function RAT:_ATCQueue()
|
||||
for k,v in ipairs(_queue) do
|
||||
table.insert(RAT.ATC.airport[airport].queue, v[1])
|
||||
end
|
||||
|
||||
--fvh
|
||||
--for k,v in ipairs(RAT.ATC.airport[airport].queue) do
|
||||
--print(string.format("queue #%02i flight \"%s\" holding %d seconds",k, v, RAT.ATC.flight[v].holding))
|
||||
--end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -276,7 +276,7 @@ RANGE.id="RANGE | "
|
||||
|
||||
--- Range script version.
|
||||
-- @field #string version
|
||||
RANGE.version="1.2.1"
|
||||
RANGE.version="1.2.3"
|
||||
|
||||
--TODO list:
|
||||
--TODO: Add custom weapons, which can be specified by the user.
|
||||
@@ -460,9 +460,10 @@ 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 location of the range.
|
||||
-- The range location determines the position at which the weather data is evaluated.
|
||||
-- @param #RANGE self
|
||||
-- @param Core.Point#COORDINATE coordinate Coordinate of the center of the range.
|
||||
-- @param Core.Point#COORDINATE coordinate Coordinate of the range.
|
||||
function RANGE:SetRangeLocation(coordinate)
|
||||
self.location=coordinate
|
||||
end
|
||||
@@ -471,7 +472,7 @@ end
|
||||
-- If a zone is not explicitly specified, the range zone is determined by its location and radius.
|
||||
-- @param #RANGE self
|
||||
-- @param Core.Zone#ZONE zone MOOSE zone defining the range perimeters.
|
||||
function RANGE:SetRangeLocation(zone)
|
||||
function RANGE:SetRangeZone(zone)
|
||||
self.rangezone=zone
|
||||
end
|
||||
|
||||
@@ -1163,11 +1164,19 @@ function RANGE:OnEventShot(EventData)
|
||||
-- Coordinate of impact point.
|
||||
local impactcoord=COORDINATE:NewFromVec3(_lastBombPos)
|
||||
|
||||
-- Check if impact happend in range zone.
|
||||
local insidezone=self.rangezone:IsCoordinateInZone(impactcoord)
|
||||
|
||||
-- Distance from range. We dont want to smoke targets outside of the range.
|
||||
local impactdist=impactcoord:Get2DDistance(self.location)
|
||||
|
||||
-- Impact point of bomb.
|
||||
if self.Debug then
|
||||
impactcoord:MarkToAll("Bomb impact point")
|
||||
end
|
||||
|
||||
-- Smoke impact point of bomb.
|
||||
if self.PlayerSettings[_playername].smokebombimpact and impactdist<self.rangeradius then
|
||||
if self.PlayerSettings[_playername].smokebombimpact and insidezone then
|
||||
if self.PlayerSettings[_playername].delaysmoke then
|
||||
timer.scheduleFunction(self._DelayedSmoke, {coord=impactcoord, color=self.PlayerSettings[_playername].smokecolor}, timer.getTime() + self.TdelaySmoke)
|
||||
else
|
||||
@@ -1184,6 +1193,8 @@ function RANGE:OnEventShot(EventData)
|
||||
|
||||
-- Distance between bomb and target.
|
||||
local _temp = impactcoord:Get2DDistance(_target:GetCoordinate())
|
||||
|
||||
--env.info(string.format("FF target = %s dist = %d m", _target:GetName(), _temp))
|
||||
|
||||
-- Find closest target to last known position of the bomb.
|
||||
if _distance == nil or _temp < _distance then
|
||||
@@ -1203,7 +1214,7 @@ function RANGE:OnEventShot(EventData)
|
||||
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
|
||||
|
||||
-- Init bomb player results.
|
||||
@@ -1222,10 +1233,10 @@ function RANGE:OnEventShot(EventData)
|
||||
|
||||
-- Send message.
|
||||
self:_DisplayMessageToGroup(_unit, _message, nil, true)
|
||||
elseif _distance <= self.rangeradius then
|
||||
elseif insidezone 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)
|
||||
self:_DisplayMessageToGroup(_unit, _message, nil, false)
|
||||
end
|
||||
|
||||
--Terminate the timer
|
||||
|
||||
Reference in New Issue
Block a user