Fixed error in documentation of UTILS.LoadFromFile

This commit is contained in:
kaltokri 2024-06-09 10:59:58 +02:00
parent 16dc3860f7
commit 137f0251fb

View File

@ -104,7 +104,7 @@ CALLSIGN={
Shell=3, Shell=3,
Navy_One=4, Navy_One=4,
Mauler=5, Mauler=5,
Bloodhound=6, Bloodhound=6,
}, },
-- JTAC -- JTAC
JTAC={ JTAC={
@ -418,7 +418,7 @@ function UTILS._OneLineSerialize(tbl)
end end
end end
tbl_str[#tbl_str + 1] = '}' tbl_str[#tbl_str + 1] = '}'
return table.concat(tbl_str) return table.concat(tbl_str)
else else
@ -435,7 +435,7 @@ UTILS.BasicSerialize = function(s)
if ((type(s) == 'number') or (type(s) == 'boolean') or (type(s) == 'function') or (type(s) == 'userdata') ) then if ((type(s) == 'number') or (type(s) == 'boolean') or (type(s) == 'function') or (type(s) == 'userdata') ) then
return tostring(s) return tostring(s)
elseif type(s) == "table" then elseif type(s) == "table" then
return UTILS._OneLineSerialize(s) return UTILS._OneLineSerialize(s)
elseif type(s) == 'string' then elseif type(s) == 'string' then
s = string.format('(%s)', s) s = string.format('(%s)', s)
return s return s
@ -564,15 +564,15 @@ end
-- @param #string fname File name. -- @param #string fname File name.
function UTILS.Gdump(fname) function UTILS.Gdump(fname)
if lfs and io then if lfs and io then
local fdir = lfs.writedir() .. [[Logs\]] .. fname local fdir = lfs.writedir() .. [[Logs\]] .. fname
local f = io.open(fdir, 'w') local f = io.open(fdir, 'w')
f:write(UTILS.TableShow(_G)) f:write(UTILS.TableShow(_G))
f:close() f:close()
env.info(string.format('Wrote debug data to $1', fdir)) env.info(string.format('Wrote debug data to $1', fdir))
else else
env.error("WARNING: lfs and/or io not de-sanitized - cannot dump _G!") env.error("WARNING: lfs and/or io not de-sanitized - cannot dump _G!")
@ -869,17 +869,17 @@ UTILS.tostringLLM2KData = function( lat, lon, acc)
-- degrees, decimal minutes. -- degrees, decimal minutes.
latMin = UTILS.Round(latMin, acc) latMin = UTILS.Round(latMin, acc)
lonMin = UTILS.Round(lonMin, acc) lonMin = UTILS.Round(lonMin, acc)
if latMin == 60 then if latMin == 60 then
latMin = 0 latMin = 0
latDeg = latDeg + 1 latDeg = latDeg + 1
end end
if lonMin == 60 then if lonMin == 60 then
lonMin = 0 lonMin = 0
lonDeg = lonDeg + 1 lonDeg = lonDeg + 1
end end
local minFrmtStr -- create the formatting string for the minutes place local minFrmtStr -- create the formatting string for the minutes place
if acc <= 0 then -- no decimal place. if acc <= 0 then -- no decimal place.
minFrmtStr = '%02d' minFrmtStr = '%02d'
@ -887,7 +887,7 @@ UTILS.tostringLLM2KData = function( lat, lon, acc)
local width = 3 + acc -- 01.310 - that's a width of 6, for example. local width = 3 + acc -- 01.310 - that's a width of 6, for example.
minFrmtStr = '%0' .. width .. '.' .. acc .. 'f' minFrmtStr = '%0' .. width .. '.' .. acc .. 'f'
end end
-- 024 23'N or 024 23.123'N -- 024 23'N or 024 23.123'N
return latHemi..string.format('%02d:', latDeg) .. string.format(minFrmtStr, latMin), lonHemi..string.format('%02d:', lonDeg) .. string.format(minFrmtStr, lonMin) return latHemi..string.format('%02d:', latDeg) .. string.format(minFrmtStr, latMin), lonHemi..string.format('%02d:', lonDeg) .. string.format(minFrmtStr, lonMin)
@ -899,9 +899,9 @@ UTILS.tostringMGRS = function(MGRS, acc) --R2.1
if acc <= 0 then if acc <= 0 then
return MGRS.UTMZone .. ' ' .. MGRS.MGRSDigraph return MGRS.UTMZone .. ' ' .. MGRS.MGRSDigraph
else else
if acc > 5 then acc = 5 end if acc > 5 then acc = 5 end
-- Test if Easting/Northing have less than 4 digits. -- Test if Easting/Northing have less than 4 digits.
--MGRS.Easting=123 -- should be 00123 --MGRS.Easting=123 -- should be 00123
--MGRS.Northing=5432 -- should be 05432 --MGRS.Northing=5432 -- should be 05432
@ -1384,7 +1384,7 @@ end
function UTILS.VecDist2D(a, b) function UTILS.VecDist2D(a, b)
local d = math.huge local d = math.huge
if (not a) or (not b) then return d end if (not a) or (not b) then return d end
local c={x=b.x-a.x, y=b.y-a.y} local c={x=b.x-a.x, y=b.y-a.y}
@ -1400,12 +1400,12 @@ end
-- @param DCS#Vec3 b Vector in 3D with x, y, z components. -- @param DCS#Vec3 b Vector in 3D with x, y, z components.
-- @return #number Distance between the vectors. -- @return #number Distance between the vectors.
function UTILS.VecDist3D(a, b) function UTILS.VecDist3D(a, b)
local d = math.huge local d = math.huge
if (not a) or (not b) then return d end if (not a) or (not b) then return d end
local c={x=b.x-a.x, y=b.y-a.y, z=b.z-a.z} local c={x=b.x-a.x, y=b.y-a.y, z=b.z-a.z}
d=math.sqrt(UTILS.VecDot(c, c)) d=math.sqrt(UTILS.VecDot(c, c))
@ -1801,7 +1801,7 @@ function UTILS.GetCoalitionEnemy(Coalition, Neutral)
local Coalitions={} local Coalitions={}
if Coalition then if Coalition then
if Coalition==coalition.side.RED then if Coalition==coalition.side.RED then
Coalitions={coalition.side.BLUE} Coalitions={coalition.side.BLUE}
elseif Coalition==coalition.side.BLUE then elseif Coalition==coalition.side.BLUE then
Coalitions={coalition.side.RED} Coalitions={coalition.side.RED}
@ -1809,7 +1809,7 @@ function UTILS.GetCoalitionEnemy(Coalition, Neutral)
Coalitions={coalition.side.RED, coalition.side.BLUE} Coalitions={coalition.side.RED, coalition.side.BLUE}
end end
end end
if Neutral then if Neutral then
table.insert(Coalitions, coalition.side.NEUTRAL) table.insert(Coalitions, coalition.side.NEUTRAL)
end end
@ -1840,17 +1840,17 @@ end
-- @param #number Typename The type name. -- @param #number Typename The type name.
-- @return #string The Reporting name or "Bogey". -- @return #string The Reporting name or "Bogey".
function UTILS.GetReportingName(Typename) function UTILS.GetReportingName(Typename)
local typename = string.lower(Typename) local typename = string.lower(Typename)
for name, value in pairs(ENUMS.ReportingName.NATO) do for name, value in pairs(ENUMS.ReportingName.NATO) do
local svalue = string.lower(value) local svalue = string.lower(value)
if string.find(typename,svalue,1,true) then if string.find(typename,svalue,1,true) then
return name return name
end end
end end
return "Bogey" return "Bogey"
end end
--- Get the callsign name from its enumerator value --- Get the callsign name from its enumerator value
@ -1881,49 +1881,49 @@ function UTILS.GetCallsignName(Callsign)
return name return name
end end
end end
for name, value in pairs(CALLSIGN.B1B) do for name, value in pairs(CALLSIGN.B1B) do
if value==Callsign then if value==Callsign then
return name return name
end end
end end
for name, value in pairs(CALLSIGN.B52) do for name, value in pairs(CALLSIGN.B52) do
if value==Callsign then if value==Callsign then
return name return name
end end
end end
for name, value in pairs(CALLSIGN.F15E) do for name, value in pairs(CALLSIGN.F15E) do
if value==Callsign then if value==Callsign then
return name return name
end end
end end
for name, value in pairs(CALLSIGN.F16) do for name, value in pairs(CALLSIGN.F16) do
if value==Callsign then if value==Callsign then
return name return name
end end
end end
for name, value in pairs(CALLSIGN.F18) do for name, value in pairs(CALLSIGN.F18) do
if value==Callsign then if value==Callsign then
return name return name
end end
end end
for name, value in pairs(CALLSIGN.FARP) do for name, value in pairs(CALLSIGN.FARP) do
if value==Callsign then if value==Callsign then
return name return name
end end
end end
for name, value in pairs(CALLSIGN.TransportAircraft) do for name, value in pairs(CALLSIGN.TransportAircraft) do
if value==Callsign then if value==Callsign then
return name return name
end end
end end
return "Ghostrider" return "Ghostrider"
end end
@ -1952,7 +1952,7 @@ function UTILS.GMTToLocalTimeDifference()
elseif theatre==DCSMAP.Sinai then elseif theatre==DCSMAP.Sinai then
return 2 -- Currently map is +2 but should be +3 (DCS bug?) return 2 -- Currently map is +2 but should be +3 (DCS bug?)
elseif theatre==DCSMAP.Kola then elseif theatre==DCSMAP.Kola then
return 3 -- Currently map is +2 but should be +3 (DCS bug?) return 3 -- Currently map is +2 but should be +3 (DCS bug?)
else else
BASE:E(string.format("ERROR: Unknown Map %s in UTILS.GMTToLocal function. Returning 0", tostring(theatre))) BASE:E(string.format("ERROR: Unknown Map %s in UTILS.GMTToLocal function. Returning 0", tostring(theatre)))
return 0 return 0
@ -2157,19 +2157,19 @@ function UTILS.GetRandomTableElement(t, replace)
BASE:I("Error in ShuffleTable: Missing or wrong type of Argument") BASE:I("Error in ShuffleTable: Missing or wrong type of Argument")
return return
end end
math.random() math.random()
math.random() math.random()
math.random() math.random()
local r=math.random(#t) local r=math.random(#t)
local element=t[r] local element=t[r]
if not replace then if not replace then
table.remove(t, r) table.remove(t, r)
end end
return element return element
end end
@ -2198,7 +2198,7 @@ function UTILS.IsLoadingDoorOpen( unit_name )
BASE:T(unit_name .. " a side door is open ") BASE:T(unit_name .. " a side door is open ")
return true return true
end end
if string.find(type_name, "SA342" ) and (unit:getDrawArgumentValue(34) == 1) then if string.find(type_name, "SA342" ) and (unit:getDrawArgumentValue(34) == 1) then
BASE:T(unit_name .. " front door(s) are open or doors removed") BASE:T(unit_name .. " front door(s) are open or doors removed")
return true return true
@ -2223,7 +2223,7 @@ function UTILS.IsLoadingDoorOpen( unit_name )
BASE:T(unit_name .. " door is open") BASE:T(unit_name .. " door is open")
return true return true
end end
if type_name == "UH-60L" and (unit:getDrawArgumentValue(401) == 1 or unit:getDrawArgumentValue(402) == 1) then if type_name == "UH-60L" and (unit:getDrawArgumentValue(401) == 1 or unit:getDrawArgumentValue(402) == 1) then
BASE:T(unit_name .. " cargo door is open") BASE:T(unit_name .. " cargo door is open")
return true return true
@ -2233,27 +2233,27 @@ function UTILS.IsLoadingDoorOpen( unit_name )
BASE:T(unit_name .. " front door(s) are open") BASE:T(unit_name .. " front door(s) are open")
return true return true
end end
if type_name == "AH-64D_BLK_II" then if type_name == "AH-64D_BLK_II" then
BASE:T(unit_name .. " front door(s) are open") BASE:T(unit_name .. " front door(s) are open")
return true -- no doors on this one ;) return true -- no doors on this one ;)
end end
if type_name == "Bronco-OV-10A" then if type_name == "Bronco-OV-10A" then
BASE:T(unit_name .. " front door(s) are open") BASE:T(unit_name .. " front door(s) are open")
return true -- no doors on this one ;) return true -- no doors on this one ;)
end end
if type_name == "MH-60R" and (unit:getDrawArgumentValue(403) > 0 or unit:getDrawArgumentValue(403) == -1) then if type_name == "MH-60R" and (unit:getDrawArgumentValue(403) > 0 or unit:getDrawArgumentValue(403) == -1) then
BASE:T(unit_name .. " cargo door is open") BASE:T(unit_name .. " cargo door is open")
return true return true
end end
if type_name == " OH-58D" and (unit:getDrawArgumentValue(35) > 0 or unit:getDrawArgumentValue(421) == -1) then if type_name == " OH-58D" and (unit:getDrawArgumentValue(35) > 0 or unit:getDrawArgumentValue(421) == -1) then
BASE:T(unit_name .. " cargo door is open") BASE:T(unit_name .. " cargo door is open")
return true return true
end end
return false return false
end -- nil end -- nil
@ -2362,7 +2362,7 @@ function UTILS.GenerateUHFrequencies(Start,End)
local FreeUHFFrequencies = {} local FreeUHFFrequencies = {}
local _start = 220000000 local _start = 220000000
if not Start then if not Start then
while _start < 399000000 do while _start < 399000000 do
if _start ~= 243000000 then if _start ~= 243000000 then
@ -2373,7 +2373,7 @@ function UTILS.GenerateUHFrequencies(Start,End)
else else
local myend = End*1000000 or 399000000 local myend = End*1000000 or 399000000
local mystart = Start*1000000 or 220000000 local mystart = Start*1000000 or 220000000
while _start < 399000000 do while _start < 399000000 do
if _start ~= 243000000 and (_start < mystart or _start > myend) then if _start ~= 243000000 and (_start < mystart or _start > myend) then
print(_start) print(_start)
@ -2381,10 +2381,10 @@ function UTILS.GenerateUHFrequencies(Start,End)
end end
_start = _start + 500000 _start = _start + 500000
end end
end end
return FreeUHFFrequencies return FreeUHFFrequencies
end end
@ -2425,7 +2425,7 @@ function UTILS.GenerateLaserCodes()
return jtacGeneratedLaserCodes return jtacGeneratedLaserCodes
end end
--- Ensure the passed object is a table. --- Ensure the passed object is a table.
-- @param #table Object The object that should be a table. -- @param #table Object The object that should be a table.
-- @param #boolean ReturnNil If `true`, return `#nil` if `Object` is nil. Otherwise an empty table `{}` is returned. -- @param #boolean ReturnNil If `true`, return `#nil` if `Object` is nil. Otherwise an empty table `{}` is returned.
-- @return #table The object that now certainly *is* a table. -- @return #table The object that now certainly *is* a table.
@ -2437,11 +2437,11 @@ function UTILS.EnsureTable(Object, ReturnNil)
end end
else else
if ReturnNil then if ReturnNil then
return nil return nil
else else
Object={} Object={}
end end
end end
return Object return Object
@ -2453,30 +2453,30 @@ end
-- @param #table Data The LUA data structure to save. This will be e.g. a table of text lines with an \\n at the end of each line. -- @param #table Data The LUA data structure to save. This will be e.g. a table of text lines with an \\n at the end of each line.
-- @return #boolean outcome True if saving is possible, else false. -- @return #boolean outcome True if saving is possible, else false.
function UTILS.SaveToFile(Path,Filename,Data) function UTILS.SaveToFile(Path,Filename,Data)
-- Thanks to @FunkyFranky -- Thanks to @FunkyFranky
-- Check io module is available. -- Check io module is available.
if not io then if not io then
BASE:E("ERROR: io not desanitized. Can't save current file.") BASE:E("ERROR: io not desanitized. Can't save current file.")
return false return false
end end
-- Check default path. -- Check default path.
if Path==nil and not lfs then if Path==nil and not lfs then
BASE:E("WARNING: lfs not desanitized. File will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder.") BASE:E("WARNING: lfs not desanitized. File will be saved in DCS installation root directory rather than your \"Saved Games\\DCS\" folder.")
end end
-- Set path or default. -- Set path or default.
local path = nil local path = nil
if lfs then if lfs then
path=Path or lfs.writedir() path=Path or lfs.writedir()
end end
-- Set file name. -- Set file name.
local filename=Filename local filename=Filename
if path~=nil then if path~=nil then
filename=path.."\\"..filename filename=path.."\\"..filename
end end
-- write -- write
local f = assert(io.open(filename, "wb")) local f = assert(io.open(filename, "wb"))
f:write(Data) f:write(Data)
@ -2484,43 +2484,43 @@ function UTILS.SaveToFile(Path,Filename,Data)
return true return true
end end
--- Function to save an object to a file --- Function to load an object from a file.
-- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems. -- @param #string Path The path to use. Use double backslashes \\\\ on Windows filesystems.
-- @param #string Filename The name of the file. -- @param #string Filename The name of the file.
-- @return #boolean outcome True if reading is possible and successful, else false. -- @return #boolean outcome True if reading is possible and successful, else false.
-- @return #table data The data read from the filesystem (table of lines of text). Each line is one single #string! -- @return #table data The data read from the filesystem (table of lines of text). Each line is one single #string!
function UTILS.LoadFromFile(Path,Filename) function UTILS.LoadFromFile(Path,Filename)
-- Thanks to @FunkyFranky -- Thanks to @FunkyFranky
-- Check io module is available. -- Check io module is available.
if not io then if not io then
BASE:E("ERROR: io not desanitized. Can't save current state.") BASE:E("ERROR: io not desanitized. Can't save current state.")
return false return false
end end
-- Check default path. -- Check default path.
if Path==nil and not lfs then if Path==nil and not lfs then
BASE:E("WARNING: lfs not desanitized. Loading will look into your DCS installation root directory rather than your \"Saved Games\\DCS\" folder.") BASE:E("WARNING: lfs not desanitized. Loading will look into your DCS installation root directory rather than your \"Saved Games\\DCS\" folder.")
end end
-- Set path or default. -- Set path or default.
local path = nil local path = nil
if lfs then if lfs then
path=Path or lfs.writedir() path=Path or lfs.writedir()
end end
-- Set file name. -- Set file name.
local filename=Filename local filename=Filename
if path~=nil then if path~=nil then
filename=path.."\\"..filename filename=path.."\\"..filename
end end
-- Check if file exists. -- Check if file exists.
local exists=UTILS.CheckFileExists(Path,Filename) local exists=UTILS.CheckFileExists(Path,Filename)
if not exists then if not exists then
BASE:I(string.format("ERROR: File %s does not exist!",filename)) BASE:I(string.format("ERROR: File %s does not exist!",filename))
return false return false
end end
-- read -- read
local file=assert(io.open(filename, "rb")) local file=assert(io.open(filename, "rb"))
local loadeddata = {} local loadeddata = {}
@ -2547,30 +2547,30 @@ function UTILS.CheckFileExists(Path,Filename)
return false return false
end end
end end
-- Check io module is available. -- Check io module is available.
if not io then if not io then
BASE:E("ERROR: io not desanitized.") BASE:E("ERROR: io not desanitized.")
return false return false
end end
-- Check default path. -- Check default path.
if Path==nil and not lfs then if Path==nil and not lfs then
BASE:E("WARNING: lfs not desanitized. Loading will look into your DCS installation root directory rather than your \"Saved Games\\DCS\" folder.") BASE:E("WARNING: lfs not desanitized. Loading will look into your DCS installation root directory rather than your \"Saved Games\\DCS\" folder.")
end end
-- Set path or default. -- Set path or default.
local path = nil local path = nil
if lfs then if lfs then
path=Path or lfs.writedir() path=Path or lfs.writedir()
end end
-- Set file name. -- Set file name.
local filename=Filename local filename=Filename
if path~=nil then if path~=nil then
filename=path.."\\"..filename filename=path.."\\"..filename
end end
-- Check if file exists. -- Check if file exists.
local exists=_fileexists(filename) local exists=_fileexists(filename)
if not exists then if not exists then
@ -2607,7 +2607,7 @@ end
-- @return #boolean outcome True if saving is successful, else false. -- @return #boolean outcome True if saving is successful, else false.
-- @usage -- @usage
-- We will go through the list and find the corresponding group and save the current group size (0 when dead). -- We will go through the list and find the corresponding group and save the current group size (0 when dead).
-- These groups are supposed to be put on the map in the ME and have *not* moved (e.g. stationary SAM sites). -- These groups are supposed to be put on the map in the ME and have *not* moved (e.g. stationary SAM sites).
-- Position is still saved for your usage. -- Position is still saved for your usage.
-- The idea is to reduce the number of units when reloading the data again to restart the saved mission. -- The idea is to reduce the number of units when reloading the data again to restart the saved mission.
-- The data will be a simple comma separated list of groupname and size, with one header line. -- The data will be a simple comma separated list of groupname and size, with one header line.
@ -2646,12 +2646,12 @@ end
-- @return #boolean outcome True if saving is successful, else false. -- @return #boolean outcome True if saving is successful, else false.
-- @usage -- @usage
-- We will go through the set and find the corresponding group and save the current group size and current position. -- We will go through the set and find the corresponding group and save the current group size and current position.
-- The idea is to respawn the groups **spawned during an earlier run of the mission** at the given location and reduce -- The idea is to respawn the groups **spawned during an earlier run of the mission** at the given location and reduce
-- the number of units in the group when reloading the data again to restart the saved mission. Note that *dead* groups -- the number of units in the group when reloading the data again to restart the saved mission. Note that *dead* groups
-- cannot be covered with this. -- cannot be covered with this.
-- **Note** Do NOT use dashes or hashes in group template names (-,#)! -- **Note** Do NOT use dashes or hashes in group template names (-,#)!
-- The data will be a simple comma separated list of groupname and size, with one header line. -- The data will be a simple comma separated list of groupname and size, with one header line.
-- The current task/waypoint/etc cannot be restored. -- The current task/waypoint/etc cannot be restored.
function UTILS.SaveSetOfGroups(Set,Path,Filename,Structured) function UTILS.SaveSetOfGroups(Set,Path,Filename,Structured)
local filename = Filename or "SetOfGroups" local filename = Filename or "SetOfGroups"
local data = "--Save SET of groups: "..Filename .."\n" local data = "--Save SET of groups: "..Filename .."\n"
@ -2666,7 +2666,7 @@ function UTILS.SaveSetOfGroups(Set,Path,Filename,Structured)
end end
if string.find(template,"#") then if string.find(template,"#") then
template = string.gsub(name,"#(%d+)$","") template = string.gsub(name,"#(%d+)$","")
end end
local units = group:CountAliveUnits() local units = group:CountAliveUnits()
local position = group:GetVec3() local position = group:GetVec3()
if Structured then if Structured then
@ -2678,7 +2678,7 @@ function UTILS.SaveSetOfGroups(Set,Path,Filename,Structured)
data = string.format("%s%s,%s,%d,%d,%d,%d,%s\n",data,name,template,units,position.x,position.y,position.z,strucdata) data = string.format("%s%s,%s,%d,%d,%d,%d,%s\n",data,name,template,units,position.x,position.y,position.z,strucdata)
else else
data = string.format("%s%s,%s,%d,%d,%d,%d\n",data,name,template,units,position.x,position.y,position.z) data = string.format("%s%s,%s,%d,%d,%d,%d\n",data,name,template,units,position.x,position.y,position.z)
end end
end end
end end
-- save the data -- save the data
@ -2749,16 +2749,16 @@ end
-- @return #table Table of data objects (tables) containing groupname, coordinate and group object. Returns nil when file cannot be read. -- @return #table Table of data objects (tables) containing groupname, coordinate and group object. Returns nil when file cannot be read.
-- @return #table When using Cinematic: table of names of smoke and fire objects, so they can be extinguished with `COORDINATE.StopBigSmokeAndFire( name )` -- @return #table When using Cinematic: table of names of smoke and fire objects, so they can be extinguished with `COORDINATE.StopBigSmokeAndFire( name )`
function UTILS.LoadStationaryListOfGroups(Path,Filename,Reduce,Structured,Cinematic,Effect,Density) function UTILS.LoadStationaryListOfGroups(Path,Filename,Reduce,Structured,Cinematic,Effect,Density)
local fires = {} local fires = {}
local function Smokers(name,coord,effect,density) local function Smokers(name,coord,effect,density)
local eff = math.random(8) local eff = math.random(8)
if type(effect) == "number" then eff = effect end if type(effect) == "number" then eff = effect end
coord:BigSmokeAndFire(eff,density,name) coord:BigSmokeAndFire(eff,density,name)
table.insert(fires,name) table.insert(fires,name)
end end
local function Cruncher(group,typename,anzahl) local function Cruncher(group,typename,anzahl)
local units = group:GetUnits() local units = group:GetUnits()
local reduced = 0 local reduced = 0
@ -2776,7 +2776,7 @@ function UTILS.LoadStationaryListOfGroups(Path,Filename,Reduce,Structured,Cinema
end end
end end
end end
local reduce = true local reduce = true
if Reduce == false then reduce = false end if Reduce == false then reduce = false end
local filename = Filename or "StateListofGroups" local filename = Filename or "StateListofGroups"
@ -2818,13 +2818,13 @@ function UTILS.LoadStationaryListOfGroups(Path,Filename,Reduce,Structured,Cinema
end end
local reduce = false local reduce = false
if loadednumber < _number then reduce = true end if loadednumber < _number then reduce = true end
--BASE:I(string.format("Looking at: %s | Original number: %d | Loaded number: %d | Reduce: %s",_name,_number,loadednumber,tostring(reduce))) --BASE:I(string.format("Looking at: %s | Original number: %d | Loaded number: %d | Reduce: %s",_name,_number,loadednumber,tostring(reduce)))
if reduce then if reduce then
Cruncher(actualgroup,_name,_number-loadednumber) Cruncher(actualgroup,_name,_number-loadednumber)
end end
end end
else else
local reduction = actualgroup:CountAliveUnits() - size local reduction = actualgroup:CountAliveUnits() - size
@ -2839,7 +2839,7 @@ function UTILS.LoadStationaryListOfGroups(Path,Filename,Reduce,Structured,Cinema
end end
end end
table.insert(datatable,data) table.insert(datatable,data)
end end
else else
return nil return nil
end end
@ -2854,11 +2854,11 @@ end
-- @param #boolean Cinematic (Optional, needs Structured=true) If true, place a fire/smoke effect on the dead static position. -- @param #boolean Cinematic (Optional, needs Structured=true) If true, place a fire/smoke effect on the dead static position.
-- @param #number Effect (Optional for Cinematic) What effect to use. Defaults to a random effect. Smoke presets are: 1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke. -- @param #number Effect (Optional for Cinematic) What effect to use. Defaults to a random effect. Smoke presets are: 1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke.
-- @param #number Density (Optional for Cinematic) What smoke density to use, can be 0 to 1. Defaults to 0.5. -- @param #number Density (Optional for Cinematic) What smoke density to use, can be 0 to 1. Defaults to 0.5.
-- @return Core.Set#SET_GROUP Set of GROUP objects. -- @return Core.Set#SET_GROUP Set of GROUP objects.
-- Returns nil when file cannot be read. Returns a table of data entries if Spawn is false: `{ groupname=groupname, size=size, coordinate=coordinate, template=template }` -- Returns nil when file cannot be read. Returns a table of data entries if Spawn is false: `{ groupname=groupname, size=size, coordinate=coordinate, template=template }`
-- @return #table When using Cinematic: table of names of smoke and fire objects, so they can be extinguished with `COORDINATE.StopBigSmokeAndFire( name )` -- @return #table When using Cinematic: table of names of smoke and fire objects, so they can be extinguished with `COORDINATE.StopBigSmokeAndFire( name )`
function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,Density) function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,Density)
local fires = {} local fires = {}
local usedtemplates = {} local usedtemplates = {}
local spawn = true local spawn = true
@ -2866,14 +2866,14 @@ function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,D
local filename = Filename or "SetOfGroups" local filename = Filename or "SetOfGroups"
local setdata = SET_GROUP:New() local setdata = SET_GROUP:New()
local datatable = {} local datatable = {}
local function Smokers(name,coord,effect,density) local function Smokers(name,coord,effect,density)
local eff = math.random(8) local eff = math.random(8)
if type(effect) == "number" then eff = effect end if type(effect) == "number" then eff = effect end
coord:BigSmokeAndFire(eff,density,name) coord:BigSmokeAndFire(eff,density,name)
table.insert(fires,name) table.insert(fires,name)
end end
local function Cruncher(group,typename,anzahl) local function Cruncher(group,typename,anzahl)
local units = group:GetUnits() local units = group:GetUnits()
local reduced = 0 local reduced = 0
@ -2891,7 +2891,7 @@ function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,D
end end
end end
end end
local function PostSpawn(args) local function PostSpawn(args)
local spwndgrp = args[1] local spwndgrp = args[1]
local size = args[2] local size = args[2]
@ -2901,16 +2901,16 @@ function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,D
local actualsize = spwndgrp:CountAliveUnits() local actualsize = spwndgrp:CountAliveUnits()
if actualsize > size then if actualsize > size then
if Structured and structure then if Structured and structure then
local loadedstructure = {} local loadedstructure = {}
local strcset = UTILS.Split(structure,";") local strcset = UTILS.Split(structure,";")
for _,_data in pairs(strcset) do for _,_data in pairs(strcset) do
local datasplit = UTILS.Split(_data,"==") local datasplit = UTILS.Split(_data,"==")
loadedstructure[datasplit[1]] = tonumber(datasplit[2]) loadedstructure[datasplit[1]] = tonumber(datasplit[2])
end end
local originalstructure = UTILS.GetCountPerTypeName(spwndgrp) local originalstructure = UTILS.GetCountPerTypeName(spwndgrp)
for _name,_number in pairs(originalstructure) do for _name,_number in pairs(originalstructure) do
local loadednumber = 0 local loadednumber = 0
if loadedstructure[_name] then if loadedstructure[_name] then
@ -2918,11 +2918,11 @@ function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,D
end end
local reduce = false local reduce = false
if loadednumber < _number then reduce = true end if loadednumber < _number then reduce = true end
if reduce then if reduce then
Cruncher(spwndgrp,_name,_number-loadednumber) Cruncher(spwndgrp,_name,_number-loadednumber)
end end
end end
else else
local reduction = actualsize-size local reduction = actualsize-size
@ -2935,16 +2935,16 @@ function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,D
end end
end end
end end
local function MultiUse(Data) local function MultiUse(Data)
local template = Data.template local template = Data.template
if template and usedtemplates[template] and usedtemplates[template].used and usedtemplates[template].used > 1 then if template and usedtemplates[template] and usedtemplates[template].used and usedtemplates[template].used > 1 then
-- multispawn -- multispawn
if not usedtemplates[template].done then if not usedtemplates[template].done then
local spwnd = 0 local spwnd = 0
local spawngrp = SPAWN:New(template) local spawngrp = SPAWN:New(template)
spawngrp:InitLimit(0,usedtemplates[template].used) spawngrp:InitLimit(0,usedtemplates[template].used)
for _,_entry in pairs(usedtemplates[template].data) do for _,_entry in pairs(usedtemplates[template].data) do
spwnd = spwnd + 1 spwnd = spwnd + 1
local sgrp=spawngrp:SpawnFromCoordinate(_entry.coordinate,spwnd) local sgrp=spawngrp:SpawnFromCoordinate(_entry.coordinate,spwnd)
BASE:ScheduleOnce(0.5,PostSpawn,{sgrp,_entry.size,_entry.structure}) BASE:ScheduleOnce(0.5,PostSpawn,{sgrp,_entry.size,_entry.structure})
@ -2956,7 +2956,7 @@ function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,D
return false return false
end end
end end
--BASE:I("Spawn = "..tostring(spawn)) --BASE:I("Spawn = "..tostring(spawn))
if UTILS.CheckFileExists(Path,filename) then if UTILS.CheckFileExists(Path,filename) then
local outcome,loadeddata = UTILS.LoadFromFile(Path,Filename) local outcome,loadeddata = UTILS.LoadFromFile(Path,Filename)
@ -2990,13 +2990,13 @@ function UTILS.LoadSetOfGroups(Path,Filename,Spawn,Structured,Cinematic,Effect,D
end end
end end
end end
for _id,_entry in pairs (datatable) do for _id,_entry in pairs (datatable) do
if spawn and not MultiUse(_entry) and _entry.size > 0 then if spawn and not MultiUse(_entry) and _entry.size > 0 then
local group = SPAWN:New(_entry.template) local group = SPAWN:New(_entry.template)
local sgrp=group:SpawnFromCoordinate(_entry.coordinate) local sgrp=group:SpawnFromCoordinate(_entry.coordinate)
BASE:ScheduleOnce(0.5,PostSpawn,{sgrp,_entry.size,_entry.structure}) BASE:ScheduleOnce(0.5,PostSpawn,{sgrp,_entry.size,_entry.structure})
end end
end end
else else
return nil return nil
end end
@ -3025,7 +3025,7 @@ function UTILS.LoadSetOfStatics(Path,Filename)
if StaticObject then if StaticObject then
datatable:AddObject(StaticObject) datatable:AddObject(StaticObject)
end end
end end
else else
return nil return nil
end end
@ -3041,7 +3041,7 @@ end
-- @param #number Effect (Optional for Cinematic) What effect to use. Defaults to a random effect. Smoke presets are: 1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke. -- @param #number Effect (Optional for Cinematic) What effect to use. Defaults to a random effect. Smoke presets are: 1=small smoke and fire, 2=medium smoke and fire, 3=large smoke and fire, 4=huge smoke and fire, 5=small smoke, 6=medium smoke, 7=large smoke, 8=huge smoke.
-- @param #number Density (Optional for Cinematic) What smoke density to use, can be 0 to 1. Defaults to 0.5. -- @param #number Density (Optional for Cinematic) What smoke density to use, can be 0 to 1. Defaults to 0.5.
-- @return #table Table of data objects (tables) containing staticname, size (0=dead else 1), coordinate and the static object. Dead objects will have coordinate points `{x=0,y=0,z=0}` -- @return #table Table of data objects (tables) containing staticname, size (0=dead else 1), coordinate and the static object. Dead objects will have coordinate points `{x=0,y=0,z=0}`
-- @return #table When using Cinematic: table of names of smoke and fire objects, so they can be extinguished with `COORDINATE.StopBigSmokeAndFire( name )` -- @return #table When using Cinematic: table of names of smoke and fire objects, so they can be extinguished with `COORDINATE.StopBigSmokeAndFire( name )`
-- Returns nil when file cannot be read. -- Returns nil when file cannot be read.
function UTILS.LoadStationaryListOfStatics(Path,Filename,Reduce,Dead,Cinematic,Effect,Density) function UTILS.LoadStationaryListOfStatics(Path,Filename,Reduce,Dead,Cinematic,Effect,Density)
local fires = {} local fires = {}
@ -3077,7 +3077,7 @@ function UTILS.LoadStationaryListOfStatics(Path,Filename,Reduce,Dead,Cinematic,E
if Cinematic then if Cinematic then
local effect = math.random(8) local effect = math.random(8)
if type(Effect) == "number" then if type(Effect) == "number" then
effect = Effect effect = Effect
end end
coord:BigSmokeAndFire(effect,Density,staticname) coord:BigSmokeAndFire(effect,Density,staticname)
table.insert(fires,staticname) table.insert(fires,staticname)
@ -3087,7 +3087,7 @@ function UTILS.LoadStationaryListOfStatics(Path,Filename,Reduce,Dead,Cinematic,E
end end
end end
end end
end end
else else
return nil return nil
end end
@ -3135,10 +3135,10 @@ function UTILS.ToStringBRAANATO(FromGrp,ToGrp)
if aspect == "" then if aspect == "" then
BRAANATO = string.format("%s, BRA, %03d, %d miles, Angels %d, Track %s",GroupWords,bearing, rangeNM, alt, track) BRAANATO = string.format("%s, BRA, %03d, %d miles, Angels %d, Track %s",GroupWords,bearing, rangeNM, alt, track)
else else
BRAANATO = string.format("%s, BRAA, %03d, %d miles, Angels %d, %s, Track %s",GroupWords, bearing, rangeNM, alt, aspect, track) BRAANATO = string.format("%s, BRAA, %03d, %d miles, Angels %d, %s, Track %s",GroupWords, bearing, rangeNM, alt, aspect, track)
end end
end end
return BRAANATO return BRAANATO
end end
--- Check if an object is contained in a table. --- Check if an object is contained in a table.
@ -3183,7 +3183,7 @@ function UTILS.IsAnyInTable(Table, Objects, Key)
end end
end end
end end
end end
return false return false
@ -3199,30 +3199,30 @@ end
-- @param #table Color Color of the line in RGB, e.g. {1,0,0} for red -- @param #table Color Color of the line in RGB, e.g. {1,0,0} for red
-- @param #number Alpha Transparency factor, between 0.1 and 1 -- @param #number Alpha Transparency factor, between 0.1 and 1
-- @param #number LineType Line type to be used, line type: 0=No line, 1=Solid, 2=Dashed, 3=Dotted, 4=Dot dash, 5=Long dash, 6=Two dash. Default 1=Solid. -- @param #number LineType Line type to be used, line type: 0=No line, 1=Solid, 2=Dashed, 3=Dotted, 4=Dot dash, 5=Long dash, 6=Two dash. Default 1=Solid.
-- @param #boolean ReadOnly -- @param #boolean ReadOnly
function UTILS.PlotRacetrack(Coordinate, Altitude, Speed, Heading, Leg, Coalition, Color, Alpha, LineType, ReadOnly) function UTILS.PlotRacetrack(Coordinate, Altitude, Speed, Heading, Leg, Coalition, Color, Alpha, LineType, ReadOnly)
local fix_coordinate = Coordinate local fix_coordinate = Coordinate
local altitude = Altitude local altitude = Altitude
local speed = Speed or 350 local speed = Speed or 350
local heading = Heading or 270 local heading = Heading or 270
local leg_distance = Leg or 10 local leg_distance = Leg or 10
local coalition = Coalition or -1 local coalition = Coalition or -1
local color = Color or {1,0,0} local color = Color or {1,0,0}
local alpha = Alpha or 1 local alpha = Alpha or 1
local lineType = LineType or 1 local lineType = LineType or 1
speed = UTILS.IasToTas(speed, UTILS.FeetToMeters(altitude), oatcorr) speed = UTILS.IasToTas(speed, UTILS.FeetToMeters(altitude), oatcorr)
local turn_radius = 0.0211 * speed -3.01 local turn_radius = 0.0211 * speed -3.01
local point_two = fix_coordinate:Translate(UTILS.NMToMeters(leg_distance), heading, true, false) local point_two = fix_coordinate:Translate(UTILS.NMToMeters(leg_distance), heading, true, false)
local point_three = point_two:Translate(UTILS.NMToMeters(turn_radius)*2, heading - 90, true, false) local point_three = point_two:Translate(UTILS.NMToMeters(turn_radius)*2, heading - 90, true, false)
local point_four = fix_coordinate:Translate(UTILS.NMToMeters(turn_radius)*2, heading - 90, true, false) local point_four = fix_coordinate:Translate(UTILS.NMToMeters(turn_radius)*2, heading - 90, true, false)
local circle_center_fix_four = point_two:Translate(UTILS.NMToMeters(turn_radius), heading - 90, true, false) local circle_center_fix_four = point_two:Translate(UTILS.NMToMeters(turn_radius), heading - 90, true, false)
local circle_center_two_three = fix_coordinate:Translate(UTILS.NMToMeters(turn_radius), heading - 90, true, false) local circle_center_two_three = fix_coordinate:Translate(UTILS.NMToMeters(turn_radius), heading - 90, true, false)
fix_coordinate:LineToAll(point_two, coalition, color, alpha, lineType) fix_coordinate:LineToAll(point_two, coalition, color, alpha, lineType)
point_four:LineToAll(point_three, coalition, color, alpha, lineType) point_four:LineToAll(point_three, coalition, color, alpha, lineType)
@ -3935,7 +3935,7 @@ function UTILS.MGRSStringToSRSFriendly(Text,Slow)
Text = string.gsub(Text,"9","niner") Text = string.gsub(Text,"9","niner")
if Slow then if Slow then
Text = '<prosody rate="slow">'..Text..'</prosody>' Text = '<prosody rate="slow">'..Text..'</prosody>'
end end
Text = "MGRS;"..Text Text = "MGRS;"..Text
return Text return Text
end end