mirror of
https://github.com/ciribob/DCS-CTLD.git
synced 2026-08-12 04:31:06 +00:00
Compare commits
184 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e59bc50e6c | |||
| c12c0b242d | |||
| 659268d3f5 | |||
| c9270a0fd2 | |||
| def40f440c | |||
| 417c57f97c | |||
| dec5bf02b4 | |||
| 68693300dc | |||
| f7f603c486 | |||
| 290950a16b | |||
| 041a9ab6af | |||
| 8d73c966db | |||
| af3e4fab17 | |||
| 97e7c72144 | |||
| 65336fdab8 | |||
| 61db3e9f93 | |||
| a1da0ea1c4 | |||
| 782940265d | |||
| b5cd8929f3 | |||
| 1826d28a86 | |||
| 359bf1418d | |||
| e3424c6af5 | |||
| 1ac3b3f8a9 | |||
| e13e630830 | |||
| 7bfed7ef55 | |||
| 8bfaba399f | |||
| 4dada3d24d | |||
| 74b40fe3cb | |||
| aa8bc78b27 | |||
| 7286a6a010 | |||
| c8bb41648c | |||
| 08635622b0 | |||
| 42e8549649 | |||
| 5c48a9d756 | |||
| f3983c6a90 | |||
| 1c66408127 | |||
| 3ac2b3b22c | |||
| c576268d87 | |||
| 35f52d543a | |||
| c608d00d15 | |||
| d2789f554a | |||
| fcef6a66d1 | |||
| dd71451194 | |||
| 807e81e389 | |||
| 33d8810ebb | |||
| 87e8a31f31 | |||
| e4a0fff931 | |||
| ca5bf76c78 | |||
| f8659c5de6 | |||
| 9a0cc8eeee | |||
| a706890cb6 | |||
| 815684dd77 | |||
| 0ccb2ba7bb | |||
| 1e471df264 | |||
| cc8b916870 | |||
| cd62d0c60a | |||
| a35e023752 | |||
| f71e7f3213 | |||
| a468faefec | |||
| 99f2c7aec0 | |||
| 7db8e2d772 | |||
| 026099bd12 | |||
| 82a330e61a | |||
| b3470250e4 | |||
| bbde4ae62b | |||
| 540a316754 | |||
| 574217d931 | |||
| 1fce52088d | |||
| 4d704a489e | |||
| da80f9ea06 | |||
| 93260908c4 | |||
| 3c261e8dc2 | |||
| 7b7eb62bf0 | |||
| 951ee37903 | |||
| 3a7ab50834 | |||
| 9a69d4b52c | |||
| 0345d16150 | |||
| d071fba20f | |||
| 1a32ce6b57 | |||
| 85275ad84b | |||
| 819ba2de53 | |||
| 8f34ad3902 | |||
| 16f366d039 | |||
| 2524320096 | |||
| e6b8c9ba14 | |||
| a5b47503be | |||
| aaa25dcd41 | |||
| e834dd1395 | |||
| 774e499759 | |||
| 0a1f4de471 | |||
| f9cd8b8b51 | |||
| 3eef8d9a5d | |||
| e1b9e1d7d8 | |||
| ca976f4387 | |||
| 91f74b73ed | |||
| f8df243043 | |||
| 29b19d5262 | |||
| 48aca9d488 | |||
| 12741d0532 | |||
| 6df583b9f1 | |||
| ca99c58f98 | |||
| 879272a2e8 | |||
| 267156e04e | |||
| 6fa12ca46f | |||
| eb22f5dc67 | |||
| 601805abb0 | |||
| e0e4279f20 | |||
| 9023c571ba | |||
| 72aab26e43 | |||
| aef146a6d8 | |||
| d8db662dc5 | |||
| e4f13f98b1 | |||
| c1aba95b6f | |||
| d50bcfccd9 | |||
| f0f095e274 | |||
| 69f04dfd57 | |||
| 546f3feaae | |||
| 23e83bf53a | |||
| ee07423588 | |||
| 96d801c342 | |||
| b1818d9fb3 | |||
| 2bc6e76516 | |||
| 61a1fd42ee | |||
| 954a6b0fad | |||
| 159915a6ac | |||
| d029e2479b | |||
| 251467fee4 | |||
| f3a9b44388 | |||
| f0adb72c49 | |||
| ecc47bb247 | |||
| 0c74729837 | |||
| ef1d3d57e5 | |||
| b69f20eb6b | |||
| d80a70c0ee | |||
| 80fe5d59b0 | |||
| 3eaa08b74e | |||
| f83365ec63 | |||
| 0b3b1ea1f8 | |||
| 888d949234 | |||
| 75c9d0bf68 | |||
| 7517eaf188 | |||
| 1181fcfff7 | |||
| 9def2f1a3a | |||
| 9c25240c43 | |||
| 8a17ff52aa | |||
| d125cdbe80 | |||
| 8dcaa3e0bb | |||
| baf1231141 | |||
| d1d9b55769 | |||
| ff06dcecf7 | |||
| dcdf6438a1 | |||
| 4d0062dee3 | |||
| c618f4b282 | |||
| b390d5dabf | |||
| f4b81fd101 | |||
| 78aa8a010e | |||
| 6996769cec | |||
| 0d9c01283c | |||
| fa1553a83e | |||
| 4db3c71728 | |||
| 0180cf33d2 | |||
| c51a3d80ca | |||
| 9eb4fc66b5 | |||
| 8f2a335609 | |||
| c5bae34ed1 | |||
| 6fc9f146ae | |||
| b6232d3c15 | |||
| 111fd73b94 | |||
| 61d9e206b2 | |||
| 08ebd7e82d | |||
| f152f58a97 | |||
| 38e86bead3 | |||
| b0d8f8b5c7 | |||
| a58efad985 | |||
| 0793d3bda5 | |||
| c397bad107 | |||
| 791ee4e63e | |||
| 5aa37c52a4 | |||
| fb26645996 | |||
| 3a3bcaf568 | |||
| fb804b4a22 | |||
| 665bdddbdd | |||
| 6beaedb79a | |||
| 9c2f982d03 |
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"Lua.diagnostics.globals": [
|
||||||
|
"ctld"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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
|
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
|
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 - "
|
ctld.Id = "CTLD - "
|
||||||
|
|
||||||
--- Version.
|
--- Version.
|
||||||
ctld.Version = "1.5.0"
|
ctld.Version = "1.6.0-alpha"
|
||||||
|
|
||||||
-- To add debugging messages to dcs.log, change the following log levels to `true`; `Debug` is less detailed than `Trace`
|
-- To add debugging messages to dcs.log, change the following log levels to `true`; `Debug` is less detailed than `Trace`
|
||||||
ctld.Debug = false
|
ctld.Debug = false
|
||||||
@@ -491,8 +492,8 @@ ctld.JTAC_LIMIT_RED = 10 -- max number of JTAC Crates for the RED Si
|
|||||||
ctld.JTAC_LIMIT_BLUE = 10 -- max number of JTAC Crates for the BLUE Side
|
ctld.JTAC_LIMIT_BLUE = 10 -- max number of JTAC Crates for the BLUE Side
|
||||||
ctld.JTAC_dropEnabled = true -- allow JTAC Crate spawn from F10 menu
|
ctld.JTAC_dropEnabled = true -- allow JTAC Crate spawn from F10 menu
|
||||||
ctld.JTAC_maxDistance = 10000 -- How far a JTAC can "see" in meters (with Line of Sight)
|
ctld.JTAC_maxDistance = 10000 -- How far a JTAC can "see" in meters (with Line of Sight)
|
||||||
ctld.JTAC_smokeOn_RED = true -- enables marking of target with smoke for RED forces
|
ctld.JTAC_smokeOn_RED = false -- enables marking of target with smoke for RED forces
|
||||||
ctld.JTAC_smokeOn_BLUE = true -- enables marking of target with smoke for BLUE forces
|
ctld.JTAC_smokeOn_BLUE = false -- enables marking of target with smoke for BLUE forces
|
||||||
ctld.JTAC_smokeColour_RED = 4 -- RED side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4
|
ctld.JTAC_smokeColour_RED = 4 -- RED side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4
|
||||||
ctld.JTAC_smokeColour_BLUE = 1 -- BLUE side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4
|
ctld.JTAC_smokeColour_BLUE = 1 -- BLUE side smoke colour -- Green = 0 , Red = 1, White = 2, Orange = 3, Blue = 4
|
||||||
ctld.JTAC_smokeMarginOfError = 50 -- error that the JTAC is allowed to make when popping a smoke (in meters)
|
ctld.JTAC_smokeMarginOfError = 50 -- error that the JTAC is allowed to make when popping a smoke (in meters)
|
||||||
@@ -817,7 +818,9 @@ ctld.vehicleTransportEnabled = {
|
|||||||
-- We will also use this to make modifications to the menu and other checks and messages
|
-- We will also use this to make modifications to the menu and other checks and messages
|
||||||
ctld.dynamicCargoUnits = {
|
ctld.dynamicCargoUnits = {
|
||||||
"CH-47Fbl1",
|
"CH-47Fbl1",
|
||||||
--"UH-1H",
|
"UH-1H",
|
||||||
|
"Mi-8MT",
|
||||||
|
"Mi-24P",
|
||||||
}
|
}
|
||||||
|
|
||||||
-- ************** Maximum Units SETUP for UNITS ******************
|
-- ************** Maximum Units SETUP for UNITS ******************
|
||||||
@@ -888,6 +891,7 @@ ctld.internalCargoLimits = {
|
|||||||
-- Remove the -- below to turn on options
|
-- Remove the -- below to turn on options
|
||||||
["Mi-8MT"] = 2,
|
["Mi-8MT"] = 2,
|
||||||
["CH-47Fbl1"] = 8,
|
["CH-47Fbl1"] = 8,
|
||||||
|
["UH-1H"] = 3, -- to remove after debug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1977,7 +1981,7 @@ function ctld.getUnitsInRepackRadius(_PlayerTransportUnitName, _radius)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local unitsNamesList = ctld.getNearbyUnits(unit:getPoint(), _radius, unit:getCoalition())
|
local unitsNamesList = ctld.getNearbyUnits(unit:getPoint(), _radius, unit:getCoalition())
|
||||||
|
|
||||||
local repackableUnits = {}
|
local repackableUnits = {}
|
||||||
for i = 1, #unitsNamesList do
|
for i = 1, #unitsNamesList do
|
||||||
local unitObject = Unit.getByName(unitsNamesList[i])
|
local unitObject = Unit.getByName(unitsNamesList[i])
|
||||||
@@ -1998,11 +2002,13 @@ function ctld.getNearbyUnits(_point, _radius, _coalition)
|
|||||||
local unitsByDistance = {}
|
local unitsByDistance = {}
|
||||||
local cpt = 1
|
local cpt = 1
|
||||||
local _units = {}
|
local _units = {}
|
||||||
local _unitList = mist.DBs.unitsByName
|
for _unitName, _ in pairs(mist.DBs.unitsByName) do
|
||||||
for _unitName, _unit in pairs(mist.DBs.unitsByName) do
|
|
||||||
local u = Unit.getByName(_unitName)
|
local u = Unit.getByName(_unitName)
|
||||||
if u and u:isExist() and (_coalition == 4 or u:getCoalition() == _coalition) then
|
local e = (u and u:isExist()) or false
|
||||||
--local _dist = ctld.getDistance(u:getPoint(), _point)
|
-- pcall is needed because getCoalition() fails if the unit is an object without coalition (like a smoke effect)
|
||||||
|
local c = nil
|
||||||
|
pcall(function() c = (u and e and u:getCoalition()) or nil end)
|
||||||
|
if u and e and (_coalition == 4 or c == _coalition) then
|
||||||
local _dist = mist.utils.get2DDist(u:getPoint(), _point)
|
local _dist = mist.utils.get2DDist(u:getPoint(), _point)
|
||||||
if _dist <= _radius then
|
if _dist <= _radius then
|
||||||
unitsByDistance[cpt] = {id =cpt, dist = _dist, unit = _unitName, typeName = u:getTypeName()}
|
unitsByDistance[cpt] = {id =cpt, dist = _dist, unit = _unitName, typeName = u:getTypeName()}
|
||||||
@@ -2010,7 +2016,7 @@ function ctld.getNearbyUnits(_point, _radius, _coalition)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--table.sort(unitsByDistance, function(a,b) return a.dist < b.dist end) -- sort the table by distance (the nearest first)
|
--table.sort(unitsByDistance, function(a,b) return a.dist < b.dist end) -- sort the table by distance (the nearest first)
|
||||||
table.sort(unitsByDistance, function(a,b) return a.typeName < b.typeName end) -- sort the table by typeNAme
|
table.sort(unitsByDistance, function(a,b) return a.typeName < b.typeName end) -- sort the table by typeNAme
|
||||||
for i, v in ipairs(unitsByDistance) do
|
for i, v in ipairs(unitsByDistance) do
|
||||||
@@ -2092,7 +2098,7 @@ function ctld.repackVehicle(_params, t) -- scan rrs table 'repackRequestsStack'
|
|||||||
local _name = string.format("%s_%i", v.desc, _unitId)
|
local _name = string.format("%s_%i", v.desc, _unitId)
|
||||||
local secureDistance = ctld.getSecureDistanceFromUnit(playerUnitName) or 10
|
local secureDistance = ctld.getSecureDistanceFromUnit(playerUnitName) or 10
|
||||||
local relativePoint = ctld.getRelativePoint(playerPoint, secureDistance + (i * offset), randomHeading) -- 7 meters from the transport unit
|
local relativePoint = ctld.getRelativePoint(playerPoint, secureDistance + (i * offset), randomHeading) -- 7 meters from the transport unit
|
||||||
|
|
||||||
if ctld.unitDynamicCargoCapable(PlayerTransportUnit) == false then
|
if ctld.unitDynamicCargoCapable(PlayerTransportUnit) == false then
|
||||||
ctld.spawnCrateStatic(refCountry, _unitId, relativePoint, _name, crateWeight, playerCoa, playerHeading, nil)
|
ctld.spawnCrateStatic(refCountry, _unitId, relativePoint, _name, crateWeight, playerCoa, playerHeading, nil)
|
||||||
else
|
else
|
||||||
@@ -2105,8 +2111,8 @@ function ctld.repackVehicle(_params, t) -- scan rrs table 'repackRequestsStack'
|
|||||||
ctld.repackRequestsStack[ii] = nil -- remove the processed request from the stacking table
|
ctld.repackRequestsStack[ii] = nil -- remove the processed request from the stacking table
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ctld.enableRepackingVehicles == true then
|
if ctld.enableRepackingVehicles == true then
|
||||||
return t + 3 -- reschedule the function in 3 seconds
|
return t + 3 -- reschedule the function in 3 seconds
|
||||||
else
|
else
|
||||||
@@ -2615,10 +2621,19 @@ function ctld.spawnCrate(_arguments, bypassCrateWaitTime)
|
|||||||
|
|
||||||
-- add to move table
|
-- add to move table
|
||||||
ctld.crateMove[_name] = _name
|
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.displayMessageToGroup(_heli,
|
||||||
ctld.i18n_translate("A %1 crate weighing %2 kg has been brought out and is at your %3 o'clock ",
|
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
|
else
|
||||||
env.info("Couldn't find crate item to spawn")
|
env.info("Couldn't find crate item to spawn")
|
||||||
end
|
end
|
||||||
@@ -3169,7 +3184,7 @@ function ctld.updateTroopsInGame(params, t) -- return count of troops in game b
|
|||||||
for index, unitObj in pairs(v:getUnits()) do -- for each unit in group
|
for index, unitObj in pairs(v:getUnits()) do -- for each unit in group
|
||||||
if unitObj:getDesc().attributes.Infantry then
|
if unitObj:getDesc().attributes.Infantry then
|
||||||
ctld.InfantryInGameCount[coalitionId] = ctld.InfantryInGameCount[coalitionId] + 1
|
ctld.InfantryInGameCount[coalitionId] = ctld.InfantryInGameCount[coalitionId] + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -3227,7 +3242,7 @@ function ctld.loadTroopsFromZone(_args)
|
|||||||
ctld.logTrace("FG_ ctld.InfantryInGameCount[heloCoa] = %s", ctld.p(ctld.InfantryInGameCount[heloCoa]))
|
ctld.logTrace("FG_ ctld.InfantryInGameCount[heloCoa] = %s", ctld.p(ctld.InfantryInGameCount[heloCoa]))
|
||||||
ctld.logTrace("FG_ _groupTemplate.total = %s", ctld.p(_groupTemplate.total))
|
ctld.logTrace("FG_ _groupTemplate.total = %s", ctld.p(_groupTemplate.total))
|
||||||
ctld.logTrace("FG_ ctld.nbLimitSpawnedTroops[%s].total = %s", ctld.p(heloCoa), ctld.p(ctld.nbLimitSpawnedTroops[heloCoa]))
|
ctld.logTrace("FG_ ctld.nbLimitSpawnedTroops[%s].total = %s", ctld.p(heloCoa), ctld.p(ctld.nbLimitSpawnedTroops[heloCoa]))
|
||||||
|
|
||||||
local limitReached = true
|
local limitReached = true
|
||||||
if (ctld.nbLimitSpawnedTroops[1]~=0 or ctld.nbLimitSpawnedTroops[2]~=0) and (ctld.InfantryInGameCount[heloCoa] + _groupTemplate.total > ctld.nbLimitSpawnedTroops[heloCoa]) then -- load troops only if Coa limit not reached
|
if (ctld.nbLimitSpawnedTroops[1]~=0 or ctld.nbLimitSpawnedTroops[2]~=0) and (ctld.InfantryInGameCount[heloCoa] + _groupTemplate.total > ctld.nbLimitSpawnedTroops[heloCoa]) then -- load troops only if Coa limit not reached
|
||||||
ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Count Infantries limit in the mission reached, you can't load more troops"), 10)
|
ctld.displayMessageToGroup(_heli, ctld.i18n_translate("Count Infantries limit in the mission reached, you can't load more troops"), 10)
|
||||||
@@ -3960,7 +3975,7 @@ function ctld.unpackCrates(_arguments)
|
|||||||
local _crates = ctld.getCratesAndDistance(_heli)
|
local _crates = ctld.getCratesAndDistance(_heli)
|
||||||
local _crate = ctld.getClosestCrate(_heli, _crates)
|
local _crate = ctld.getClosestCrate(_heli, _crates)
|
||||||
ctld.logTrace("FG_ ctld.unpackCrates._crate = %s", ctld.p(_crate))
|
ctld.logTrace("FG_ ctld.unpackCrates._crate = %s", ctld.p(_crate))
|
||||||
|
|
||||||
if ctld.inLogisticsZone(_heli) == true or ctld.farEnoughFromLogisticZone(_heli) == false then
|
if ctld.inLogisticsZone(_heli) == true or ctld.farEnoughFromLogisticZone(_heli) == false then
|
||||||
ctld.displayMessageToGroup(_heli,
|
ctld.displayMessageToGroup(_heli,
|
||||||
ctld.i18n_translate("You can't unpack that here! Take it to where it's needed!"), 20)
|
ctld.i18n_translate("You can't unpack that here! Take it to where it's needed!"), 20)
|
||||||
@@ -4015,7 +4030,7 @@ function ctld.unpackCrates(_arguments)
|
|||||||
ctld.logTrace("_crate = %s", ctld.p(_crate))
|
ctld.logTrace("_crate = %s", ctld.p(_crate))
|
||||||
local _spawnedGroups = ctld.spawnCrateGroup(_heli, { _point }, { _crate.details.unit }, { _crateHdg })
|
local _spawnedGroups = ctld.spawnCrateGroup(_heli, { _point }, { _crate.details.unit }, { _crateHdg })
|
||||||
ctld.logTrace("_spawnedGroups = %s", ctld.p(_spawnedGroups))
|
ctld.logTrace("_spawnedGroups = %s", ctld.p(_spawnedGroups))
|
||||||
|
|
||||||
if _heli:getCoalition() == 1 then
|
if _heli:getCoalition() == 1 then
|
||||||
ctld.spawnedCratesRED[_crateName] = nil
|
ctld.spawnedCratesRED[_crateName] = nil
|
||||||
else
|
else
|
||||||
@@ -4221,8 +4236,7 @@ function ctld.dropSlingCrate(_args)
|
|||||||
_position = "6"
|
_position = "6"
|
||||||
end
|
end
|
||||||
ctld.displayMessageToGroup(_heli,
|
ctld.displayMessageToGroup(_heli,
|
||||||
ctld.i18n_translate("%1 crate has been safely unhooked and is at your %2 o'clock", _crate.desc,
|
ctld.i18n_translate("%1 crate has been safely unhooked and is at your %2 o'clock", _crate.desc, _position), 10)
|
||||||
_position), 10)
|
|
||||||
elseif _heightDiff > 7.5 and _heightDiff <= 40.0 then
|
elseif _heightDiff > 7.5 and _heightDiff <= 40.0 then
|
||||||
ctld.displayMessageToGroup(_heli,
|
ctld.displayMessageToGroup(_heli,
|
||||||
ctld.i18n_translate("%1 crate has been safely dropped below you", _crate.desc), 10)
|
ctld.i18n_translate("%1 crate has been safely dropped below you", _crate.desc), 10)
|
||||||
@@ -5026,7 +5040,7 @@ function ctld.unpackMultiCrate(_heli, _nearestCrate, _nearbyCrates)
|
|||||||
if ctld.unitDynamicCargoCapable(_heli) == true then
|
if ctld.unitDynamicCargoCapable(_heli) == true then
|
||||||
_point = ctld.getPointInRearSector(_heli, ctld.getSecureDistanceFromUnit(_heli:getName()))
|
_point = ctld.getPointInRearSector(_heli, ctld.getSecureDistanceFromUnit(_heli:getName()))
|
||||||
end
|
end
|
||||||
|
|
||||||
local _crateHdg = mist.getHeading(_nearestCrate.crateUnit, true)
|
local _crateHdg = mist.getHeading(_nearestCrate.crateUnit, true)
|
||||||
|
|
||||||
-- destroy crates
|
-- destroy crates
|
||||||
@@ -5744,7 +5758,7 @@ function ctld.unitDynamicCargoCapable(_unit)
|
|||||||
--ctld.logDebug("ctld.unitDynamicCargoCapable(_type=[%s])", ctld.p(_type))
|
--ctld.logDebug("ctld.unitDynamicCargoCapable(_type=[%s])", ctld.p(_type))
|
||||||
for _, _name in ipairs(ctld.dynamicCargoUnits) do
|
for _, _name in ipairs(ctld.dynamicCargoUnits) do
|
||||||
local _nameLower = string.lower(_name)
|
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
|
result = true
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@@ -5864,208 +5878,203 @@ end
|
|||||||
-- Adds menuitem to a human unit
|
-- Adds menuitem to a human unit
|
||||||
function ctld.addTransportF10MenuOptions(_unitName)
|
function ctld.addTransportF10MenuOptions(_unitName)
|
||||||
ctld.logDebug("ctld.addTransportF10MenuOptions(_unitName=[%s])", ctld.p(_unitName))
|
ctld.logDebug("ctld.addTransportF10MenuOptions(_unitName=[%s])", ctld.p(_unitName))
|
||||||
local status, error = pcall(function()
|
local _unit = ctld.getTransportUnit(_unitName)
|
||||||
local _unit = ctld.getTransportUnit(_unitName)
|
ctld.logTrace("_unit = %s", ctld.p(_unit))
|
||||||
ctld.logTrace("_unit = %s", ctld.p(_unit))
|
|
||||||
|
|
||||||
if _unit then
|
if _unit then
|
||||||
local _unitTypename = _unit:getTypeName()
|
local _unitTypename = _unit:getTypeName()
|
||||||
local _groupId = ctld.getGroupId(_unit)
|
local _groupId = ctld.getGroupId(_unit)
|
||||||
if _groupId then
|
if _groupId then
|
||||||
-- ctld.logTrace("_groupId = %s", ctld.p(_groupId))
|
-- ctld.logTrace("_groupId = %s", ctld.p(_groupId))
|
||||||
-- ctld.logTrace("ctld.addedTo = %s", ctld.p(ctld.addedTo[tostring(_groupId)]))
|
-- ctld.logTrace("ctld.addedTo = %s", ctld.p(ctld.addedTo[tostring(_groupId)]))
|
||||||
if ctld.addedTo[tostring(_groupId)] == nil then
|
if ctld.addedTo[tostring(_groupId)] == nil then
|
||||||
ctld.logTrace("adding CTLD menu for _groupId = %s", ctld.p(_groupId))
|
ctld.logTrace("adding CTLD menu for _groupId = %s", ctld.p(_groupId))
|
||||||
local _rootPath = missionCommands.addSubMenuForGroup(_groupId, ctld.i18n_translate("CTLD"))
|
local _rootPath = missionCommands.addSubMenuForGroup(_groupId, ctld.i18n_translate("CTLD"))
|
||||||
local _unitActions = ctld.getUnitActions(_unitTypename)
|
local _unitActions = ctld.getUnitActions(_unitTypename)
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Check Cargo"), _rootPath, ctld.checkTroopStatus, { _unitName })
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Check Cargo"), _rootPath, ctld.checkTroopStatus, { _unitName })
|
||||||
if _unitActions.troops then
|
if _unitActions.troops then
|
||||||
local _troopCommandsPath = missionCommands.addSubMenuForGroup(_groupId,ctld.i18n_translate("Troop Transport"), _rootPath)
|
local _troopCommandsPath = missionCommands.addSubMenuForGroup(_groupId,ctld.i18n_translate("Troop Transport"), _rootPath)
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Unload / Extract Troops"),
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Unload / Extract Troops"),
|
||||||
_troopCommandsPath, ctld.unloadExtractTroops, { _unitName })
|
_troopCommandsPath, ctld.unloadExtractTroops, { _unitName })
|
||||||
|
|
||||||
-- local _loadPath = missionCommands.addSubMenuForGroup(_groupId, "Load From Zone", _troopCommandsPath)
|
-- local _loadPath = missionCommands.addSubMenuForGroup(_groupId, "Load From Zone", _troopCommandsPath)
|
||||||
local _transportLimit = ctld.getTransportLimit(_unitTypename)
|
local _transportLimit = ctld.getTransportLimit(_unitTypename)
|
||||||
local itemNb = 0
|
local itemNb = 0
|
||||||
local menuEntries = {}
|
local menuEntries = {}
|
||||||
local menuPath = _troopCommandsPath
|
local menuPath = _troopCommandsPath
|
||||||
for _, _loadGroup in pairs(ctld.loadableGroups) do
|
for _, _loadGroup in pairs(ctld.loadableGroups) do
|
||||||
if not _loadGroup.side or _loadGroup.side == _unit:getCoalition() then
|
if not _loadGroup.side or _loadGroup.side == _unit:getCoalition() then
|
||||||
-- check size & unit
|
-- check size & unit
|
||||||
if _transportLimit >= _loadGroup.total then
|
if _transportLimit >= _loadGroup.total then
|
||||||
table.insert(menuEntries,
|
table.insert(menuEntries,
|
||||||
{ text = ctld.i18n_translate("Load ") .. _loadGroup.name, group = _loadGroup })
|
{ text = ctld.i18n_translate("Load ") .. _loadGroup.name, group = _loadGroup })
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _i, _menu in ipairs(menuEntries) do
|
|
||||||
-- add the menu item
|
|
||||||
itemNb = itemNb + 1
|
|
||||||
if itemNb == 9 and _i < #menuEntries then -- page limit reached (first item is "unload")
|
|
||||||
menuPath = missionCommands.addSubMenuForGroup(_groupId, ctld.i18n_translate("Next page"),
|
|
||||||
menuPath)
|
|
||||||
itemNb = 1
|
|
||||||
end
|
|
||||||
missionCommands.addCommandForGroup(_groupId, _menu.text, menuPath, ctld.loadTroopsFromZone,
|
|
||||||
{ _unitName, true, _menu.group, false })
|
|
||||||
end
|
|
||||||
if ctld.unitCanCarryVehicles(_unit) then
|
|
||||||
local _vehicleCommandsPath = missionCommands.addSubMenuForGroup(_groupId,
|
|
||||||
ctld.i18n_translate("Vehicle / FOB Transport"), _rootPath)
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Unload Vehicles"),
|
|
||||||
_vehicleCommandsPath, ctld.unloadTroops, { _unitName, false })
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Load / Extract Vehicles"),
|
|
||||||
_vehicleCommandsPath, ctld.loadTroopsFromZone, { _unitName, false, "", true })
|
|
||||||
|
|
||||||
if ctld.enabledFOBBuilding and ctld.staticBugWorkaround == false then
|
|
||||||
missionCommands.addCommandForGroup(_groupId,
|
|
||||||
ctld.i18n_translate("Load / Unload FOB Crate"), _vehicleCommandsPath,
|
|
||||||
ctld.loadUnloadFOBCrate, { _unitName, false })
|
|
||||||
end
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Check Cargo"),
|
|
||||||
_vehicleCommandsPath, ctld.checkTroopStatus, { _unitName })
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
for _i, _menu in ipairs(menuEntries) do
|
||||||
|
-- add the menu item
|
||||||
|
itemNb = itemNb + 1
|
||||||
|
if itemNb == 9 and _i < #menuEntries then -- page limit reached (first item is "unload")
|
||||||
|
menuPath = missionCommands.addSubMenuForGroup(_groupId, ctld.i18n_translate("Next page"),
|
||||||
|
menuPath)
|
||||||
|
itemNb = 1
|
||||||
|
end
|
||||||
|
missionCommands.addCommandForGroup(_groupId, _menu.text, menuPath, ctld.loadTroopsFromZone,
|
||||||
|
{ _unitName, true, _menu.group, false })
|
||||||
|
end
|
||||||
|
if ctld.unitCanCarryVehicles(_unit) then
|
||||||
|
local _vehicleCommandsPath = missionCommands.addSubMenuForGroup(_groupId,
|
||||||
|
ctld.i18n_translate("Vehicle / FOB Transport"), _rootPath)
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Unload Vehicles"),
|
||||||
|
_vehicleCommandsPath, ctld.unloadTroops, { _unitName, false })
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Load / Extract Vehicles"),
|
||||||
|
_vehicleCommandsPath, ctld.loadTroopsFromZone, { _unitName, false, "", true })
|
||||||
|
|
||||||
if ctld.enableCrates and _unitActions.crates then
|
if ctld.enabledFOBBuilding and ctld.staticBugWorkaround == false then
|
||||||
if ctld.unitCanCarryVehicles(_unit) == false then
|
missionCommands.addCommandForGroup(_groupId,
|
||||||
-- sort the crate categories alphabetically
|
ctld.i18n_translate("Load / Unload FOB Crate"), _vehicleCommandsPath,
|
||||||
local crateCategories = {}
|
ctld.loadUnloadFOBCrate, { _unitName, false })
|
||||||
for category, _ in pairs(ctld.spawnableCrates) do
|
end
|
||||||
table.insert(crateCategories, category)
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Check Cargo"),
|
||||||
|
_vehicleCommandsPath, ctld.checkTroopStatus, { _unitName })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ctld.enableCrates and _unitActions.crates then
|
||||||
|
if ctld.unitCanCarryVehicles(_unit) == false then
|
||||||
|
-- sort the crate categories alphabetically
|
||||||
|
local crateCategories = {}
|
||||||
|
for category, _ in pairs(ctld.spawnableCrates) do
|
||||||
|
table.insert(crateCategories, category)
|
||||||
|
end
|
||||||
|
table.sort(crateCategories)
|
||||||
|
--ctld.logTrace("crateCategories = [%s]", ctld.p(crateCategories))
|
||||||
|
|
||||||
|
-- add menu for spawning crates
|
||||||
|
local itemNbMain = 0
|
||||||
|
local _cratesMenuPath = missionCommands.addSubMenuForGroup(_groupId,
|
||||||
|
ctld.i18n_translate("Crates: Vehicle / FOB / Drone"), _rootPath)
|
||||||
|
|
||||||
|
for _i, _category in ipairs(crateCategories) do
|
||||||
|
local _subMenuName = _category
|
||||||
|
local _crates = ctld.spawnableCrates[_subMenuName]
|
||||||
|
|
||||||
|
-- add the submenu item
|
||||||
|
itemNbMain = itemNbMain + 1
|
||||||
|
if itemNbMain == 10 and _i < #crateCategories then -- page limit reached
|
||||||
|
_cratesMenuPath = missionCommands.addSubMenuForGroup(_groupId,
|
||||||
|
ctld.i18n_translate("Next page"), _cratesMenuPath)
|
||||||
|
itemNbMain = 1
|
||||||
end
|
end
|
||||||
table.sort(crateCategories)
|
local itemNbSubmenu = 0
|
||||||
--ctld.logTrace("crateCategories = [%s]", ctld.p(crateCategories))
|
local menuEntries = {}
|
||||||
|
local _subMenuPath = missionCommands.addSubMenuForGroup(_groupId, _subMenuName, _cratesMenuPath)
|
||||||
-- add menu for spawning crates
|
for _, _crate in pairs(_crates) do
|
||||||
local itemNbMain = 0
|
--ctld.logTrace("_crate = [%s]", ctld.p(_crate))
|
||||||
local _cratesMenuPath = missionCommands.addSubMenuForGroup(_groupId,
|
if not (_crate.multiple) or ctld.enableAllCrates then
|
||||||
ctld.i18n_translate("Crates: Vehicle / FOB / Drone"), _rootPath)
|
local isJTAC = ctld.isJTACUnitType(_crate.unit)
|
||||||
|
--ctld.logTrace("isJTAC = [%s]", ctld.p(isJTAC))
|
||||||
for _i, _category in ipairs(crateCategories) do
|
if not isJTAC or (isJTAC and ctld.JTAC_dropEnabled) then
|
||||||
local _subMenuName = _category
|
if _crate.side == nil or (_crate.side == _unit:getCoalition()) then
|
||||||
local _crates = ctld.spawnableCrates[_subMenuName]
|
local _crateRadioMsg = _crate.desc
|
||||||
|
--add in the number of crates required to build something
|
||||||
-- add the submenu item
|
if _crate.cratesRequired ~= nil and _crate.cratesRequired > 1 then
|
||||||
itemNbMain = itemNbMain + 1
|
_crateRadioMsg = _crateRadioMsg .. " (" .. _crate.cratesRequired ..
|
||||||
if itemNbMain == 10 and _i < #crateCategories then -- page limit reached
|
")"
|
||||||
_cratesMenuPath = missionCommands.addSubMenuForGroup(_groupId,
|
|
||||||
ctld.i18n_translate("Next page"), _cratesMenuPath)
|
|
||||||
itemNbMain = 1
|
|
||||||
end
|
|
||||||
local itemNbSubmenu = 0
|
|
||||||
local menuEntries = {}
|
|
||||||
local _subMenuPath = missionCommands.addSubMenuForGroup(_groupId, _subMenuName, _cratesMenuPath)
|
|
||||||
for _, _crate in pairs(_crates) do
|
|
||||||
--ctld.logTrace("_crate = [%s]", ctld.p(_crate))
|
|
||||||
if not (_crate.multiple) or ctld.enableAllCrates then
|
|
||||||
local isJTAC = ctld.isJTACUnitType(_crate.unit)
|
|
||||||
--ctld.logTrace("isJTAC = [%s]", ctld.p(isJTAC))
|
|
||||||
if not isJTAC or (isJTAC and ctld.JTAC_dropEnabled) then
|
|
||||||
if _crate.side == nil or (_crate.side == _unit:getCoalition()) then
|
|
||||||
local _crateRadioMsg = _crate.desc
|
|
||||||
--add in the number of crates required to build something
|
|
||||||
if _crate.cratesRequired ~= nil and _crate.cratesRequired > 1 then
|
|
||||||
_crateRadioMsg = _crateRadioMsg .. " (" .. _crate.cratesRequired ..
|
|
||||||
")"
|
|
||||||
end
|
|
||||||
if _crate.multiple then
|
|
||||||
_crateRadioMsg = "* " .. _crateRadioMsg
|
|
||||||
end
|
|
||||||
local _menuEntry = { text = _crateRadioMsg, crate = _crate }
|
|
||||||
--ctld.logTrace("_menuEntry = [%s]", ctld.p(_menuEntry))
|
|
||||||
table.insert(menuEntries, _menuEntry)
|
|
||||||
end
|
end
|
||||||
|
if _crate.multiple then
|
||||||
|
_crateRadioMsg = "* " .. _crateRadioMsg
|
||||||
|
end
|
||||||
|
local _menuEntry = { text = _crateRadioMsg, crate = _crate }
|
||||||
|
--ctld.logTrace("_menuEntry = [%s]", ctld.p(_menuEntry))
|
||||||
|
table.insert(menuEntries, _menuEntry)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _i, _menu in ipairs(menuEntries) do
|
end
|
||||||
--ctld.logTrace("_menu = [%s]", ctld.p(_menu))
|
for _i, _menu in ipairs(menuEntries) do
|
||||||
-- add the submenu item
|
--ctld.logTrace("_menu = [%s]", ctld.p(_menu))
|
||||||
itemNbSubmenu = itemNbSubmenu + 1
|
-- add the submenu item
|
||||||
if itemNbSubmenu == 10 and _i < #menuEntries then -- page limit reached
|
itemNbSubmenu = itemNbSubmenu + 1
|
||||||
_subMenuPath = missionCommands.addSubMenuForGroup(_groupId,
|
if itemNbSubmenu == 10 and _i < #menuEntries then -- page limit reached
|
||||||
ctld.i18n_translate("Next page"), _subMenuPath)
|
_subMenuPath = missionCommands.addSubMenuForGroup(_groupId,
|
||||||
itemNbSubmenu = 1
|
ctld.i18n_translate("Next page"), _subMenuPath)
|
||||||
end
|
itemNbSubmenu = 1
|
||||||
missionCommands.addCommandForGroup(_groupId, _menu.text, _subMenuPath,
|
|
||||||
ctld.spawnCrate, { _unitName, _menu.crate.weight })
|
|
||||||
end
|
end
|
||||||
|
missionCommands.addCommandForGroup(_groupId, _menu.text, _subMenuPath,
|
||||||
|
ctld.spawnCrate, { _unitName, _menu.crate.weight })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if (ctld.enabledFOBBuilding or ctld.enableCrates) and _unitActions.crates then
|
|
||||||
local _crateCommands = missionCommands.addSubMenuForGroup(_groupId,
|
|
||||||
ctld.i18n_translate("CTLD Commands"), _rootPath)
|
|
||||||
if ctld.vehicleCommandsPath[_unitName] == nil then
|
|
||||||
ctld.vehicleCommandsPath[_unitName] = mist.utils.deepCopy(_crateCommands)
|
|
||||||
end
|
|
||||||
if ctld.hoverPickup == false or ctld.loadCrateFromMenu == true then
|
|
||||||
if ctld.loadCrateFromMenu then
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Load Nearby Crate(s)"),
|
|
||||||
_crateCommands, ctld.loadNearbyCrate, _unitName)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if ctld.loadCrateFromMenu or ctld.hoverPickup then
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Crate(s)"),
|
|
||||||
_crateCommands, ctld.dropSlingCrate, { _unitName })
|
|
||||||
end
|
|
||||||
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Unpack Any Crate"),
|
|
||||||
_crateCommands, ctld.unpackCrates, { _unitName })
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List Nearby Crates"),
|
|
||||||
_crateCommands, ctld.listNearbyCrates, { _unitName })
|
|
||||||
|
|
||||||
if ctld.enabledFOBBuilding then
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List FOBs"), _crateCommands,
|
|
||||||
ctld.listFOBS, { _unitName })
|
|
||||||
end
|
|
||||||
|
|
||||||
if ctld.enableRepackingVehicles == true then
|
|
||||||
ctld.updateRepackMenu( _unitName ) -- add repack menu
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if ctld.enableSmokeDrop then
|
|
||||||
local _smokeMenu = missionCommands.addSubMenuForGroup(_groupId,
|
|
||||||
ctld.i18n_translate("Smoke Markers"), _rootPath)
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Red Smoke"), _smokeMenu,
|
|
||||||
ctld.dropSmoke, { _unitName, trigger.smokeColor.Red })
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Blue Smoke"), _smokeMenu,
|
|
||||||
ctld.dropSmoke, { _unitName, trigger.smokeColor.Blue })
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Orange Smoke"), _smokeMenu,
|
|
||||||
ctld.dropSmoke, { _unitName, trigger.smokeColor.Orange })
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Green Smoke"), _smokeMenu,
|
|
||||||
ctld.dropSmoke, { _unitName, trigger.smokeColor.Green })
|
|
||||||
end
|
|
||||||
|
|
||||||
if ctld.enabledRadioBeaconDrop then
|
|
||||||
local _radioCommands = missionCommands.addSubMenuForGroup(_groupId,
|
|
||||||
ctld.i18n_translate("Radio Beacons"), _rootPath)
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List Beacons"), _radioCommands,
|
|
||||||
ctld.listRadioBeacons, { _unitName })
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Beacon"), _radioCommands,
|
|
||||||
ctld.dropRadioBeacon, { _unitName })
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Remove Closest Beacon"),
|
|
||||||
_radioCommands, ctld.removeRadioBeacon, { _unitName })
|
|
||||||
elseif ctld.deployedRadioBeacons ~= {} then
|
|
||||||
local _radioCommands = missionCommands.addSubMenuForGroup(_groupId,
|
|
||||||
ctld.i18n_translate("Radio Beacons"), _rootPath)
|
|
||||||
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List Beacons"), _radioCommands,
|
|
||||||
ctld.listRadioBeacons, { _unitName })
|
|
||||||
end
|
|
||||||
|
|
||||||
ctld.addedTo[tostring(_groupId)] = true
|
|
||||||
ctld.logTrace("ctld.addedTo = %s", ctld.p(ctld.addedTo))
|
|
||||||
ctld.logTrace("done adding CTLD menu for _groupId = %s", ctld.p(_groupId))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if (ctld.enabledFOBBuilding or ctld.enableCrates) and _unitActions.crates then
|
||||||
|
local _crateCommands = missionCommands.addSubMenuForGroup(_groupId,
|
||||||
|
ctld.i18n_translate("CTLD Commands"), _rootPath)
|
||||||
|
if ctld.vehicleCommandsPath[_unitName] == nil then
|
||||||
|
ctld.vehicleCommandsPath[_unitName] = mist.utils.deepCopy(_crateCommands)
|
||||||
|
end
|
||||||
|
if ctld.hoverPickup == false or ctld.loadCrateFromMenu == true then
|
||||||
|
if ctld.loadCrateFromMenu then
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Load Nearby Crate(s)"),
|
||||||
|
_crateCommands, ctld.loadNearbyCrate, _unitName)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ctld.loadCrateFromMenu or ctld.hoverPickup then
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Crate(s)"),
|
||||||
|
_crateCommands, ctld.dropSlingCrate, { _unitName })
|
||||||
|
end
|
||||||
|
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Unpack Any Crate"),
|
||||||
|
_crateCommands, ctld.unpackCrates, { _unitName })
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List Nearby Crates"),
|
||||||
|
_crateCommands, ctld.listNearbyCrates, { _unitName })
|
||||||
|
|
||||||
|
if ctld.enabledFOBBuilding then
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List FOBs"), _crateCommands,
|
||||||
|
ctld.listFOBS, { _unitName })
|
||||||
|
end
|
||||||
|
|
||||||
|
if ctld.enableRepackingVehicles == true then
|
||||||
|
ctld.updateRepackMenu( _unitName ) -- add repack menu
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ctld.enableSmokeDrop then
|
||||||
|
local _smokeMenu = missionCommands.addSubMenuForGroup(_groupId,
|
||||||
|
ctld.i18n_translate("Smoke Markers"), _rootPath)
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Red Smoke"), _smokeMenu,
|
||||||
|
ctld.dropSmoke, { _unitName, trigger.smokeColor.Red })
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Blue Smoke"), _smokeMenu,
|
||||||
|
ctld.dropSmoke, { _unitName, trigger.smokeColor.Blue })
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Orange Smoke"), _smokeMenu,
|
||||||
|
ctld.dropSmoke, { _unitName, trigger.smokeColor.Orange })
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Green Smoke"), _smokeMenu,
|
||||||
|
ctld.dropSmoke, { _unitName, trigger.smokeColor.Green })
|
||||||
|
end
|
||||||
|
|
||||||
|
if ctld.enabledRadioBeaconDrop then
|
||||||
|
local _radioCommands = missionCommands.addSubMenuForGroup(_groupId,
|
||||||
|
ctld.i18n_translate("Radio Beacons"), _rootPath)
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List Beacons"), _radioCommands,
|
||||||
|
ctld.listRadioBeacons, { _unitName })
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Drop Beacon"), _radioCommands,
|
||||||
|
ctld.dropRadioBeacon, { _unitName })
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("Remove Closest Beacon"),
|
||||||
|
_radioCommands, ctld.removeRadioBeacon, { _unitName })
|
||||||
|
elseif ctld.deployedRadioBeacons ~= {} then
|
||||||
|
local _radioCommands = missionCommands.addSubMenuForGroup(_groupId,
|
||||||
|
ctld.i18n_translate("Radio Beacons"), _rootPath)
|
||||||
|
missionCommands.addCommandForGroup(_groupId, ctld.i18n_translate("List Beacons"), _radioCommands,
|
||||||
|
ctld.listRadioBeacons, { _unitName })
|
||||||
|
end
|
||||||
|
|
||||||
|
ctld.addedTo[tostring(_groupId)] = true
|
||||||
|
ctld.logTrace("ctld.addedTo = %s", ctld.p(ctld.addedTo))
|
||||||
|
ctld.logTrace("done adding CTLD menu for _groupId = %s", ctld.p(_groupId))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
if (not status) then
|
|
||||||
ctld.logError(string.format("Error adding f10 to transport: %s", error))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -7773,7 +7782,7 @@ function ctld.TreatOrbitJTAC(params, t)
|
|||||||
if ctld.JTACInRoute[k] == nil and ctld.OrbitInUse[k] == nil then -- if JTAC is in route
|
if ctld.JTACInRoute[k] == nil and ctld.OrbitInUse[k] == nil then -- if JTAC is in route
|
||||||
ctld.JTACInRoute[k] = timer.getTime() -- update time of the last run
|
ctld.JTACInRoute[k] = timer.getTime() -- update time of the last run
|
||||||
end
|
end
|
||||||
|
|
||||||
if ctld.jtacCurrentTargets[k] ~= nil then -- if target lased by JTAC
|
if ctld.jtacCurrentTargets[k] ~= nil then -- if target lased by JTAC
|
||||||
local droneAlti = Unit.getByName(k):getPoint().y
|
local droneAlti = Unit.getByName(k):getPoint().y
|
||||||
if ctld.OrbitInUse[k] == nil then -- if JTAC is not in orbit => start orbiting and update start time
|
if ctld.OrbitInUse[k] == nil then -- if JTAC is not in orbit => start orbiting and update start time
|
||||||
@@ -7784,7 +7793,7 @@ function ctld.TreatOrbitJTAC(params, t)
|
|||||||
if timer.getTime() > (ctld.OrbitInUse[k] + 60) then -- each 60" update orbit coord
|
if timer.getTime() > (ctld.OrbitInUse[k] + 60) then -- each 60" update orbit coord
|
||||||
ctld.StartOrbitGroup(k, ctld.jtacCurrentTargets[k].name, droneAlti, 100) -- do orbit JTAC
|
ctld.StartOrbitGroup(k, ctld.jtacCurrentTargets[k].name, droneAlti, 100) -- do orbit JTAC
|
||||||
ctld.OrbitInUse[k] = timer.getTime() -- update time of the last orbit run
|
ctld.OrbitInUse[k] = timer.getTime() -- update time of the last orbit run
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else -- if JTAC have no target
|
else -- if JTAC have no target
|
||||||
if ctld.InOrbitList(k) == true then -- JTAC orbiting, without target => stop orbit
|
if ctld.InOrbitList(k) == true then -- JTAC orbiting, without target => stop orbit
|
||||||
@@ -7802,12 +7811,12 @@ end
|
|||||||
-- Make orbit the group "_grpName", on target "_unitTargetName". _alti in meters, speed in km/h
|
-- Make orbit the group "_grpName", on target "_unitTargetName". _alti in meters, speed in km/h
|
||||||
function ctld.StartOrbitGroup(_jtacUnitName, _unitTargetName, _alti, _speed)
|
function ctld.StartOrbitGroup(_jtacUnitName, _unitTargetName, _alti, _speed)
|
||||||
if (Unit.getByName(_unitTargetName) ~= nil) and (Unit.getByName(_jtacUnitName) ~= nil) then -- si target unit and JTAC group exist
|
if (Unit.getByName(_unitTargetName) ~= nil) and (Unit.getByName(_jtacUnitName) ~= nil) then -- si target unit and JTAC group exist
|
||||||
local orbit = { id = 'Orbit',
|
local orbit = { id = 'Orbit',
|
||||||
params = {pattern = 'Circle',
|
params = {pattern = 'Circle',
|
||||||
point = mist.utils.makeVec2(mist.getAvgPos(mist.makeUnitTable({_unitTargetName}))),
|
point = mist.utils.makeVec2(mist.getAvgPos(mist.makeUnitTable({_unitTargetName}))),
|
||||||
speed = _speed,
|
speed = _speed,
|
||||||
altitude = _alti
|
altitude = _alti
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
local jtacGroupName = Unit.getByName(_jtacUnitName):getGroup():getName()
|
local jtacGroupName = Unit.getByName(_jtacUnitName):getGroup():getName()
|
||||||
Unit.getByName(_jtacUnitName):getController():popTask() -- stop current Task
|
Unit.getByName(_jtacUnitName):getController():popTask() -- stop current Task
|
||||||
@@ -7818,10 +7827,10 @@ end
|
|||||||
-- test if one unitName already is targeted by a JTAC
|
-- test if one unitName already is targeted by a JTAC
|
||||||
function ctld.InOrbitList(_grpName)
|
function ctld.InOrbitList(_grpName)
|
||||||
for k, v in pairs(ctld.OrbitInUse) do -- for each orbit in use
|
for k, v in pairs(ctld.OrbitInUse) do -- for each orbit in use
|
||||||
if k == _grpName then
|
if k == _grpName then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
-------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------
|
||||||
@@ -7853,10 +7862,10 @@ function ctld.backToRoute(_jtacUnitName)
|
|||||||
local jtacGroupName = Unit.getByName(_jtacUnitName):getGroup():getName()
|
local jtacGroupName = Unit.getByName(_jtacUnitName):getGroup():getName()
|
||||||
--local JTACRoute = mist.getGroupRoute(jtacGroupName, true) -- get the initial editor route of the current group
|
--local JTACRoute = mist.getGroupRoute(jtacGroupName, true) -- get the initial editor route of the current group
|
||||||
local JTACRoute = mist.utils.deepCopy(mist.getGroupRoute(jtacGroupName, true)) -- get the initial editor route of the current group
|
local JTACRoute = mist.utils.deepCopy(mist.getGroupRoute(jtacGroupName, true)) -- get the initial editor route of the current group
|
||||||
local newJTACRoute = ctld.adjustRoute(JTACRoute, ctld.getNearestWP(_jtacUnitName))
|
local newJTACRoute = ctld.adjustRoute(JTACRoute, ctld.getNearestWP(_jtacUnitName))
|
||||||
|
|
||||||
local Mission = {}
|
local Mission = {}
|
||||||
Mission = { id = 'Mission', params = {route = {points = newJTACRoute}}}
|
Mission = { id = 'Mission', params = {route = {points = newJTACRoute}}}
|
||||||
|
|
||||||
-- unactive orbit mode if it's on
|
-- unactive orbit mode if it's on
|
||||||
if ctld.InOrbitList(_jtacUnitName) == true then -- if JTAC orbiting => stop it
|
if ctld.InOrbitList(_jtacUnitName) == true then -- if JTAC orbiting => stop it
|
||||||
@@ -7887,26 +7896,56 @@ function ctld.adjustRoute(_initialRouteTable, _firstWpOfNewRoute) -- create a r
|
|||||||
|
|
||||||
-- apply offset (_firstWpOfNewRoute) to SwitchWaypoint tasks
|
-- apply offset (_firstWpOfNewRoute) to SwitchWaypoint tasks
|
||||||
local lastWpAsAlreadySwitchWaypoint = false
|
local lastWpAsAlreadySwitchWaypoint = false
|
||||||
for idx = 1, #adjustedRoute do
|
for idx2 = 1, #adjustedRoute do
|
||||||
for j=1, #adjustedRoute[idx].task.params.tasks do
|
if #adjustedRoute[idx2] and
|
||||||
if adjustedRoute[idx].task.params.tasks[j].id ~= "ControlledTask" then
|
#adjustedRoute[idx2].task and
|
||||||
if adjustedRoute[idx].task.params.tasks[j].params.action.id == "SwitchWaypoint" then
|
#adjustedRoute[idx2].task.params and
|
||||||
local goToWaypointIndex = adjustedRoute[idx].task.params.tasks[j].params.action.params.goToWaypointIndex
|
#adjustedRoute[idx2].task.params.tasks then
|
||||||
adjustedRoute[idx].task.params.tasks[j].params.action.params.fromWaypointIndex = idx
|
|
||||||
adjustedRoute[idx].task.params.tasks[j].params.action.params.goToWaypointIndex = mappingWP[goToWaypointIndex]
|
for j=1, #adjustedRoute[idx2].task.params.tasks do
|
||||||
if idx == #adjustedRoute then
|
if adjustedRoute[idx2].task.params.tasks[j].id and
|
||||||
lastWpAsAlreadySwitchWaypoint = true
|
adjustedRoute[idx2].task.params.tasks[j].id ~= "ControlledTask" then
|
||||||
|
|
||||||
|
if adjustedRoute[idx2].task.params.tasks[j].params and
|
||||||
|
adjustedRoute[idx2].task.params.tasks[j].params.action and
|
||||||
|
adjustedRoute[idx2].task.params.tasks[j].params.action.id and
|
||||||
|
adjustedRoute[idx2].task.params.tasks[j].params.action.id == "SwitchWaypoint" then
|
||||||
|
|
||||||
|
if adjustedRoute[idx2].task.params.tasks[j].params.action.params then
|
||||||
|
|
||||||
|
local goToWaypointIndex = adjustedRoute[idx2].task.params.tasks[j].params.action.params.goToWaypointIndex
|
||||||
|
adjustedRoute[idx2].task.params.tasks[j].params.action.params.fromWaypointIndex = idx2
|
||||||
|
adjustedRoute[idx2].task.params.tasks[j].params.action.params.goToWaypointIndex = mappingWP[goToWaypointIndex]
|
||||||
|
if idx2 == #adjustedRoute then
|
||||||
|
lastWpAsAlreadySwitchWaypoint = true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
|
||||||
else -- for "ControlledTask"
|
else -- for "ControlledTask"
|
||||||
if adjustedRoute[idx].task.params.tasks[j].params.task.params.action.id == "SwitchWaypoint" then
|
if adjustedRoute[idx2].task.params.tasks[j].params and
|
||||||
local goToWaypointIndex = adjustedRoute[idx].task.params.tasks[j].params.task.params.action.params.goToWaypointIndex
|
adjustedRoute[idx2].task.params.tasks[j].params.task and
|
||||||
adjustedRoute[idx].task.params.tasks[j].params.task.params.action.params.fromWaypointIndex = idx
|
adjustedRoute[idx2].task.params.tasks[j].params.task.params and
|
||||||
adjustedRoute[idx].task.params.tasks[j].params.task.params.action.params.goToWaypointIndex = mappingWP[goToWaypointIndex]
|
adjustedRoute[idx2].task.params.tasks[j].params.task.params.action and
|
||||||
if idx == #adjustedRoute then
|
adjustedRoute[idx2].task.params.tasks[j].params.task.params.action.id and
|
||||||
lastWpAsAlreadySwitchWaypoint = true
|
adjustedRoute[idx2].task.params.tasks[j].params.task.params.action.id == "SwitchWaypoint" then
|
||||||
|
|
||||||
|
if adjustedRoute[idx2].task.params.tasks[j].params.task.params.action.params then
|
||||||
|
|
||||||
|
local goToWaypointIndex = adjustedRoute[idx2].task.params.tasks[j].params.task.params.action.params.goToWaypointIndex
|
||||||
|
adjustedRoute[idx2].task.params.tasks[j].params.task.params.action.params.fromWaypointIndex = idx2
|
||||||
|
adjustedRoute[idx2].task.params.tasks[j].params.task.params.action.params.goToWaypointIndex = mappingWP[goToWaypointIndex]
|
||||||
|
if idx2 == #adjustedRoute then
|
||||||
|
lastWpAsAlreadySwitchWaypoint = true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -7957,7 +7996,7 @@ ctld.reconMenuName = ctld.i18n_translate("RECON") --name of the
|
|||||||
ctld.reconRadioAdded = {} --stores the groups that have had the radio menu added
|
ctld.reconRadioAdded = {} --stores the groups that have had the radio menu added
|
||||||
ctld.reconLosSearchRadius = 2000 -- search radius in meters
|
ctld.reconLosSearchRadius = 2000 -- search radius in meters
|
||||||
ctld.reconLosMarkRadius = 100 -- mark radius dimension in meters
|
ctld.reconLosMarkRadius = 100 -- mark radius dimension in meters
|
||||||
ctld.reconAutoRefreshLosTargetMarks = true -- if true recon LOS marks are automaticaly refreshed on F10 map
|
ctld.reconAutoRefreshLosTargetMarks = false -- if true recon LOS marks are automaticaly refreshed on F10 map
|
||||||
ctld.reconLastScheduleIdAutoRefresh = 0
|
ctld.reconLastScheduleIdAutoRefresh = 0
|
||||||
|
|
||||||
---- F10 RECON Menus ------------------------------------------------------------------
|
---- F10 RECON Menus ------------------------------------------------------------------
|
||||||
@@ -8465,7 +8504,7 @@ end
|
|||||||
--- Handle world events.
|
--- Handle world events.
|
||||||
ctld.eventHandler = {}
|
ctld.eventHandler = {}
|
||||||
function ctld.eventHandler:onEvent(event)
|
function ctld.eventHandler:onEvent(event)
|
||||||
ctld.logTrace("ctld.eventHandler:onEvent()")
|
--ctld.logTrace("ctld.eventHandler:onEvent()")
|
||||||
if event == nil then
|
if event == nil then
|
||||||
ctld.logError("Event handler was called with a nil event!")
|
ctld.logError("Event handler was called with a nil event!")
|
||||||
return
|
return
|
||||||
@@ -8478,7 +8517,7 @@ function ctld.eventHandler:onEvent(event)
|
|||||||
elseif event.id == world.event.S_EVENT_BIRTH then
|
elseif event.id == world.event.S_EVENT_BIRTH then
|
||||||
eventName = "S_EVENT_BIRTH"
|
eventName = "S_EVENT_BIRTH"
|
||||||
else
|
else
|
||||||
ctld.logTrace("Ignoring event %s", ctld.p(event))
|
--ctld.logTrace("Ignoring event %s", ctld.p(event))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
ctld.logDebug("caught event %s: %s", ctld.p(eventName), ctld.p(event))
|
ctld.logDebug("caught event %s: %s", ctld.p(eventName), ctld.p(event))
|
||||||
@@ -8513,7 +8552,7 @@ function ctld.eventHandler:onEvent(event)
|
|||||||
for _, aircraftType in pairs(ctld.aircraftTypeTable) do
|
for _, aircraftType in pairs(ctld.aircraftTypeTable) do
|
||||||
if aircraftType == playerTypeName then
|
if aircraftType == playerTypeName then
|
||||||
ctld.logTrace("adding by aircraft type, unitName = %s", ctld.p(unitName))
|
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
|
table.insert(ctld.transportPilotNames, unitName) -- add transport unit to the list
|
||||||
end
|
end
|
||||||
if ctld.addedTo[tostring(_groupId)] == nil then -- only if menu not already set up
|
if ctld.addedTo[tostring(_groupId)] == nil then -- only if menu not already set up
|
||||||
@@ -8591,7 +8630,8 @@ function ctld.RandomReal(mini, maxi)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Tools
|
-- Tools
|
||||||
function ctld.isValueInIpairTable(tab, value)
|
ctld.tools = {}
|
||||||
|
function ctld.tools.isValueInIpairTable(tab, value)
|
||||||
for i, v in ipairs(tab) do
|
for i, v in ipairs(tab) do
|
||||||
if v == value then
|
if v == value then
|
||||||
return true -- La valeur existe
|
return true -- La valeur existe
|
||||||
@@ -8599,6 +8639,58 @@ function ctld.isValueInIpairTable(tab, value)
|
|||||||
end
|
end
|
||||||
return false -- La valeur n'existe pas
|
return false -- La valeur n'existe pas
|
||||||
end
|
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.
|
--- Enable/Disable error boxes displayed on screen.
|
||||||
env.setErrorMessageBoxEnabled(false)
|
env.setErrorMessageBoxEnabled(false)
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ It's open-source and free as in free beer (you don't have to pay to use it), and
|
|||||||
|
|
||||||
We're always looking for help, please reach out to [Zip on Discord](https://discordapp.com/users/421317390807203850) if you want to participate in maintenance or development.
|
We're always looking for help, please reach out to [Zip on Discord](https://discordapp.com/users/421317390807203850) if you want to participate in maintenance or development.
|
||||||
|
|
||||||
|
And if you'd like to support our work, you can [buy me a coffee](https://coff.ee/veaf_zip)!
|
||||||
|
|
||||||
## Contents
|
## Contents
|
||||||
|
|
||||||
This script is a rewrite of some of the functionality of the original Complete Combat Troop Transport Script (CTTS) by Geloxo (http://forums.eagle.ru/showthread.php?t=108523), as well as adding new features.
|
This script is a rewrite of some of the functionality of the original Complete Combat Troop Transport Script (CTTS) by Geloxo (http://forums.eagle.ru/showthread.php?t=108523), as well as adding new features.
|
||||||
@@ -130,7 +132,7 @@ Optionaly, you can disable the STTS (text to speech over SRS) feature (4).
|
|||||||
![dynamic_loading]
|
![dynamic_loading]
|
||||||
|
|
||||||
### Script Setup
|
### 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.
|
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.
|
||||||
|
|
||||||
@@ -865,10 +867,11 @@ For example, if the laser code is *1688*, the frequency will be *40.40Mhz*.
|
|||||||
JTAC frequency is available through the "JTAC Status" radio menu
|
JTAC frequency is available through the "JTAC Status" radio menu
|
||||||
|
|
||||||
#### Jtac-automatic-orbiting-over-lased-target
|
#### Jtac-automatic-orbiting-over-lased-target
|
||||||
By setting parameter ctld.enableAutoOrbitingFlyingJtacOnTarget = true, a script
|
|
||||||
dedicated script puts in orbit each flying JTAC over his detected target.
|
By setting parameter ctld.enableAutoOrbitingFlyingJtacOnTarget = true, a script dedicated script puts in orbit each flying JTAC over his detected target.
|
||||||
Associated with CTLD/JTAC functions, you can assign a fly route to the JTAC drone,
|
|
||||||
this one follow it, and start orbiting when he detects a target.
|
Associated with CTLD/JTAC functions, you can assign a fly route to the JTAC drone, this one follow it, and start orbiting when he detects a target.
|
||||||
|
|
||||||
As soon as it don't detect a target, it restart following its initial route at the nearest waypoint
|
As soon as it don't detect a target, it restart following its initial route at the nearest waypoint
|
||||||
|
|
||||||
# In Game
|
# In Game
|
||||||
@@ -927,11 +930,13 @@ ctld.JTAC_WEIGHT = 15 -- kg
|
|||||||
```
|
```
|
||||||
## Limit troop Loading
|
## Limit troop Loading
|
||||||
The number of Infantries units in mission can be limited by setting the table below :
|
The number of Infantries units in mission can be limited by setting the table below :
|
||||||
ctld.nbLimitSpwanedTroops = {0, 0} -- {redLimitInfantryCount, blueLimitInfantryCount}
|
|
||||||
|
`ctld.nbLimitSpawnedTroops = {0, 0} -- {redLimitInfantryCount, blueLimitInfantryCount}`
|
||||||
|
|
||||||
When this cumulative number of troops is reached for a coalition, no more troops can be loaded onboard, and a message is sent to player.
|
When this cumulative number of troops is reached for a coalition, no more troops can be loaded onboard, and a message is sent to player.
|
||||||
|
|
||||||
If ctld.nbLimitSpwanedTroops = {0, 0} (both values at 0) the limit control is disabled.
|
If set to `ctld.nbLimitSpawnedTroops = {0, 0}` (both values at 0) the limit control is disabled. This is the default.
|
||||||
|
|
||||||
If either value is non-zero, limit control becomes active for both coalitions.
|
If either value is non-zero, limit control becomes active for both coalitions.
|
||||||
|
|
||||||
## Cargo Spawning and Sling Loading
|
## Cargo Spawning and Sling Loading
|
||||||
@@ -1024,13 +1029,14 @@ Rearming:
|
|||||||
You can also repair a partially destroyed HAWK / BUK or KUB system by dropping a repair crate next to it and unpacking. A repair crate will also re-arm the system.
|
You can also repair a partially destroyed HAWK / BUK or KUB system by dropping a repair crate next to it and unpacking. A repair crate will also re-arm the system.
|
||||||
|
|
||||||
## Crate Repacking
|
## Crate Repacking
|
||||||
The F10 menu allows you to repack units having associated crate types in the "ctld.spawnableCrates" table.
|
|
||||||
Simply land near the unit you wish to repack and select it from the list presented by the "CTLD//Vehicle/FOB transport...//Repack Vehicles" menu.
|
|
||||||
The defined radius of vehicles detection is specified by the parameter
|
|
||||||
|
|
||||||
ctld.maximumDistanceRepackableUnitsSearch = 200 -- max distance from transportUnit to search force repackable units in meters
|
The F10 menu allows you to repack units having associated crate types in the "ctld.spawnableCrates" table.
|
||||||
|
|
||||||
|
Simply land near the unit you wish to repack and select it from the list presented by the "CTLD//Vehicle/FOB transport...//Repack Vehicles" menu.
|
||||||
|
|
||||||
|
The defined radius of vehicles detection is specified by the parameter `ctld.maximumDistanceRepackableUnitsSearch` (default 200 meters).
|
||||||
|
|
||||||
WARNING: Due to technical reasons related to the refresh time of the F10 menus, there may be inconsistencies between the type of vehicles requested and those provided. It is recommended to wait 5 to 10 seconds without moving after landing and opening the F10 menu for a packaging order.
|
*WARNING*: Due to technical reasons related to the refresh time of the F10 menus, there may be inconsistencies between the type of vehicles requested and those provided. It is recommended to wait 5 to 10 seconds without moving after landing and opening the F10 menu for a packaging order.
|
||||||
|
|
||||||
## Forward Operating Base (FOB) Construction
|
## Forward Operating Base (FOB) Construction
|
||||||
FOBs can be built by loading special FOB crates from a **Logistics** unit into a C-130 or other large aircraft configured in the script. To load the crate use the F10 - Troop Commands Menu. The idea behind FOBs is to make player vs player missions even more dynamic as these can be deployed in most locations. Once destroyed the FOB can no longer be used.
|
FOBs can be built by loading special FOB crates from a **Logistics** unit into a C-130 or other large aircraft configured in the script. To load the crate use the F10 - Troop Commands Menu. The idea behind FOBs is to make player vs player missions even more dynamic as these can be deployed in most locations. Once destroyed the FOB can no longer be used.
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ mist = {}
|
|||||||
-- don't change these
|
-- don't change these
|
||||||
mist.majorVersion = 4
|
mist.majorVersion = 4
|
||||||
mist.minorVersion = 5
|
mist.minorVersion = 5
|
||||||
mist.build = "128-DYNSLOTS-01"
|
mist.build = "128-DYNSLOTS-02"
|
||||||
|
|
||||||
-- forward declaration of log shorthand
|
-- forward declaration of log shorthand
|
||||||
local log
|
local log
|
||||||
@@ -826,11 +826,11 @@ do -- the main scope
|
|||||||
if zone.verticies then
|
if zone.verticies then
|
||||||
local offset = {}
|
local offset = {}
|
||||||
for i = 1, #zone.verticies do
|
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
|
end
|
||||||
zone.offset = offset
|
zone.offset = offset
|
||||||
else
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user