Dateien nach "/" hochladen
This commit is contained in:
parent
e6ffcfba68
commit
84e10c1e9e
81
CA BSA3.lua
Normal file
81
CA BSA3.lua
Normal file
@ -0,0 +1,81 @@
|
||||
--[[
|
||||
Targets fot TITS v2.0Xx
|
||||
]]--
|
||||
|
||||
|
||||
--[[ Add target parameters
|
||||
function TITS.AddTarget(
|
||||
_TargetName -- UNIQUE! Target name
|
||||
, _DisplayName -- display name, accepts duplicates, if empty _TargetName will be used
|
||||
, _Type -- [ unit | zone | static ] must be in lower case
|
||||
, _Respawn -- Only for units. if true, unit can be respawned. Respwan will only happen when ALL the units in the group are destroyed
|
||||
, _TrackImpact -- use target to calculate distance to impact
|
||||
, _TrackStrafing -- count strafing hits on target
|
||||
, _ReportHits -- reports splash damage from weapons
|
||||
, _AllowSmokeDesignation -- Allow use of smoke designation for target
|
||||
, _AllowLaserDesignation -- Allow use of laser designation for target
|
||||
, _AllowIRDesignation -- Allow use of IR designation for target
|
||||
, _AllowListCoordinates -- Allow list of target coordinates
|
||||
, _uiNum1 -- Numeric value for custom UI use
|
||||
, _uiNum2 -- Numeric value for custom UI use
|
||||
, _uiNum3 -- Numeric value for custom UI use
|
||||
, _uiBool1 -- Boolean value for custom UI use
|
||||
, _uiBool2 -- Boolean value for custom UI use
|
||||
, _uiBool3 -- Boolean value for custom UI use
|
||||
, _uiText1 -- Text value for custom UI use
|
||||
, _uiText2 -- Text value for custom UI use
|
||||
, _uiText3 -- Text value for custom UI use
|
||||
)
|
||||
|
||||
--]]
|
||||
|
||||
UI.MagneticVar = 6
|
||||
|
||||
-- Load Targets
|
||||
-- Display Track Track Report Designation Allow Smoke Allow Laser Allow IR Allow Nomark List UI UI UI UI UI UI UI UI UI
|
||||
-- Name name Type Reswpan Impact Strafing Hits Zone Designation Designation Designation designation Coords. Num1 Num2 Num3 Bool1 Bool2 Bool3 Text1 Text2 Text3
|
||||
|
||||
TITS.AddTarget( 'Circle-A', '', 'unit', true, true, true, true, 1, false, false, false, true, true, 0, 0, 0, false, false, false, '', '', '' )
|
||||
TITS.AddTarget( 'Circle-B', '', 'unit', true, true, true, true, 1, false, false, false, true, true, 0, 0, 0, false, false, false, '', '', '' )
|
||||
TITS.AddTarget( 'Strafe Pit' ,'', 'unit', true, true, true, true, 1, false, false, false, true, true, 0, 0, 0, false, false, false, '', '', '' )
|
||||
TITS.AddTarget( 'Tank', '', 'unit', true, true, true, true, 1, true, true, true, true, false, 0, 0, 0, false, false, false, 'Left target', '', '' )
|
||||
TITS.AddTarget( 'Truck', '', 'unit', true, true, true, true, 1, true, true, true, true, false, 0, 0, 0, false, false, false, 'Right Target', '', '' )
|
||||
|
||||
TITS.AddTarget( 'Ground-23-1','Bridge-1', 'poly', true, true, true, true, 2, true, true, true, true, true, 0, 0, 0, false, false, false, 'It is oriented in the 147°/327° (mmagnetic) radial', '', '' )
|
||||
TITS.AddTarget( 'white','Goverment bldg.', 'unit', true, true, true, true, 2, true, true, true, true, true, 0, 0, 0, false, false, false, 'White Building.', 'North of the Bridge', '' )
|
||||
TITS.AddTarget( 'red', 'Factory', 'unit', true, true, true, true, 2, true, true, true, true, true, 0, 0, 0, false, false, false, 'Red Building', 'West of the Bridge', '' )
|
||||
TITS.AddTarget( 'wAr','Refinary', 'unit', true, true, true, true, 2, true, true, true, true, true, 0, 0, 0, false, false, false, 'White and Red Building', 'South of th Bridge', '' )
|
||||
|
||||
|
||||
|
||||
|
||||
-- Laod laser/ir designator list
|
||||
-- name displayName zones allowLaser allowIR laser code
|
||||
UI.AddDesignator( 'Predator' , '' , {1,2} , true , true , '1688' )
|
||||
|
||||
|
||||
|
||||
-- Engagement Zones
|
||||
-- Name Type
|
||||
UI.AddEngagementZone ( 'Engagement Zone', 'zone' )
|
||||
|
||||
--designation zones
|
||||
UI.AddDesignationZone( 1, 'BSA' )
|
||||
UI.AddDesignationZone( 2, 'Structures' )
|
||||
|
||||
|
||||
-- Illumination Zones (circular ME zones)
|
||||
-- Name Number of shells per round
|
||||
UI.AddIlluminationZone( 'Illumination-1', 3 )
|
||||
UI.AddIlluminationZone( 'Illumination-2', 2 )
|
||||
|
||||
-- Confirm load
|
||||
trigger.action.outText( "CA BSA 3 targets", 2 )
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2345
Range_UI.1.3.lua
Normal file
2345
Range_UI.1.3.lua
Normal file
File diff suppressed because it is too large
Load Diff
1310
TargetImpactTracker-2.3.lua
Normal file
1310
TargetImpactTracker-2.3.lua
Normal file
File diff suppressed because it is too large
Load Diff
662
TargetImpactTracker.lua
Normal file
662
TargetImpactTracker.lua
Normal file
@ -0,0 +1,662 @@
|
||||
--[[
|
||||
|
||||
DCS - Target Impact Tracker Script - Range Control
|
||||
by Draken35
|
||||
|
||||
Requires MIST 4.4.90 or above <https://github.com/mrSkortch/MissionScriptingTools/tree/master>
|
||||
|
||||
Version history
|
||||
1.00 10/04/2021 Initial release / Development start
|
||||
|
||||
|
||||
|
||||
--]]
|
||||
|
||||
TITS = {}
|
||||
trigger.action.outText( 'Target Impact Tracker Script- V1.00', 2 )
|
||||
|
||||
|
||||
--############################################################################################################################################
|
||||
-- ############# Configuration section #############
|
||||
--############################################################################################################################################
|
||||
TITS.MaxMissDistance = 1000 -- Any impact over this distance from the closest target will be considered as Miss
|
||||
|
||||
TITS.TargetList = {} -- These are the targets that the script handles
|
||||
-- for the unit, use the UNIT name, not the group.
|
||||
-- Only units can be strafed and have a bda (hit)
|
||||
-- target names need to be UNIQUE. It is also case sensitive.
|
||||
-- impact = true will consider the target when calculating the closest target to the weapon impact. If false it will not be considered.
|
||||
-- strafing = true will allow the target to count strafing hits. If false, it will not
|
||||
-- bda = true will make the script check if the target was in the weapon blast radio and was "hit" by the blast. If false, it will not
|
||||
-- The existance or type of the targets IS NOT VALIDATED by the script to save some CPU cycles. Make sure the list match the mission
|
||||
|
||||
table.insert(TITS.TargetList, { name = 'Circle A', type = 'unit', impact =true, strafing = true, bda = true })
|
||||
table.insert(TITS.TargetList, { name = 'Moving Target', type = 'unit', impact =true, strafing = true, bda = true })
|
||||
table.insert(TITS.TargetList, { name = 'Circle B', type = 'zone', impact =true, strafing = false, bda = false })
|
||||
table.insert(TITS.TargetList, { name = 'Blue Sealand', type = 'unit', impact =false, strafing = true, bda = true })
|
||||
table.insert(TITS.TargetList, { name = 'Brown Sealand', type = 'unit', impact =false, strafing = true, bda = true })
|
||||
table.insert(TITS.TargetList, { name = 'Green Sealand', type = 'unit', impact =false, strafing = true, bda = true })
|
||||
table.insert(TITS.TargetList, { name = 'Tan Sealand', type = 'unit', impact =false, strafing = true, bda = true })
|
||||
table.insert(TITS.TargetList, { name = 'Strafe pit', type = 'unit', impact =false, strafing = true, bda = false })
|
||||
|
||||
|
||||
--############################################################################################################################################
|
||||
-- ############# Sound Files #############
|
||||
--############################################################################################################################################
|
||||
TITS.messageBeep = '204521__redoper__roger-beep.ogg' -- leave empty for no sound
|
||||
|
||||
|
||||
|
||||
--############################################################################################################################################
|
||||
-- ############# Code section #############
|
||||
--############################################################################################################################################
|
||||
-- Initialization of globals
|
||||
|
||||
TITS.eventHandler = {}
|
||||
TITS.menuAddedToGroup = {}
|
||||
TITS.attackingUnits = {}
|
||||
TITS.isStrafingAttack = {}
|
||||
TITS.reportWeaponsDistance = {} -- report non-strafing hits
|
||||
TITS.reportWeaponsHits = {} -- report non-strafing hits
|
||||
TITS.strafingHitCounter = {}
|
||||
TITS.weponsHit = {}
|
||||
TITS.rootPath = {}
|
||||
TITS.rollInPath = {}
|
||||
TITS.offPath = {}
|
||||
TITS.lastAbortMSG = {}
|
||||
TITS.passCounter = {}
|
||||
TITS.uom ={} -- 1 metric (kph), 2 imperial (knots) , 3 imperial (mph)
|
||||
TITS.DisplayDBA = {}
|
||||
TITS.DisplayReleaseData = {}
|
||||
|
||||
|
||||
--############################################################################################################################################
|
||||
function TITS.eventHandler:onEvent(_eventDCS)
|
||||
|
||||
if _eventDCS == nil or _eventDCS.initiator == nil then
|
||||
return true
|
||||
end
|
||||
|
||||
local status, err = pcall(function(_event)
|
||||
|
||||
|
||||
-- ### player entered unit _event.id == 15
|
||||
if _event.id == 15 then -- id == 15 Enter
|
||||
|
||||
TITS.EnterUnitEvent(_event)
|
||||
|
||||
elseif (_event.id == world.event.S_EVENT_SHOT) and _event.initiator:getPlayerName() then -- id == 1 Shot
|
||||
|
||||
TITS.ShotEvent(_event)
|
||||
|
||||
elseif _event.id == world.event.S_EVENT_HIT and _event.initiator:getPlayerName() then -- id == 2 Hit
|
||||
|
||||
TITS.HitEvent(_event)
|
||||
|
||||
elseif _event.id == world.event.S_EVENT_SHOOTING_START and _event.initiator:getPlayerName() then -- id == 23 Start Shooting
|
||||
|
||||
TITS.StartShootingEvent(_event)
|
||||
|
||||
end -- if _event.id == S_EVENT_PLAYER_ENTER_UNIT then --player entered unit
|
||||
-- ### End event processing
|
||||
|
||||
return true
|
||||
end, _eventDCS)
|
||||
|
||||
if (not status) then
|
||||
env.error(string.format("Target Impact Tracker: Error while handling event %s", err),false)
|
||||
trigger.action.outText( string.format("Target Impact Tracker: Error while handling event %s", err), 30 )
|
||||
end
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.EnterUnitEvent(_event)
|
||||
local groupID = _event.initiator:getGroup():getID()
|
||||
local unitName = _event.initiator:getName()
|
||||
|
||||
-- inits
|
||||
TITS.attackingUnits[unitName] = false
|
||||
TITS.reportWeaponsHits[unitName] = false
|
||||
TITS.lastAbortMSG[unitName] = timer.getTime() - 5
|
||||
TITS.passCounter[unitName] = 0
|
||||
TITS.uom[unitName] = 2 -- 1 metric (kph), 2 imperial (knots) , 3 imperial (mph)
|
||||
TITS.DisplayDBA[unitName] = true
|
||||
TITS.DisplayReleaseData[unitName] = true
|
||||
|
||||
-- Menu
|
||||
if not TITS.menuAddedToGroup[groupID] then
|
||||
TITS.rootPath[unitName] = missionCommands.addSubMenuForGroup(groupID, "Range")
|
||||
local _reportsPath = missionCommands.addSubMenuForGroup(groupID, "Reports", TITS.rootPath[unitName])
|
||||
missionCommands.addCommandForGroup(groupID,"Attack results" , _reportsPath, TITS.ReportAttackResults , unitName)
|
||||
|
||||
local _settingsPath = missionCommands.addSubMenuForGroup(groupID, "Settings", TITS.rootPath[unitName])
|
||||
missionCommands.addCommandForGroup(groupID,"Toggle non strafing hits (BDA) report" , _settingsPath, TITS.Settings , {unitName,1})
|
||||
missionCommands.addCommandForGroup(groupID,"Toggle display of Release data" , _settingsPath, TITS.Settings , {unitName,2})
|
||||
missionCommands.addCommandForGroup(groupID,"Use metric units" , _settingsPath, TITS.Settings , {unitName,3})
|
||||
missionCommands.addCommandForGroup(groupID,"Use imperial units (knots)" , _settingsPath, TITS.Settings , {unitName,4})
|
||||
missionCommands.addCommandForGroup(groupID,"Use imperial units (mph)" , _settingsPath, TITS.Settings , {unitName,5})
|
||||
|
||||
TITS.rollInPath[unitName] = missionCommands.addCommandForGroup(groupID,"Rolling in" , TITS.rootPath[unitName], TITS.ReportAttack , {unitName,'in'})
|
||||
|
||||
end -- if not TITS.menuAddedToGroup[groupID] then
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.ShotEvent(_event)
|
||||
local _weapon = _event.weapon
|
||||
local _target = _weapon:getTarget()
|
||||
local unitName = _event.initiator:getName()
|
||||
|
||||
if not TITS.attackingUnits[unitName] then
|
||||
local t = timer.getTime()
|
||||
if (t - TITS.lastAbortMSG[unitName]) > 5 then
|
||||
TITS.messageToUnit(unitName,'Abort! Abort! Abort!. You are not cleared to employ weapons.',{},10)
|
||||
TITS.lastAbortMSG[unitName] = t
|
||||
end
|
||||
else
|
||||
local params = {}
|
||||
params.unitName = _event.initiator:getName()
|
||||
params.releaseHeading = mist.utils.toDegree(mist.getHeading(_event.initiator)) -- in degrees. Players release heading
|
||||
local pos = _event.initiator:getPosition().p
|
||||
local height = land.getHeight({x = pos.x, y = pos.z})
|
||||
params.releaseAlt = pos.y - height -- in meters. Release AGL
|
||||
params.releasePitch = mist.utils.toDegree(mist.getClimbAngle(_event.initiator)) -- in degrees. Release dive angle
|
||||
params.releaseRoll = mist.utils.toDegree(mist.getRoll(_event.initiator)) -- in degrees.
|
||||
params.releaseYaw = mist.utils.toDegree(mist.getYaw(_event.initiator)) -- in degrees.
|
||||
params.releaseSpeed = mist.vec.mag(_event.initiator:getVelocity()) -- meters/second
|
||||
params.weapon = _weapon
|
||||
params.weponName = _weapon:getTypeName()
|
||||
params.weaponID = _weapon:getName()
|
||||
params.weaponLastPoint = _weapon:getPoint()
|
||||
|
||||
|
||||
timer.scheduleFunction(TITS.TrackWeapon, params, timer.getTime() + 0.001 )
|
||||
end
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.StartShootingEvent(_event)
|
||||
local unitName = _event.initiator:getName()
|
||||
|
||||
|
||||
if not TITS.attackingUnits[unitName] then
|
||||
local t = timer.getTime()
|
||||
if (t - TITS.lastAbortMSG[unitName]) > 5 then
|
||||
TITS.messageToUnit(unitName,'Abort! Abort! Abort!. You are not cleared to employ weapons.',{},10)
|
||||
TITS.lastAbortMSG[unitName] = t
|
||||
end
|
||||
else
|
||||
TITS.isStrafingAttack[unitName] = true
|
||||
end
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.HitEvent(_event)
|
||||
local unitName = _event.initiator:getName()
|
||||
local eventTarget = _event.target
|
||||
local isStrafingWeapon = string.find(_event.weapon:getTypeName():lower(), "weapons.shell")
|
||||
local targetName = ''
|
||||
|
||||
if eventTarget then
|
||||
targetName = eventTarget:getName()
|
||||
end
|
||||
|
||||
|
||||
if TITS.attackingUnits[unitName] and targetName ~= '' then
|
||||
if isStrafingWeapon then
|
||||
local list = TITS.strafingHitCounter[unitName]
|
||||
for t,v in pairs(list) do
|
||||
|
||||
if t == targetName then
|
||||
|
||||
TITS.strafingHitCounter[unitName][targetName] = TITS.strafingHitCounter[unitName][targetName] + 1
|
||||
break
|
||||
end
|
||||
end
|
||||
else -- it goes big boom
|
||||
local target = TITS.getTarget(targetName)
|
||||
if target then
|
||||
if target.bda then
|
||||
-- record the target that got splashed by the weapon BDA
|
||||
local r = {
|
||||
weaponID = _event.weapon:getName()
|
||||
, weaponType = _event.weapon:getTypeName()
|
||||
, Target = targetName
|
||||
}
|
||||
table.insert(TITS.reportWeaponsHits[unitName],r)
|
||||
|
||||
end
|
||||
end
|
||||
end -- if isStrafingWeapon then
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.ReportAttack(_args)
|
||||
local unitName = _args[1]
|
||||
local value = _args[2]
|
||||
local groupID = Unit.getByName(unitName):getGroup():getID()
|
||||
|
||||
TITS.passCounter[unitName] = TITS.passCounter[unitName] + 1
|
||||
|
||||
TITS.attackingUnits[unitName] = (value == 'in')
|
||||
if TITS.attackingUnits[unitName] then
|
||||
TITS.messageToUnit(unitName,'Roger. Cleared in hot',{},10)
|
||||
-- reset non-strafing results
|
||||
TITS.ResetStrafingHitCounter(unitName)
|
||||
TITS.reportWeaponsDistance[unitName] = {}
|
||||
TITS.reportWeaponsHits[unitName] = {}
|
||||
missionCommands.removeItemForGroup(groupID, TITS.rollInPath[unitName])
|
||||
TITS.offPath[unitName] = missionCommands.addCommandForGroup(groupID,"Off - attack completed" , TITS.rootPath[unitName], TITS.ReportAttack , {unitName,'off'})
|
||||
else
|
||||
TITS.messageToUnit(unitName,'Roger. Standby for report',{},10)
|
||||
|
||||
TITS.ReportAttackResults(unitName)
|
||||
|
||||
missionCommands.removeItemForGroup(groupID, TITS.offPath[unitName])
|
||||
TITS.rollInPath[unitName] = missionCommands.addCommandForGroup(groupID,"Rolling in" , TITS.rootPath[unitName], TITS.ReportAttack , {unitName,'in'})
|
||||
end
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.ReportAttackResults(_unitName)
|
||||
local unit = Unit.getByName(_unitName)
|
||||
local player = unit:getPlayerName()
|
||||
local dist_uom
|
||||
|
||||
if TITS.uom[_unitName] == 1 then
|
||||
dist_uom = 'm'
|
||||
elseif TITS.uom[_unitName] == 2 then
|
||||
dist_uom = 'ft'
|
||||
else
|
||||
dist_uom = 'ft'
|
||||
end
|
||||
-- Strafing results
|
||||
local strafingResults = ''
|
||||
local unitTargetList = TITS.strafingHitCounter[_unitName]
|
||||
if TITS.strafingHitCounter[_unitName] ~= nil then
|
||||
for t,v in pairs(unitTargetList) do
|
||||
if v > 0 then
|
||||
local target = TITS.getTarget(t)
|
||||
if target then
|
||||
strafingResults = strafingResults..string.format("\n%s, %i hit(s)",target.name,v)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if TITS.isStrafingAttack[_unitName] then
|
||||
if strafingResults == '' then
|
||||
strafingResults = 'no targets hit'
|
||||
end
|
||||
strafingResults = 'Strafing attack: '.. strafingResults
|
||||
end
|
||||
|
||||
-- Impact distace results and BDA
|
||||
|
||||
local distanceResult = ''
|
||||
|
||||
for _,r in pairs(TITS.reportWeaponsDistance[_unitName]) do
|
||||
|
||||
local impact = 'Miss'
|
||||
local targetsHit = ''
|
||||
if r.impactDistance <= TITS.MaxMissDistance then
|
||||
impact = string.format("%s %s of %s @ %s o'clock"
|
||||
, math.floor(TITS.convertDistance(_unitName,r.impactDistance))
|
||||
, dist_uom
|
||||
, r.closestTarget
|
||||
, r.impactDirection
|
||||
)
|
||||
end
|
||||
------ BDA
|
||||
local targetsHit = ''
|
||||
for _,h in pairs(TITS.reportWeaponsHits[_unitName]) do
|
||||
if h.weaponID == r.weaponID then
|
||||
if not string.find(targetsHit, h.Target) then
|
||||
if targetsHit ~= '' then
|
||||
targetsHit = targetsHit..', '
|
||||
end
|
||||
targetsHit = targetsHit..h.Target
|
||||
end
|
||||
end
|
||||
end
|
||||
if targetsHit == '' then
|
||||
targetsHit = 'none'
|
||||
end
|
||||
|
||||
local tempStr = string.format( ">>> %s : %s"
|
||||
, r.weaponType
|
||||
, impact
|
||||
)
|
||||
if TITS.DisplayDBA[_unitName] then
|
||||
tempStr = string.format("%s\n Targets hit: %s",tempStr,targetsHit)
|
||||
end
|
||||
|
||||
|
||||
-- Release parameters
|
||||
local alt = string.format("%s",math.floor(TITS.convertDistance(_unitName,r.releaseAlt )+0.5))
|
||||
local Speed = string.format("%s",math.floor(TITS.convertSpeed(_unitName,r.releaseSpeed )+0.5))
|
||||
if TITS.uom[_unitName] == 1 then
|
||||
alt = alt..' m'
|
||||
Speed = Speed..' kph'
|
||||
elseif TITS.uom[_unitName] == 2 then
|
||||
alt = alt..' ft'
|
||||
Speed = Speed..' knots'
|
||||
else
|
||||
alt = alt..' ft'
|
||||
Speed = Speed..' mph'
|
||||
end
|
||||
local Pitch = string.format("%s°",math.floor((r.releasePitch+0.05) *100 )/100)
|
||||
local Roll = string.format("%s°",math.floor((r.releaseRoll +0.05) *100 )/100)
|
||||
local Yaw = string.format("%s°",math.floor((r.releaseYaw +0.05) *100 )/100)
|
||||
local relP = string.format(" Release Parameters:\n Alt: %s AGL Speed: %s\n P: %s R:%s Y:%s"
|
||||
, alt
|
||||
, Speed
|
||||
, Pitch
|
||||
, Roll
|
||||
, Yaw
|
||||
)
|
||||
|
||||
if TITS.DisplayReleaseData[_unitName] then
|
||||
tempStr = string.format("%s\n%s",tempStr,relP)
|
||||
end
|
||||
|
||||
if tempStr ~= '' then
|
||||
distanceResult = distanceResult..'\n'..tempStr
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local results = ''
|
||||
if strafingResults ~= '' then
|
||||
results = strafingResults..'\n\n'
|
||||
end
|
||||
if distanceResult ~= '' then
|
||||
results = results..distanceResult..'\n\n'
|
||||
end
|
||||
|
||||
TITS.messageToUnit(_unitName,results,{},45)
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.messageToUnit(_unitName,_messageText,_soundTable,_displayTime)
|
||||
local msg = {}
|
||||
|
||||
msg.text = _messageText
|
||||
msg.msgFor = {units = {_unitName}}
|
||||
|
||||
if TITS.messageBeep ~= '' then
|
||||
msg.sound = TITS.messageBeep
|
||||
end
|
||||
|
||||
if _soundTable ~= nil then
|
||||
msg.multSound = _soundTable
|
||||
end
|
||||
|
||||
if _displayTime == nil then
|
||||
_displayTime = 5
|
||||
end
|
||||
msg.displayTime = _displayTime
|
||||
|
||||
mist.message.add(msg)
|
||||
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.Settings(_args)
|
||||
local unitName = _args[1]
|
||||
local setting = _args[2]
|
||||
|
||||
if setting == 1 then -- Toggle non strafing hits report
|
||||
TITS.DisplayDBA[unitName] = not TITS.DisplayDBA[unitName]
|
||||
if TITS.DisplayDBA[unitName] then
|
||||
TITS.messageToUnit(unitName,'Non-strafing hits (BDA) reports is ON')
|
||||
else
|
||||
TITS.messageToUnit(unitName,'Non-strafing hits (BDA) reports is OFF')
|
||||
end
|
||||
elseif setting == 2 then -- Toggle display of Release data
|
||||
TITS.DisplayReleaseData[unitName] = not TITS.DisplayReleaseData[unitName]
|
||||
if TITS.DisplayReleaseData[unitName] then
|
||||
TITS.messageToUnit(unitName,'Release data display is ON')
|
||||
else
|
||||
TITS.messageToUnit(unitName,'Release data display is OFF')
|
||||
end
|
||||
elseif setting == 3 then -- use metric units
|
||||
TITS.uom[unitName] = 1 -- 1 metric (kph), 2 imperial (knots) , 3 imperial (mph)
|
||||
TITS.messageToUnit(unitName,'Using metric units')
|
||||
elseif setting == 4 then -- use imperial units(knots)
|
||||
TITS.uom[unitName] = 2 -- 1 metric (kph), 2 imperial (knots) , 3 imperial (mph)
|
||||
TITS.messageToUnit(unitName,'Using imperial units (knots)')
|
||||
elseif setting == 5 then -- use imperial units(mph
|
||||
TITS.uom[unitName] = 3 -- 1 metric (kph), 2 imperial (knots) , 3 imperial (mph)
|
||||
TITS.messageToUnit(unitName,'Using imperial units (mph)')
|
||||
end -- main if
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.ResetStrafingHitCounter(_unitName)
|
||||
|
||||
TITS.isStrafingAttack[_unitName] = false
|
||||
for _,t in pairs(TITS.TargetList) do
|
||||
if t.strafing and t.type == 'unit' then
|
||||
u = Unit.getByName(t.name)
|
||||
if u then
|
||||
if TITS.strafingHitCounter[_unitName] == nil then
|
||||
TITS.strafingHitCounter[_unitName] = {}
|
||||
end
|
||||
TITS.strafingHitCounter[_unitName][t.name] = 0
|
||||
-- else ignore it, doesn't exists
|
||||
end -- if u then
|
||||
end -- if t.strafing and type == 'unit'then
|
||||
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.getTarget(_name)
|
||||
for _,t in pairs(TITS.TargetList) do
|
||||
if t.name == _name then
|
||||
return t
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.TrackWeapon(params,time)
|
||||
|
||||
local _status,_weaponPos = pcall(function()
|
||||
return params.weapon:getPoint()
|
||||
end)
|
||||
if _status then
|
||||
-- weapon still in fly, update last point
|
||||
params.weaponLastPoint = _weaponPos
|
||||
return timer.getTime() + 0.001 -- keep tracking
|
||||
else -- wepon hit
|
||||
local target
|
||||
local targetPos
|
||||
local tempTarget
|
||||
local tempDist = nil
|
||||
local tempPos
|
||||
-- weapon had no valid target so look for the closest to impact
|
||||
for t,v in pairs(TITS.TargetList) do
|
||||
if v.impact then -- impact tracking target
|
||||
local oTarget
|
||||
local oTargetPos
|
||||
|
||||
if v.type == 'unit' then
|
||||
oTarget = Unit.getByName(v.name)
|
||||
oTargetPos = oTarget:getPoint()
|
||||
else -- it's a zone
|
||||
oTarget = trigger.misc.getZone(v.name)
|
||||
oTargetPos = oTarget.point
|
||||
end -- if v.type == 'unit' then
|
||||
local d = math.floor(TITS.getDistance(params.weaponLastPoint,oTargetPos)) -- in meters
|
||||
if tempDist then
|
||||
if d < tempDist then
|
||||
tempTarget = v.name
|
||||
tempPos = oTargetPos
|
||||
tempDist = d
|
||||
end -- if d < tempDist then
|
||||
else -- if tempDist then
|
||||
tempTarget = v.name
|
||||
tempPos = oTargetPos
|
||||
tempDist = d
|
||||
end -- if not tempDist then
|
||||
end --if v.impact then -- impact tracking target
|
||||
end -- for t,v in pairs(TITS.TargetList) do
|
||||
target = tempTarget
|
||||
targetPos = tempPos
|
||||
|
||||
|
||||
local _impactDistance = math.floor(TITS.getDistance(params.weaponLastPoint,targetPos)) -- in meters
|
||||
local _direction = TITS.getRelativeDirection(params.releaseHeading ,targetPos,params.weaponLastPoint)
|
||||
_direction = TITS.getClockDirection(_direction)
|
||||
|
||||
-- store the data
|
||||
|
||||
local r = {
|
||||
weaponID = params.weaponID
|
||||
, weaponType = params.weponName
|
||||
, intendedTarget = 'unk'
|
||||
, closestTarget = target
|
||||
, impactDistance = _impactDistance
|
||||
, impactDirection = _direction
|
||||
, releaseHeading = params.releaseHeading
|
||||
, releaseAlt = params.releaseAlt
|
||||
, releaseSpeed = params.releaseSpeed
|
||||
, releasePitch = params.releasePitch
|
||||
, releaseRoll = params.releaseRoll
|
||||
, releaseYaw = params.releaseYaw
|
||||
}
|
||||
if params.weponHasTarget then
|
||||
r.intendedTarget = params.target:getName()
|
||||
end
|
||||
table.insert(TITS.reportWeaponsDistance[params.unitName],r)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.convertSpeed(_unitName,_speed)
|
||||
local s
|
||||
-- 1 metric (kph), 2 imperial (knots) , 3 imperial (mph)
|
||||
if TITS.uom[_unitName] == 1 then
|
||||
s = _speed * 3.6
|
||||
elseif TITS.uom[_unitName] == 2 then
|
||||
s = _speed * 1.943844
|
||||
else
|
||||
s = _speed * 2.23694
|
||||
end
|
||||
return s
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.convertDistance(_unitName,_distance)
|
||||
local s
|
||||
-- 1 metric (kph), 2 imperial (knots) , 3 imperial (mph)
|
||||
if TITS.uom[_unitName] == 1 then
|
||||
s = _distance
|
||||
else
|
||||
s = _distance * 3.28084
|
||||
end
|
||||
return s
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.getDistance(_point1, _point2)
|
||||
|
||||
local xUnit = _point1.x
|
||||
local yUnit = _point1.z
|
||||
local xZone = _point2.x
|
||||
local yZone = _point2.z
|
||||
|
||||
local xDiff = xUnit - xZone
|
||||
local yDiff = yUnit - yZone
|
||||
|
||||
return math.sqrt(xDiff * xDiff + yDiff * yDiff)
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.getRelativeDirection(_refHeading,_point1, _point2)
|
||||
local tgtBearing
|
||||
local xUnit = _point1.x
|
||||
local yUnit = _point1.z
|
||||
local xZone = _point2.x
|
||||
local yZone = _point2.z
|
||||
|
||||
local xDiff = xUnit - xZone
|
||||
local yDiff = yUnit - yZone
|
||||
|
||||
local tgtAngle = math.deg(math.atan(yDiff/xDiff))
|
||||
|
||||
if xDiff > 0 then
|
||||
tgtBearing = 180 + tgtAngle
|
||||
end
|
||||
|
||||
if xDiff < 0 and tgtAngle > 0 then
|
||||
tgtBearing = tgtAngle
|
||||
end
|
||||
|
||||
if xDiff < 0 and tgtAngle < 0 then
|
||||
tgtBearing = 360 + tgtAngle
|
||||
end
|
||||
|
||||
tgtBearing = tgtBearing - _refHeading
|
||||
if tgtBearing > 360 then
|
||||
tgtBearing = tgtBearing - 360
|
||||
end
|
||||
if tgtBearing < 0 then
|
||||
tgtBearing = 360 + tgtBearing
|
||||
end
|
||||
|
||||
return tgtBearing
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.getClockDirection(_direction)
|
||||
-- by cfrag
|
||||
if not _direction then return 0 end
|
||||
while _direction < 0 do
|
||||
_direction = _direction + 360
|
||||
end
|
||||
|
||||
if _direction < 15 then -- special case 12 o'clock past 12 o'clock
|
||||
return 12
|
||||
end
|
||||
|
||||
_direction = _direction + 15 -- add offset so we get all other times correct
|
||||
return math.floor(_direction/30)
|
||||
|
||||
end
|
||||
--############################################################################################################################################
|
||||
function TITS.getDirection(_point1, _point2)
|
||||
local tgtBearing
|
||||
local xUnit = _point1.x
|
||||
local yUnit = _point1.z
|
||||
local xZone = _point2.x
|
||||
local yZone = _point2.z
|
||||
|
||||
local xDiff = xUnit - xZone
|
||||
local yDiff = yUnit - yZone
|
||||
|
||||
local tgtAngle = math.deg(math.atan(yDiff/xDiff))
|
||||
|
||||
if xDiff > 0 then
|
||||
tgtBearing = 180 + tgtAngle
|
||||
end
|
||||
|
||||
if xDiff < 0 and tgtAngle > 0 then
|
||||
tgtBearing = tgtAngle
|
||||
end
|
||||
|
||||
if xDiff < 0 and tgtAngle < 0 then
|
||||
tgtBearing = 360 + tgtAngle
|
||||
end
|
||||
|
||||
|
||||
env.info("xDiff "..xDiff.." yDiff "..yDiff)
|
||||
return tgtBearing
|
||||
end
|
||||
--############################################################################################################################################
|
||||
|
||||
|
||||
|
||||
--############################################################################################################################################
|
||||
-- Main Body
|
||||
world.addEventHandler(TITS.eventHandler)
|
||||
Loading…
x
Reference in New Issue
Block a user