Work by Fullgas on multiple issues and new features

* Indicate obligation to use MIST delivered with CTLD

* update ctld.dynamicCargoUnits table

* Indicate obligation to use MIST delivered with CTLD

* MIST madatory in red

* MIST mandatory in red

* fix mist.utils.getHeadingPoints calls

* commit

* fix #164 Issue-wrong12oclock msg

* commit ctld.tools.getRelativeBearing()

* commit
This commit is contained in:
FullGas1
2025-11-22 11:50:10 +01:00
committed by GitHub
parent 659268d3f5
commit c12c0b242d
3 changed files with 77 additions and 13 deletions
+73 -9
View File
@@ -1,4 +1,5 @@
--[[
--[[ ! IMPORTANT : You must must use the version of MIST supplied in the CTLD pack to correctly manage dynamic spwans
Combat Troop and Logistics Drop
Allows Huey, Mi-8 and C130 to transport troops internally and Helicopters to transport Logistic / Vehicle units to the field via sling-loads
@@ -40,7 +41,7 @@ end
ctld.Id = "CTLD - "
--- Version.
ctld.Version = "1.5.2"
ctld.Version = "1.5.3"
-- To add debugging messages to dcs.log, change the following log levels to `true`; `Debug` is less detailed than `Trace`
ctld.Debug = false
@@ -817,7 +818,9 @@ ctld.vehicleTransportEnabled = {
-- We will also use this to make modifications to the menu and other checks and messages
ctld.dynamicCargoUnits = {
"CH-47Fbl1",
--"UH-1H",
"UH-1H",
"Mi-8MT",
"Mi-24P",
}
-- ************** Maximum Units SETUP for UNITS ******************
@@ -2618,10 +2621,19 @@ function ctld.spawnCrate(_arguments, bypassCrateWaitTime)
-- add to move table
ctld.crateMove[_name] = _name
local refPoint = _heli:getPoint()
local refLat, refLon = coord.LOtoLL(refPoint)
local unitPos = _heli:getPosition()
local refHeading = math.deg(math.atan2(unitPos.x.z, unitPos.x.x))
local destLat, destLon, destAlt = coord.LOtoLL(_point)
local relativePos, forma = ctld.tools.getRelativeBearing(refLat, refLon, refHeading, destLat, destLon, 'clock')
ctld.displayMessageToGroup(_heli,
ctld.i18n_translate("A %1 crate weighing %2 kg has been brought out and is at your %3 o'clock ",
_crateType.desc, _crateType.weight, _position), 20)
_crateType.desc, _crateType.weight, relativePos), 20)
else
env.info("Couldn't find crate item to spawn")
end
@@ -4224,8 +4236,7 @@ function ctld.dropSlingCrate(_args)
_position = "6"
end
ctld.displayMessageToGroup(_heli,
ctld.i18n_translate("%1 crate has been safely unhooked and is at your %2 o'clock", _crate.desc,
_position), 10)
ctld.i18n_translate("%1 crate has been safely unhooked and is at your %2 o'clock", _crate.desc, _position), 10)
elseif _heightDiff > 7.5 and _heightDiff <= 40.0 then
ctld.displayMessageToGroup(_heli,
ctld.i18n_translate("%1 crate has been safely dropped below you", _crate.desc), 10)
@@ -5747,7 +5758,7 @@ function ctld.unitDynamicCargoCapable(_unit)
--ctld.logDebug("ctld.unitDynamicCargoCapable(_type=[%s])", ctld.p(_type))
for _, _name in ipairs(ctld.dynamicCargoUnits) do
local _nameLower = string.lower(_name)
if string.find(_type, _nameLower, 1, true) then --string.match does not work with patterns containing '-' as it is a magic character
if string.find(_type, _nameLower, 1, true) then --string.match does not work with patterns containing '-' as it is a magic character
result = true
break
end
@@ -8541,7 +8552,7 @@ function ctld.eventHandler:onEvent(event)
for _, aircraftType in pairs(ctld.aircraftTypeTable) do
if aircraftType == playerTypeName then
ctld.logTrace("adding by aircraft type, unitName = %s", ctld.p(unitName))
if ctld.isValueInIpairTable(ctld.transportPilotNames, unitName) == false then
if ctld.tools.isValueInIpairTable(ctld.transportPilotNames, unitName) == false then
table.insert(ctld.transportPilotNames, unitName) -- add transport unit to the list
end
if ctld.addedTo[tostring(_groupId)] == nil then -- only if menu not already set up
@@ -8619,7 +8630,8 @@ function ctld.RandomReal(mini, maxi)
end
-- Tools
function ctld.isValueInIpairTable(tab, value)
ctld.tools = {}
function ctld.tools.isValueInIpairTable(tab, value)
for i, v in ipairs(tab) do
if v == value then
return true -- La valeur existe
@@ -8627,6 +8639,58 @@ function ctld.isValueInIpairTable(tab, value)
end
return false -- La valeur n'existe pas
end
------------------------------------------------------------------------------------
--- Calculates the orientation of an end point relative to a reference point.
--- The calculation takes into account the current orientation of the reference point.
---
--- @param refLat number Latitude of the reference point in degrees.
--- @param refLon number Longitude of the reference point in degrees.
--- @param refHeading number Current orientation of the reference point in degrees (0 = North, 90 = East).
--- @param destLat number Latitude of the arrival point in degrees.
--- @param destLon number Longitude of the arrival point in degrees.
--- @param resultFormat string The desired output format: "radian", "degree" or "clock".
--- @return number The relative orientation in the specified resultFormat.
function ctld.tools.getRelativeBearing(refLat, refLon, refHeading, destLat, destLon, resultFormat)
-- Converting degrees to radians for geometric calculations
local radrefLat = math.rad(refLat)
local raddestLat = math.rad(destLat)
local radrefLon = math.rad(refLon)
local raddestLon = math.rad(destLon)
local radrefHeading = math.rad(refHeading)
-- Calculating the longitude difference between the two points
local deltaLon = raddestLon - radrefLon
-- Using the great circle formula for azimuth (bearing)
-- This formula is based on spherical trigonometry and uses atan2
-- to correctly handle all quadrants.
local y = math.sin(deltaLon) * math.cos(raddestLat)
local x = math.cos(radrefLat) * math.sin(raddestLat) - math.sin(radrefLat) * math.cos(raddestLat) * math.cos(deltaLon)
local absoluteBearingRad = math.atan2(y, x)
-- Calculate relative orientation by subtracting the reference refHeading
local relativeBearingRad = absoluteBearingRad - radrefHeading
-- Normalizes the angle to be in the range [-pi, pi]
-- This ensures a consistent angle, whether positive or negative.
local normalizedRad = (relativeBearingRad + math.pi) % (2 * math.pi) - math.pi
-- Returns the value in the requested resultFormat
if resultFormat == "radian" then
return normalizedRad, resultFormat
elseif resultFormat == "clock" then
-- Convert to clock position (12h = front, 3h = right, 6h = back, etc..)
local bearingDeg = math.deg(normalizedRad)
local clockPosition = ((bearingDeg + 360) % 360) / 30
clockPosition = clockPosition >= 0 and math.floor(clockPosition + 0.5) or math.ceil(clockPosition - 0.5), resultFormat -- rounded clockPosition
if clockPosition == 0 then clockPosition = 12 end
return clockPosition, resultFormat
else -- By default, the resultFormat is "degree"
resultFormat = "degree"
local bearingDeg = math.deg(normalizedRad)
return (bearingDeg + 360) % 360, resultFormat
end
end
--- Enable/Disable error boxes displayed on screen.
env.setErrorMessageBoxEnabled(false)
+1 -1
View File
@@ -132,7 +132,7 @@ Optionaly, you can disable the STTS (text to speech over SRS) feature (4).
![dynamic_loading]
### Script Setup
**This script requires MIST version 4.0.57 or above: https://github.com/mrSkortch/MissionScriptingTools**
🔴IMPORTANT: This script requires MIST supplied in the CTLD zipped pack to correctly manage dynamic spwans.
First make sure MIST is loaded, either as an Initialization Script for the mission or the first DO SCRIPT with a "TIME MORE" of 1. "TIME MORE" means run the actions after X seconds into the mission.
+3 -3
View File
@@ -35,7 +35,7 @@ mist = {}
-- don't change these
mist.majorVersion = 4
mist.minorVersion = 5
mist.build = "128-DYNSLOTS-01"
mist.build = "128-DYNSLOTS-02"
-- forward declaration of log shorthand
local log
@@ -826,11 +826,11 @@ do -- the main scope
if zone.verticies then
local offset = {}
for i = 1, #zone.verticies do
table.insert(offset, {dist = mist.utils.get2DDist(uRef.point, zone.verticies[i]), heading = mist.getHeadingPoints(uRef.point, zone.verticies[i]) + uRef.heading})
table.insert(offset, {dist = mist.utils.get2DDist(uRef.point, zone.verticies[i]), heading = mist.utils.getHeadingPoints(uRef.point, zone.verticies[i]) + uRef.heading})
end
zone.offset = offset
else
zone.offset = {dist = mist.utils.get2DDist(uRef.point, zone.point), heading = mist.getHeadingPoints(uRef.point, zone.point) + uRef.heading}
zone.offset = {dist = mist.utils.get2DDist(uRef.point, zone.point), heading = mist.utils.getHeadingPoints(uRef.point, zone.point) + uRef.heading}
end
end
end