moar updates

MODIFIED: zones DB point.y entry for to be set to ground level at the center of the zone
MODIFIED: zones DB properties to be saved as a string
ADDED: zone.linkUnit info if present
MODIFIED: mist.DBs.missionData to have a countries list indexed by country name and their coalition
FIXED: mist.dynAddStatic heading if not present to convert 360 degress to radians
MODIFIED: mist.tostringBR to return altitude in feet to be 1000s of feet
ADDED: mist.utils.tableShowSorted function that attempts to sort the entries alphanumerically. This is mostly to more easily compare written tables in np++ like with...
MODIFIED: mist.debug.dump_G to use mist.utils.tableShowSorted instead of the older tableShow
FIXED: typo in eventHandler
FIXED: getRandomPointInPoly to use a radius value rather than a fixed value.
This commit is contained in:
mrSkortch 2023-06-28 23:55:41 -06:00
parent b9f6e11d97
commit 2e6f77452c
2 changed files with 324 additions and 42 deletions

183
mist.lua
View File

@ -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 = 116 mist.build = 118
-- forward declaration of log shorthand -- forward declaration of log shorthand
local log local log
@ -92,8 +92,9 @@ do -- the main scope
mist.DBs.missionData.files[#mist.DBs.missionData.files + 1] = mist.utils.deepCopy(fIndex) mist.DBs.missionData.files[#mist.DBs.missionData.files + 1] = mist.utils.deepCopy(fIndex)
end end
end end
-- if we add more coalition specific data then bullsye should be categorized by coaliton. For now its just the bullseye table -- if we add more coalition specific data then bullseye should be categorized by coaliton. For now its just the bullseye table
mist.DBs.missionData.bullseye = {} mist.DBs.missionData.bullseye = {}
mist.DBs.missionData.countries = {}
end end
mist.DBs.zonesByName = {} mist.DBs.zonesByName = {}
@ -104,14 +105,15 @@ do -- the main scope
for zone_ind, zone_data in pairs(env.mission.triggers.zones) do for zone_ind, zone_data in pairs(env.mission.triggers.zones) do
if type(zone_data) == 'table' then if type(zone_data) == 'table' then
local zone = mist.utils.deepCopy(zone_data) local zone = mist.utils.deepCopy(zone_data)
--log:warn(zone)
zone.point = {} -- point is used by SSE zone.point = {} -- point is used by SSE
zone.point.x = zone_data.x zone.point.x = zone_data.x
zone.point.y = 0 zone.point.y = land.getHeight({x = zone_data.x, y = zone_data.y})
zone.point.z = zone_data.y zone.point.z = zone_data.y
zone.properties = {} zone.properties = {}
if zone_data.properties then if zone_data.properties then
for propInd, prop in pairs(zone_data.properties) do for propInd, prop in pairs(zone_data.properties) do
if prop.value and type(prop.value) == 'string' and prop.value ~= "" then if prop.value and tostring(prop.value) ~= "" then
zone.properties[prop.key] = prop.value zone.properties[prop.key] = prop.value
end end
end end
@ -127,6 +129,18 @@ do -- the main scope
zone.radius = r zone.radius = r
end end
if zone.linkUnit then
local uRef = mist.DBs.unitsByName[zone.linkUnit]
if zone.verticies then
local offset = {}
for i = 1, #zone.verticies do
table.insert(offset, {dist = mist.utils.get2DDist(uRef.point, zone.verticies[i]), heading = mist.getHeadingPoints(uRef.point, zone.verticies[i]) + uRef.heading})
end
zone.offset = offset
else
zone.offset = {dist = mist.utils.get2DDist(uRef.point, zone.point), heading = mist.getHeadingPoints(uRef.point, zone.point) + uRef.heading}
end
end
mist.DBs.zonesByName[zone_data.name] = zone mist.DBs.zonesByName[zone_data.name] = zone
mist.DBs.zonesByNum[#mist.DBs.zonesByNum + 1] = mist.utils.deepCopy(zone) --[[deepcopy so that the zone in zones_by_name and the zone in mist.DBs.zonesByNum[#mist.DBs.zonesByNum + 1] = mist.utils.deepCopy(zone) --[[deepcopy so that the zone in zones_by_name and the zone in
@ -255,6 +269,7 @@ do -- the main scope
if cntry_data.id and country.names[cntry_data.id] then if cntry_data.id and country.names[cntry_data.id] then
countryName = string.lower(country.names[cntry_data.id]) countryName = string.lower(country.names[cntry_data.id])
end end
mist.DBs.missionData.countries[countryName] = coa_name
mist.DBs.units[coa_name][countryName] = {} mist.DBs.units[coa_name][countryName] = {}
mist.DBs.units[coa_name][countryName].countryId = cntry_data.id mist.DBs.units[coa_name][countryName].countryId = cntry_data.id
@ -1367,13 +1382,7 @@ do -- the main scope
local function groupSpawned(event) local function groupSpawned(event)
-- dont need to add units spawned in at the start of the mission if mist is loaded in init line -- dont need to add units spawned in at the start of the mission if mist is loaded in init line
if event.id == world.event.S_EVENT_BIRTH and timer.getTime0() < timer.getAbsTime() then if event.id == world.event.S_EVENT_BIRTH and timer.getTime0() < timer.getAbsTime() then
--log:info('unitSpawnEvent')
--log:info(event)
--log:info(event.initiator:getTypeName())
--table.insert(tempSpawnedUnits,(event.initiator))
-------
-- New functionality below.
-------
if Object.getCategory(event.initiator) == 1 and not Unit.getPlayerName(event.initiator) then -- simple player check, will need to later check to see if unit was spawned with a player in a flight if Object.getCategory(event.initiator) == 1 and not Unit.getPlayerName(event.initiator) then -- simple player check, will need to later check to see if unit was spawned with a player in a flight
--log:info('Object is a Unit') --log:info('Object is a Unit')
if Unit.getGroup(event.initiator) then if Unit.getGroup(event.initiator) then
@ -1388,7 +1397,15 @@ do -- the main scope
log:error('Group not accessible by unit in event handler. This is a DCS bug') log:error('Group not accessible by unit in event handler. This is a DCS bug')
end end
elseif Object.getCategory(event.initiator) == 3 or Object.getCategory(event.initiator) == 6 then elseif Object.getCategory(event.initiator) == 3 or Object.getCategory(event.initiator) == 6 then
--log:info('Object is Static') --log:info('staticSpawnEvent')
--log:info(event)
--log:info(event.initiator:getTypeName())
--table.insert(tempSpawnedUnits,(event.initiator))
-------
-- New functionality below.
-------
--log:info(event.initiator:getName())
--log:info('Object is Static')
tempSpawnedGroups[StaticObject.getName(event.initiator)] = {type = 'static'} tempSpawnedGroups[StaticObject.getName(event.initiator)] = {type = 'static'}
tempSpawnGroupsCounter = tempSpawnGroupsCounter + 1 tempSpawnGroupsCounter = tempSpawnGroupsCounter + 1
end end
@ -1661,8 +1678,9 @@ do -- the main scope
-- @todo write good docs -- @todo write good docs
-- @tparam table staticObj table containing data needed for the object creation -- @tparam table staticObj table containing data needed for the object creation
function mist.dynAddStatic(n) function mist.dynAddStatic(n)
--log:info(newObj)
local newObj = mist.utils.deepCopy(n) local newObj = mist.utils.deepCopy(n)
log:warn(newObj)
if newObj.units and newObj.units[1] then -- if its mist format if newObj.units and newObj.units[1] then -- if its mist format
for entry, val in pairs(newObj.units[1]) do for entry, val in pairs(newObj.units[1]) do
if newObj[entry] and newObj[entry] ~= val or not newObj[entry] then if newObj[entry] and newObj[entry] ~= val or not newObj[entry] then
@ -1720,7 +1738,7 @@ do -- the main scope
end end
if not newObj.heading then if not newObj.heading then
newObj.heading = math.random(360) newObj.heading = math.rad(math.random(360))
end end
if newObj.categoryStatic then if newObj.categoryStatic then
@ -1930,8 +1948,9 @@ do -- the main scope
-- update and verify any self tasks -- update and verify any self tasks
if newGroup.route and newGroup.route.points then if newGroup.route and newGroup.route.points then
--log:warn(newGroup.route.points)
for i, pData in pairs(newGroup.route.points) do for i, pData in pairs(newGroup.route.points) do
if pData.task and pData.task.params and pData.task.params.tasks and #pData.task.params.tasks > 0 then if pData.task and pData.task.params and pData.task.params.tasks and #pData.task.params.tasks > 0 then
for tIndex, tData in pairs(pData.task.params.tasks) do for tIndex, tData in pairs(pData.task.params.tasks) do
if tData.params and tData.params.action then if tData.params and tData.params.action then
if tData.params.action.id == "EPLRS" then if tData.params.action.id == "EPLRS" then
@ -2158,7 +2177,12 @@ do
if metric then if metric then
s = s .. ' at ' .. mist.utils.round(alt, 0) s = s .. ' at ' .. mist.utils.round(alt, 0)
else else
s = s .. ' at ' .. mist.utils.round(mist.utils.metersToFeet(alt), 0) s = s .. ' at '
local rounded = mist.utils.round(mist.utils.metersToFeet(alt/1000), 0)
s = s .. rounded
if rounded > 0 then
s = s .. "000"
end
end end
end end
return s return s
@ -5506,6 +5530,123 @@ function mist.utils.oneLineSerialize(tbl)
end end
end end
function mist.utils.tableShowSorted(tbls, v)
local vars = v or {}
local loc = vars.loc or ""
local indent = vars.indent or ""
local tableshow_tbls = vars.tableshow_tbls or {}
local tbl = tbls or {}
if type(tbl) == 'table' then --function only works for tables!
tableshow_tbls[tbl] = loc
local tbl_str = {}
tbl_str[#tbl_str + 1] = indent .. '{\n'
local sorted = {}
local function byteCompare(str1, str2)
local shorter = string.len(str1)
if shorter > string.len(str2) then
shorter = string.len(str2)
end
for i = 1, shorter do
local b1 = string.byte(str1, i)
local b2 = string.byte(str2, i)
if b1 < b2 then
return true
elseif b1 > b2 then
return false
end
end
return false
end
for ind, val in pairs(tbl) do -- serialize its fields
local indS = tostring(ind)
local ins = {ind = indS, val = val}
local index
if #sorted > 0 then
local found = false
for i = 1, #sorted do
if byteCompare(indS, tostring(sorted[i].ind)) == true then
index = i
break
end
end
end
if index then
table.insert(sorted, index, ins)
else
table.insert(sorted, ins)
end
end
--log:warn(sorted)
for i = 1, #sorted do
local ind = sorted[i].ind
local val = sorted[i].val
if type(ind) == "number" then
tbl_str[#tbl_str + 1] = indent
tbl_str[#tbl_str + 1] = loc .. '['
tbl_str[#tbl_str + 1] = tostring(ind)
tbl_str[#tbl_str + 1] = '] = '
else
tbl_str[#tbl_str + 1] = indent
tbl_str[#tbl_str + 1] = loc .. '['
tbl_str[#tbl_str + 1] = mist.utils.basicSerialize(ind)
tbl_str[#tbl_str + 1] = '] = '
end
if ((type(val) == 'number') or (type(val) == 'boolean')) then
tbl_str[#tbl_str + 1] = tostring(val)
tbl_str[#tbl_str + 1] = ',\n'
elseif type(val) == 'string' then
tbl_str[#tbl_str + 1] = mist.utils.basicSerialize(val)
tbl_str[#tbl_str + 1] = ',\n'
elseif type(val) == 'nil' then -- won't ever happen, right?
tbl_str[#tbl_str + 1] = 'nil,\n'
elseif type(val) == 'table' then
if tableshow_tbls[val] then
tbl_str[#tbl_str + 1] = ' already defined: ' .. tableshow_tbls[val] .. ',\n'
else
tableshow_tbls[val] = loc .. '["' .. ind .. '"]'
--tbl_str[#tbl_str + 1] = tostring(val) .. ' '
tbl_str[#tbl_str + 1] = mist.utils.tableShowSorted(val, {loc = loc .. '["' .. ind .. '"]', indent = indent .. ' ', tableshow_tbls = tableshow_tbls})
tbl_str[#tbl_str + 1] = ',\n'
end
elseif type(val) == 'function' then
if debug and debug.getinfo then
local fcnname = tostring(val)
local info = debug.getinfo(val, "S")
if info.what == "C" then
tbl_str[#tbl_str + 1] = ', C function\n'
else
if (string.sub(info.source, 1, 2) == [[./]]) then
tbl_str[#tbl_str + 1] = string.format('%q', 'function, defined in (' .. '-' .. info.lastlinedefined .. ')' .. info.source) ..',\n'
else
tbl_str[#tbl_str + 1] = string.format('%q', 'function, defined in (' .. '-' .. info.lastlinedefined .. ')') ..',\n'
end
end
else
tbl_str[#tbl_str + 1] = 'a function,\n'
end
else
tbl_str[#tbl_str + 1] = 'unable to serialize value type ' .. mist.utils.basicSerialize(type(val)) .. ' at index ' .. tostring(ind)
end
end
tbl_str[#tbl_str + 1] = indent .. '}'
return table.concat(tbl_str)
end
end
--- Returns table in a easy readable string representation. --- Returns table in a easy readable string representation.
-- this function is not meant for serialization because it uses -- this function is not meant for serialization because it uses
-- newlines for better readability. -- newlines for better readability.
@ -5525,7 +5666,7 @@ function mist.utils.tableShow(tbl, loc, indent, tableshow_tbls) --based on seria
tbl_str[#tbl_str + 1] = indent .. '{\n' tbl_str[#tbl_str + 1] = indent .. '{\n'
for ind,val in pairs(tbl) do -- serialize its fields for ind, val in pairs(tbl) do
if type(ind) == "number" then if type(ind) == "number" then
tbl_str[#tbl_str + 1] = indent tbl_str[#tbl_str + 1] = indent
tbl_str[#tbl_str + 1] = loc .. '[' tbl_str[#tbl_str + 1] = loc .. '['
@ -5625,10 +5766,10 @@ do -- mist.debug scope
g.country.by_idx = nil g.country.by_idx = nil
g.country.by_country = nil g.country.by_country = nil
f:write(mist.utils.tableShow(g)) f:write(mist.utils.tableShowSorted(g))
else else
f:write(mist.utils.tableShow(_G)) f:write(mist.utils.tableShowSorted(_G))
end end
f:close() f:close()
log:info('Wrote debug data to $1', fdir) log:info('Wrote debug data to $1', fdir)
@ -7555,7 +7696,7 @@ do
--log:info('create maker DB: $1', e.idx) --log:info('create maker DB: $1', e.idx)
mist.DBs.markList[e.idx] = {time = e.time, pos = e.pos, groupId = e.groupId, mType = 'panel', text = e.text, markId = e.idx, coalition = e.coalition} mist.DBs.markList[e.idx] = {time = e.time, pos = e.pos, groupId = e.groupId, mType = 'panel', text = e.text, markId = e.idx, coalition = e.coalition}
if e.unit then if e.unit then
mist.DBs.markList[e.idx].unit = e.initiaor:getName() mist.DBs.markList[e.idx].unit = e.intiator:getName()
end end
--log:info(mist.marker.list[e.idx]) --log:info(mist.marker.list[e.idx])
end end
@ -8776,7 +8917,7 @@ do -- group tasks scope
break break
end end
if j == 100 then if j == 100 then
newCoord = mist.getRandPointInCircle(avg, 50000) newCoord = mist.getRandPointInCircle(avg, radius)
log:warn("Failed to find point in poly; Giving random point from center of the poly") log:warn("Failed to find point in poly; Giving random point from center of the poly")
end end
end end

View File

@ -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 = 116 mist.build = 118
-- forward declaration of log shorthand -- forward declaration of log shorthand
local log local log
@ -92,8 +92,9 @@ do -- the main scope
mist.DBs.missionData.files[#mist.DBs.missionData.files + 1] = mist.utils.deepCopy(fIndex) mist.DBs.missionData.files[#mist.DBs.missionData.files + 1] = mist.utils.deepCopy(fIndex)
end end
end end
-- if we add more coalition specific data then bullsye should be categorized by coaliton. For now its just the bullseye table -- if we add more coalition specific data then bullseye should be categorized by coaliton. For now its just the bullseye table
mist.DBs.missionData.bullseye = {} mist.DBs.missionData.bullseye = {}
mist.DBs.missionData.countries = {}
end end
mist.DBs.zonesByName = {} mist.DBs.zonesByName = {}
@ -104,14 +105,15 @@ do -- the main scope
for zone_ind, zone_data in pairs(env.mission.triggers.zones) do for zone_ind, zone_data in pairs(env.mission.triggers.zones) do
if type(zone_data) == 'table' then if type(zone_data) == 'table' then
local zone = mist.utils.deepCopy(zone_data) local zone = mist.utils.deepCopy(zone_data)
--log:warn(zone)
zone.point = {} -- point is used by SSE zone.point = {} -- point is used by SSE
zone.point.x = zone_data.x zone.point.x = zone_data.x
zone.point.y = 0 zone.point.y = land.getHeight({x = zone_data.x, y = zone_data.y})
zone.point.z = zone_data.y zone.point.z = zone_data.y
zone.properties = {} zone.properties = {}
if zone_data.properties then if zone_data.properties then
for propInd, prop in pairs(zone_data.properties) do for propInd, prop in pairs(zone_data.properties) do
if prop.value and type(prop.value) == 'string' and prop.value ~= "" then if prop.value and tostring(prop.value) ~= "" then
zone.properties[prop.key] = prop.value zone.properties[prop.key] = prop.value
end end
end end
@ -127,6 +129,18 @@ do -- the main scope
zone.radius = r zone.radius = r
end end
if zone.linkUnit then
local uRef = mist.DBs.unitsByName[zone.linkUnit]
if zone.verticies then
local offset = {}
for i = 1, #zone.verticies do
table.insert(offset, {dist = mist.utils.get2DDist(uRef.point, zone.verticies[i]), heading = mist.getHeadingPoints(uRef.point, zone.verticies[i]) + uRef.heading})
end
zone.offset = offset
else
zone.offset = {dist = mist.utils.get2DDist(uRef.point, zone.point), heading = mist.getHeadingPoints(uRef.point, zone.point) + uRef.heading}
end
end
mist.DBs.zonesByName[zone_data.name] = zone mist.DBs.zonesByName[zone_data.name] = zone
mist.DBs.zonesByNum[#mist.DBs.zonesByNum + 1] = mist.utils.deepCopy(zone) --[[deepcopy so that the zone in zones_by_name and the zone in mist.DBs.zonesByNum[#mist.DBs.zonesByNum + 1] = mist.utils.deepCopy(zone) --[[deepcopy so that the zone in zones_by_name and the zone in
@ -255,6 +269,7 @@ do -- the main scope
if cntry_data.id and country.names[cntry_data.id] then if cntry_data.id and country.names[cntry_data.id] then
countryName = string.lower(country.names[cntry_data.id]) countryName = string.lower(country.names[cntry_data.id])
end end
mist.DBs.missionData.countries[countryName] = coa_name
mist.DBs.units[coa_name][countryName] = {} mist.DBs.units[coa_name][countryName] = {}
mist.DBs.units[coa_name][countryName].countryId = cntry_data.id mist.DBs.units[coa_name][countryName].countryId = cntry_data.id
@ -1367,13 +1382,7 @@ do -- the main scope
local function groupSpawned(event) local function groupSpawned(event)
-- dont need to add units spawned in at the start of the mission if mist is loaded in init line -- dont need to add units spawned in at the start of the mission if mist is loaded in init line
if event.id == world.event.S_EVENT_BIRTH and timer.getTime0() < timer.getAbsTime() then if event.id == world.event.S_EVENT_BIRTH and timer.getTime0() < timer.getAbsTime() then
--log:info('unitSpawnEvent')
--log:info(event)
--log:info(event.initiator:getTypeName())
--table.insert(tempSpawnedUnits,(event.initiator))
-------
-- New functionality below.
-------
if Object.getCategory(event.initiator) == 1 and not Unit.getPlayerName(event.initiator) then -- simple player check, will need to later check to see if unit was spawned with a player in a flight if Object.getCategory(event.initiator) == 1 and not Unit.getPlayerName(event.initiator) then -- simple player check, will need to later check to see if unit was spawned with a player in a flight
--log:info('Object is a Unit') --log:info('Object is a Unit')
if Unit.getGroup(event.initiator) then if Unit.getGroup(event.initiator) then
@ -1388,7 +1397,15 @@ do -- the main scope
log:error('Group not accessible by unit in event handler. This is a DCS bug') log:error('Group not accessible by unit in event handler. This is a DCS bug')
end end
elseif Object.getCategory(event.initiator) == 3 or Object.getCategory(event.initiator) == 6 then elseif Object.getCategory(event.initiator) == 3 or Object.getCategory(event.initiator) == 6 then
--log:info('Object is Static') --log:info('staticSpawnEvent')
--log:info(event)
--log:info(event.initiator:getTypeName())
--table.insert(tempSpawnedUnits,(event.initiator))
-------
-- New functionality below.
-------
--log:info(event.initiator:getName())
--log:info('Object is Static')
tempSpawnedGroups[StaticObject.getName(event.initiator)] = {type = 'static'} tempSpawnedGroups[StaticObject.getName(event.initiator)] = {type = 'static'}
tempSpawnGroupsCounter = tempSpawnGroupsCounter + 1 tempSpawnGroupsCounter = tempSpawnGroupsCounter + 1
end end
@ -1661,8 +1678,9 @@ do -- the main scope
-- @todo write good docs -- @todo write good docs
-- @tparam table staticObj table containing data needed for the object creation -- @tparam table staticObj table containing data needed for the object creation
function mist.dynAddStatic(n) function mist.dynAddStatic(n)
--log:info(newObj)
local newObj = mist.utils.deepCopy(n) local newObj = mist.utils.deepCopy(n)
log:warn(newObj)
if newObj.units and newObj.units[1] then -- if its mist format if newObj.units and newObj.units[1] then -- if its mist format
for entry, val in pairs(newObj.units[1]) do for entry, val in pairs(newObj.units[1]) do
if newObj[entry] and newObj[entry] ~= val or not newObj[entry] then if newObj[entry] and newObj[entry] ~= val or not newObj[entry] then
@ -1720,7 +1738,7 @@ do -- the main scope
end end
if not newObj.heading then if not newObj.heading then
newObj.heading = math.random(360) newObj.heading = math.rad(math.random(360))
end end
if newObj.categoryStatic then if newObj.categoryStatic then
@ -1930,8 +1948,9 @@ do -- the main scope
-- update and verify any self tasks -- update and verify any self tasks
if newGroup.route and newGroup.route.points then if newGroup.route and newGroup.route.points then
--log:warn(newGroup.route.points)
for i, pData in pairs(newGroup.route.points) do for i, pData in pairs(newGroup.route.points) do
if pData.task and pData.task.params and pData.task.params.tasks and #pData.task.params.tasks > 0 then if pData.task and pData.task.params and pData.task.params.tasks and #pData.task.params.tasks > 0 then
for tIndex, tData in pairs(pData.task.params.tasks) do for tIndex, tData in pairs(pData.task.params.tasks) do
if tData.params and tData.params.action then if tData.params and tData.params.action then
if tData.params.action.id == "EPLRS" then if tData.params.action.id == "EPLRS" then
@ -2158,7 +2177,12 @@ do
if metric then if metric then
s = s .. ' at ' .. mist.utils.round(alt, 0) s = s .. ' at ' .. mist.utils.round(alt, 0)
else else
s = s .. ' at ' .. mist.utils.round(mist.utils.metersToFeet(alt), 0) s = s .. ' at '
local rounded = mist.utils.round(mist.utils.metersToFeet(alt/1000), 0)
s = s .. rounded
if rounded > 0 then
s = s .. "000"
end
end end
end end
return s return s
@ -5506,6 +5530,123 @@ function mist.utils.oneLineSerialize(tbl)
end end
end end
function mist.utils.tableShowSorted(tbls, v)
local vars = v or {}
local loc = vars.loc or ""
local indent = vars.indent or ""
local tableshow_tbls = vars.tableshow_tbls or {}
local tbl = tbls or {}
if type(tbl) == 'table' then --function only works for tables!
tableshow_tbls[tbl] = loc
local tbl_str = {}
tbl_str[#tbl_str + 1] = indent .. '{\n'
local sorted = {}
local function byteCompare(str1, str2)
local shorter = string.len(str1)
if shorter > string.len(str2) then
shorter = string.len(str2)
end
for i = 1, shorter do
local b1 = string.byte(str1, i)
local b2 = string.byte(str2, i)
if b1 < b2 then
return true
elseif b1 > b2 then
return false
end
end
return false
end
for ind, val in pairs(tbl) do -- serialize its fields
local indS = tostring(ind)
local ins = {ind = indS, val = val}
local index
if #sorted > 0 then
local found = false
for i = 1, #sorted do
if byteCompare(indS, tostring(sorted[i].ind)) == true then
index = i
break
end
end
end
if index then
table.insert(sorted, index, ins)
else
table.insert(sorted, ins)
end
end
--log:warn(sorted)
for i = 1, #sorted do
local ind = sorted[i].ind
local val = sorted[i].val
if type(ind) == "number" then
tbl_str[#tbl_str + 1] = indent
tbl_str[#tbl_str + 1] = loc .. '['
tbl_str[#tbl_str + 1] = tostring(ind)
tbl_str[#tbl_str + 1] = '] = '
else
tbl_str[#tbl_str + 1] = indent
tbl_str[#tbl_str + 1] = loc .. '['
tbl_str[#tbl_str + 1] = mist.utils.basicSerialize(ind)
tbl_str[#tbl_str + 1] = '] = '
end
if ((type(val) == 'number') or (type(val) == 'boolean')) then
tbl_str[#tbl_str + 1] = tostring(val)
tbl_str[#tbl_str + 1] = ',\n'
elseif type(val) == 'string' then
tbl_str[#tbl_str + 1] = mist.utils.basicSerialize(val)
tbl_str[#tbl_str + 1] = ',\n'
elseif type(val) == 'nil' then -- won't ever happen, right?
tbl_str[#tbl_str + 1] = 'nil,\n'
elseif type(val) == 'table' then
if tableshow_tbls[val] then
tbl_str[#tbl_str + 1] = ' already defined: ' .. tableshow_tbls[val] .. ',\n'
else
tableshow_tbls[val] = loc .. '["' .. ind .. '"]'
--tbl_str[#tbl_str + 1] = tostring(val) .. ' '
tbl_str[#tbl_str + 1] = mist.utils.tableShowSorted(val, {loc = loc .. '["' .. ind .. '"]', indent = indent .. ' ', tableshow_tbls = tableshow_tbls})
tbl_str[#tbl_str + 1] = ',\n'
end
elseif type(val) == 'function' then
if debug and debug.getinfo then
local fcnname = tostring(val)
local info = debug.getinfo(val, "S")
if info.what == "C" then
tbl_str[#tbl_str + 1] = ', C function\n'
else
if (string.sub(info.source, 1, 2) == [[./]]) then
tbl_str[#tbl_str + 1] = string.format('%q', 'function, defined in (' .. '-' .. info.lastlinedefined .. ')' .. info.source) ..',\n'
else
tbl_str[#tbl_str + 1] = string.format('%q', 'function, defined in (' .. '-' .. info.lastlinedefined .. ')') ..',\n'
end
end
else
tbl_str[#tbl_str + 1] = 'a function,\n'
end
else
tbl_str[#tbl_str + 1] = 'unable to serialize value type ' .. mist.utils.basicSerialize(type(val)) .. ' at index ' .. tostring(ind)
end
end
tbl_str[#tbl_str + 1] = indent .. '}'
return table.concat(tbl_str)
end
end
--- Returns table in a easy readable string representation. --- Returns table in a easy readable string representation.
-- this function is not meant for serialization because it uses -- this function is not meant for serialization because it uses
-- newlines for better readability. -- newlines for better readability.
@ -5525,7 +5666,7 @@ function mist.utils.tableShow(tbl, loc, indent, tableshow_tbls) --based on seria
tbl_str[#tbl_str + 1] = indent .. '{\n' tbl_str[#tbl_str + 1] = indent .. '{\n'
for ind,val in pairs(tbl) do -- serialize its fields for ind, val in pairs(tbl) do
if type(ind) == "number" then if type(ind) == "number" then
tbl_str[#tbl_str + 1] = indent tbl_str[#tbl_str + 1] = indent
tbl_str[#tbl_str + 1] = loc .. '[' tbl_str[#tbl_str + 1] = loc .. '['
@ -5625,10 +5766,10 @@ do -- mist.debug scope
g.country.by_idx = nil g.country.by_idx = nil
g.country.by_country = nil g.country.by_country = nil
f:write(mist.utils.tableShow(g)) f:write(mist.utils.tableShowSorted(g))
else else
f:write(mist.utils.tableShow(_G)) f:write(mist.utils.tableShowSorted(_G))
end end
f:close() f:close()
log:info('Wrote debug data to $1', fdir) log:info('Wrote debug data to $1', fdir)
@ -7555,7 +7696,7 @@ do
--log:info('create maker DB: $1', e.idx) --log:info('create maker DB: $1', e.idx)
mist.DBs.markList[e.idx] = {time = e.time, pos = e.pos, groupId = e.groupId, mType = 'panel', text = e.text, markId = e.idx, coalition = e.coalition} mist.DBs.markList[e.idx] = {time = e.time, pos = e.pos, groupId = e.groupId, mType = 'panel', text = e.text, markId = e.idx, coalition = e.coalition}
if e.unit then if e.unit then
mist.DBs.markList[e.idx].unit = e.initiaor:getName() mist.DBs.markList[e.idx].unit = e.intiator:getName()
end end
--log:info(mist.marker.list[e.idx]) --log:info(mist.marker.list[e.idx])
end end
@ -8776,7 +8917,7 @@ do -- group tasks scope
break break
end end
if j == 100 then if j == 100 then
newCoord = mist.getRandPointInCircle(avg, 50000) newCoord = mist.getRandPointInCircle(avg, radius)
log:warn("Failed to find point in poly; Giving random point from center of the poly") log:warn("Failed to find point in poly; Giving random point from center of the poly")
end end
end end