FIXED: typo in mist.dynAdd
ADDED: mist.getUnitsByAttribute
ADDED: mist.getGroupsByAttribute
FIXED: typo is mist.teleportToPoint
ADDED: mist.stringCondense
ADDED: mist.debug.changeSetting
ADDED: mist.marker.add
ADDED: mist.marker.getNextId
ADDED: mist.marker.remove
ADDED: mist.marker.get
This commit is contained in:
mrSkortch 2021-08-16 01:41:40 -06:00
parent c4b96b896b
commit 28da804e80
2 changed files with 1106 additions and 196 deletions

631
mist.lua
View File

@ -39,12 +39,14 @@ mist.build = 98
-- forward declaration of log shorthand -- forward declaration of log shorthand
local log local log
local dbLog
local mistSettings = { local mistSettings = {
errorPopup = false, -- errors printed by mist logger will create popup warning you errorPopup = false, -- errors printed by mist logger will create popup warning you
warnPopup = false, warnPopup = false,
infoPopup = false, infoPopup = false,
logLevel = 'warn', logLevel = 'warn',
dbLog = 'warn',
} }
do -- the main scope do -- the main scope
@ -73,7 +75,7 @@ do -- the main scope
mist.nextGroupId = 1 mist.nextGroupId = 1
mist.nextUnitId = 1 mist.nextUnitId = 1
local dbLog
local function initDBs() -- mist.DBs scope local function initDBs() -- mist.DBs scope
mist.DBs = {} mist.DBs = {}
@ -1233,6 +1235,7 @@ do -- the main scope
end end
--- init function. --- init function.
-- creates logger, adds default event handler -- creates logger, adds default event handler
-- and calls main the first time. -- and calls main the first time.
@ -1601,7 +1604,7 @@ do -- the main scope
newGroup.country = newCountry newGroup.country = newCountry
-- update and verify any self tasks -- update and verify any self tasks
if newGroup.route and newGroup.routes.points then if newGroup.route and newGroup.route.points then
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
@ -2622,6 +2625,126 @@ do
return units_tbl return units_tbl
end end
function mist.getUnitsByAttribute(att, rnum, id)
local cEntry = {}
cEntry.typeName = att.type or att.typeName or att.typename
cEntry.country = att.country
cEntry.coalition = att.coalition
cEntry.skill = att.skill
cEntry.categry = att.category
local num = rnum or 1
if cEntry.skill == 'human' then
cEntry.skill = {'Client', 'Player'}
end
local checkedVal = {}
local units = {}
for uName, uData in pairs(mist.DBs.unitsByName) do
local matched = 0
for cName, cVal in pairs(cEntry) do
if type(cVal) == 'table' then
for sName, sVal in pairs(cVal) do
if (uData[cName] and uData[cName] == sVal) or (uData[cName] and uData[cName] == sName) then
matched = matched + 1
end
end
else
if uData[cName] and uData[cName] == cVal then
matched = matched + 1
end
end
end
if matched >= num then
if id then
units[uData.unitId] = true
else
units[uName] = true
end
end
end
local rtn = {}
for name, _ in pairs(units) do
table.insert(rtn, name)
end
return rtn
end
function mist.getGroupsByAttribute(att, rnum, id)
local cEntry = {}
cEntry.typeName = att.type or att.typeName or att.typename
cEntry.country = att.country
cEntry.coalition = att.coalition
cEntry.skill = att.skill
cEntry.categry = att.category
local num = rnum or 1
if cEntry.skill == 'human' then
cEntry.skill = {'Client', 'Player'}
end
local groups = {}
for gName, gData in pairs(mist.DBs.groupsByName) do
local matched = 0
for cName, cVal in pairs(cEntry) do
if type(cVal) == 'table' then
for sName, sVal in pairs(cVal) do
if cName == 'skill' or cName == 'typeName' then
local lMatch = 0
for uId, uData in pairs(gData.units) do
if (uData[cName] and uData[cName] == sVal) or (gData[cName] and gData[cName] == sName) then
lMatch = lMatch + 1
break
end
end
if lMatch > 0 then
matched = matched + 1
end
end
if (gData[cName] and gData[cName] == sVal) or (gData[cName] and gData[cName] == sName) then
matched = matched + 1
break
end
end
else
if cName == 'skill' or cName == 'typeName' then
local lMatch = 0
for uId, uData in pairs(gData.units) do
if (uData[cName] and uData[cName] == sVal) then
lMatch = lMatch + 1
break
end
end
if lMatch > 0 then
matched = matched + 1
end
end
if gData[cName] and gData[cName] == cVal then
matched = matched + 1
end
end
end
if matched >= num then
if id then
groups[gData.groupid] = true
else
groups[gName] = true
end
end
end
local rtn = {}
for name, _ in pairs(groups) do
table.insert(rtn, name)
end
return rtn
end
function mist.getDeadMapObjsInZones(zone_names) function mist.getDeadMapObjsInZones(zone_names)
-- zone_names: table of zone names -- zone_names: table of zone names
-- returns: table of dead map objects (indexed numerically) -- returns: table of dead map objects (indexed numerically)
@ -3543,7 +3666,7 @@ do -- group functions scope
end end
function mist.teleportToPoint(vars) -- main teleport function that all of teleport/respawn functions call function mist.teleportToPoint(vars) -- main teleport function that all of teleport/respawn functions call
--log:info(vars) --log:warn(vars)
local point = vars.point local point = vars.point
local gpName local gpName
if vars.gpName then if vars.gpName then
@ -3607,7 +3730,7 @@ do -- group functions scope
local newCoord, origCoord local newCoord, origCoord
local validTerrain = {'LAND', 'ROAD', 'SHALLOW_WATER', 'WATER', 'RUNWAY'} local validTerrain = {'LAND', 'ROAD', 'SHALLOW_WATER', 'WATER', 'RUNWAY'}
if vars.anyTarrain then if vars.anyTerrain then
-- do nothing -- do nothing
elseif vars.validTerrain then elseif vars.validTerrain then
validTerrain = vars.validTerrain validTerrain = vars.validTerrain
@ -3638,7 +3761,7 @@ do -- group functions scope
---- old ---- old
for i = 1, 100 do for i = 1, 100 do
newCoord = mist.getRandPointInCircle(point, radius, innerRadius) newCoord = mist.getRandPointInCircle(point, radius, innerRadius)
if mist.isTerrainValid(newCoord, validTerrain) then if vars.anyTerrain or mist.isTerrainValid(newCoord, validTerrain) then
origCoord = mist.utils.deepCopy(newCoord) origCoord = mist.utils.deepCopy(newCoord)
diff = {x = (newCoord.x - newGroupData.units[1].x), y = (newCoord.y - newGroupData.units[1].y)} diff = {x = (newCoord.x - newGroupData.units[1].x), y = (newCoord.y - newGroupData.units[1].y)}
valid = true valid = true
@ -3724,19 +3847,21 @@ do -- group functions scope
tempRoute = mist.getGroupRoute(gpName, true) tempRoute = mist.getGroupRoute(gpName, true)
elseif vars.route then elseif vars.route then
-- log:warn('routeExist') -- log:warn('routeExist')
tempRoute = mist.utils.deepCopy(route) tempRoute = mist.utils.deepCopy(vars.route)
end end
-- log:warn(tempRoute) -- log:warn(tempRoute)
if tempRoute and (vars.offsetRoute or vars.offsetWP1 or vars.initTasks) then if tempRoute then
for i = 1, #tempRoute do if (vars.offsetRoute or vars.offsetWP1 or vars.initTasks) then
-- log:warn(i) for i = 1, #tempRoute do
if (vars.offsetRoute) or (i == 1 and vars.offsetWP1) or (i == 1 and vars.initTasks) then -- log:warn(i)
-- log:warn('update offset') if (vars.offsetRoute) or (i == 1 and vars.offsetWP1) or (i == 1 and vars.initTasks) then
tempRoute[i].x = tempRoute[i].x + diff.x -- log:warn('update offset')
tempRoute[i].y = tempRoute[i].y + diff.y tempRoute[i].x = tempRoute[i].x + diff.x
elseif vars.initTasks and i > 1 then tempRoute[i].y = tempRoute[i].y + diff.y
--log:warn('deleteWP') elseif vars.initTasks and i > 1 then
tempRoute[i] = nil --log:warn('deleteWP')
tempRoute[i] = nil
end
end end
end end
newGroupData.route = tempRoute newGroupData.route = tempRoute
@ -4065,13 +4190,19 @@ do -- group functions scope
return choices[rtnVal] return choices[rtnVal]
end end
function mist.stringCondense(s)
local exclude = {'%-', '%(', '%)', '%_', '%[', '%]', '%.', '%#', '% ', '%{', '%}', '%$', '%%', '%?', '%+', '%^'}
for i , str in pairs(exclude) do
s = string.gsub(s, str, '')
end
return s
end
function mist.stringMatch(s1, s2, bool) function mist.stringMatch(s1, s2, bool)
local exclude = {'%-', '%(', '%)', '%_', '%[', '%]', '%.', '%#', '% ', '%{', '%}', '%$', '%%', '%?', '%+', '%^'}
if type(s1) == 'string' and type(s2) == 'string' then if type(s1) == 'string' and type(s2) == 'string' then
for i , str in pairs(exclude) do s1 = mist.stringCondense(s1)
s1 = string.gsub(s1, str, '') s2 = mist.stringCondense(s2)
s2 = string.gsub(s2, str, '')
end
if not bool then if not bool then
s1 = string.lower(s1) s1 = string.lower(s1)
s2 = string.lower(s2) s2 = string.lower(s2)
@ -4893,6 +5024,25 @@ end
do -- mist.debug scope do -- mist.debug scope
mist.debug = {} mist.debug = {}
function mist.debug.changeSetting(s)
if type(s) == 'table' then
for sName, sVal in pairs(s) do
env.info(sName)
env.info(sVal)
if type(sVal) == 'string' or type(sVal) == 'number' then
if sName == 'log' then
mistSettings[sName] = sVal
log:setLevel(sVal)
elseif sName == 'dbLog' then
mistSettings[sName] = sVal
dblog:setLevel(sVal)
end
else
mistSettings[sName] = sVal
end
end
end
end
--- Dumps the global table _G. --- Dumps the global table _G.
-- This dumps the global table _G to a file in -- This dumps the global table _G to a file in
-- the DCS\Logs directory. -- the DCS\Logs directory.
@ -6543,6 +6693,7 @@ do -- mist.demos scope
end end
end end
do do
--[[ stuff for marker panels --[[ stuff for marker panels
marker.add() add marker. Point of these functions is to simplify process and to store all mark panels added. marker.add() add marker. Point of these functions is to simplify process and to store all mark panels added.
@ -6562,10 +6713,20 @@ do
If mark added to a group before a client joins slot is synced. If mark added to a group before a client joins slot is synced.
Mark made for cliet A in Slot A. Client A leaves, Client B joins in slot A. What do they see? Mark made for cliet A in Slot A. Client A leaves, Client B joins in slot A. What do they see?
May need to automate process... May need to automate process...
Could release this. But things I might need to add/change before doing so.
- removing marks and re-adding in same sequence doesn't appear to work. May need to schedule adding mark if updating an entry.
- I really dont like the old message style code for which groups get the message. Perhaps change to unitsTable and create function for getting humanUnitsTable.
= Event Handler, and check it, for marks added via script or user to deconflict Ids.
- Full validation of passed values for a specific shape type.
]] ]]
--[[
local usedMarks = {}
local typeBase = { local typeBase = {
['Mi-8MT'] = {'Mi-8MTV2', 'Mi-8MTV', 'Mi-8'}, ['Mi-8MT'] = {'Mi-8MTV2', 'Mi-8MTV', 'Mi-8'},
['MiG-21Bis'] = {'Mig-21'}, ['MiG-21Bis'] = {'Mig-21'},
@ -6576,14 +6737,56 @@ do
local mDefs = { local mDefs = {
coa = { coa = {
['red'] = {fillColor = {.8, 0 , 0, .5}, color = {.8, 0 , 0, .5}, lineType = 2}, ['red'] = {fillColor = {.8, 0 , 0, .5}, color = {.8, 0 , 0, .5}, lineType = 2, fontSize = 16},
['blue'] = {fillColor = {0, 0 , 0.8, .5}, color = {0, 0 , 0.8, .5}, lineType = 2}, ['blue'] = {fillColor = {0, 0 , 0.8, .5}, color = {0, 0 , 0.8, .5}, lineType = 2, fontSize = 16},
['all'] = {fillColor = {.1, .1 , .1, .5}, color = {.9, .9 , .9, .5}, lineType = 2, fontSize = 16},
['neutral'] = {fillColor = {.1, .1 , .1, .5}, color = {.2, .2 , .2, .5}, lineType = 2, fontSize = 16},
}, },
} }
local userDefs = {} local userDefs = {['red'] = {},['blue'] = {},['all'] = {},['neutral'] = {}}
local mId = 1337 local mId = 1000
local tNames = {'line', 'circle','rect', 'arrow', 'text', 'quad', 'freeform'}
local tLines = {[0] = 'no line', [1] = 'solid', [2] = 'dashed',[3] = 'dotted', [4] = 'dot dash' ,[5] = 'long dash', [6] = 'two dash'}
local coas = {[-1] = 'all', [0] = 'neutral', [1] = 'red', [2] = 'blue'}
local altNames = {['poly'] = 7, ['lines'] = 1, ['polygon'] = 7 }
local function draw(s)
--log:warn(s)
if type(s) == 'table' then
local mType = s.markType
if mType == 'panel' then
if markScope == 'coa' then
trigger.action.markToCoalition(s.markId, s.text, s.pos, s.markFor, s.readOnly)
elseif markScope == 'group' then
trigger.action.markToGroup(s.markId, s.text, s.pos, s.markFor, s.readOnly)
else
trigger.action.markToAll(s.markId, s.text, s.pos, s.readOnly)
end
elseif mType == 'line' then
trigger.action.lineToAll(s.coa, s.markId, s.pos[1], s.pos[2], s.color, s.fillColor, s.lineType, s.readOnly, s.message)
elseif mType == 'circle' then
trigger.action.circleToAll(s.coa, s.markId, s.pos[1], s.radius, s.color, s.fillColor, s.lineType, s.readOnly, s.message)
elseif mType == 'rect' then
trigger.action.rectToAll(s.coa, s.markId, s.pos[1], s.pos[2], s.color, s.fillColor, s.lineType, s.readOnly, s.message)
elseif mType == 'arrow' then
trigger.action.arrowToAll(s.coa, s.markId, s.pos[1], s.pos[2], s.color, s.fillColor, s.lineType, s.readOnly, s.message)
elseif mType == 'text' then
trigger.action.textToAll(s.coa, s.markId, s.pos[1], s.color, s.fillColor, fontSize, s.readOnly, s.text)
elseif mType == 'quad' then
trigger.action.quadToAll(s.coa, s.markId, s.pos[1], s.pos[2], s.pos[3], s.pos[4], s.color, s.fillColor, s.lineType, s.readOnly, s.message)
end
if s.name and not usedMarks[s.name] then
usedMarks[s.name] = s.markId
end
elseif type(s) == 'string' then
--log:warn(s)
mist.utils.dostring(s)
end
end
mist.marker = {} mist.marker = {}
mist.marker.list = {} mist.marker.list = {}
@ -6591,20 +6794,100 @@ do
for id, name in pairs(recList) do for id, name in pairs(recList) do
if name == spamBlockOn then if name == spamBlockOn then
log:info('already on recList') --log:info('already on recList')
return recList return recList
end end
end end
log:info('add to recList') --log:info('add to recList')
table.insert(recList, spamBlockOn) table.insert(recList, spamBlockOn)
return recList return recList
end end
local function iterate() local function iterate()
mId = mId + 1 while mId < 10000000 do
return mist.utils.deepCopy(mId) if usedMarks[mId] then
mId = mId + 1
else
return mist.utils.deepCopy(mId)
end
end
return mist.utils.deepCopy(mId)
end end
local function validateColor(val)
if type(val) == 'table' then
for i = 1, #val do
if type(val[i]) == 'number' and val[i] > 1 then
val[i] = val[i]/255 -- convert RGB values from 0-255 to 0-1 equivilent.
end
end
end
return val
end
local function checkDefs(vName, coa)
--log:warn('CheckDefs: $1 $2', vName, coa)
local coaName
if type(coa) == 'number' then
if coas[coa] then
coaName = coas[coa]
end
elseif type(coa) == 'string' then
coaName = coa
end
-- log:warn(coaName)
if userDefs[coaName] and userDefs[coaName][vName] then
return userDefs[coaName][vName]
elseif mDefs.coa[coaName] and mDefs.coa[coaName][vName] then
return mDefs.coa[coaName][vName]
end
end
function mist.marker.getNextId()
return iterate()
end
local handle = {}
function handle:onEvent(e)
if world.event.S_EVENT_MARK_ADDED == e.id and e.idx then
usedMarks[e.idx] = e.idx
if not mist.marker.list[e.idx] then
--log:info('create maker DB: $1', e.idx)
mist.marker.list[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
mist.marker.list[e.idx].unit = e.initiaor:getName()
end
--log:info(mist.marker.list[e.idx])
end
elseif world.event.S_EVENT_MARK_CHANGE == e.id and e.idx then
if mist.marker.list[e.idx] then
mist.marker.list[e.idx].text = e.text
end
elseif world.event.S_EVENT_MARK_REMOVE == e.id and e.idx then
if mist.marker.list[e.idx] then
mist.marker.list[e.idx] = nil
end
end
end
local function removeMark(id)
--log:info("Removing Mark: $1", id)
if type(id) == 'table' then
for ind, val in pairs(id) do
trigger.action.removeMark(val)
mist.marker.list[val] = nil
end
else
trigger.action.removeMark(id)
mist.marker.list[id] = nil
end
end
world.addEventHandler(handle)
function mist.marker.setDefault(vars) function mist.marker.setDefault(vars)
if vars and type(vars) == 'table' then if vars and type(vars) == 'table' then
for l1, l1Data in pairs(vars) do for l1, l1Data in pairs(vars) do
@ -6625,37 +6908,116 @@ do
end end
function mist.marker.add(vars) function mist.marker.add(vars)
log:warn('markerFunc') --log:warn('markerFunc')
log:info(vars) --log:warn(vars)
local pos = vars.point or vars.points or vars.pos local pos = vars.point or vars.points or vars.pos
local text = vars.text local text = vars.text or ''
local markFor = vars.markFor local markFor = vars.markFor
local id = vars.id local markForCoa = vars.markForCoa -- optional, can be used if you just want to mark to a specific coa/all
local mType = vars.mType local id = vars.id or vars.markId or vars.markid
local mType = vars.mType or 0
local color = vars.color local color = vars.color
local fillColor = vars.fillColor local fillColor = vars.fillColor
local lineType = vars.lineType local lineType = vars.lineType or 2
local readOnly = vars.readOnly local readOnly = vars.readOnly or true
local displayMessage= vars.displayMessage local message = vars.message
local fontSize = vars.fontSize
local name = vars.name
local radius = vars.radius or 500
local coa = -1
local usedId = 0
if not id then
else if id then
if type(id) ~= 'number' then
name = id
usedId = iterate()
end
--log:info('checkIfIdExist: $1', id)
--[[
Maybe it should treat id or name as the same thing/single value.
If passed number it will use that as the first Id used and will delete/update any marks associated with that same value.
]]
local lId = id or name
if mist.marker.list[id] then ---------- NEED A BETTER WAY TO ASSOCIATE THE ID VALUE. CUrrnetly deleting from table and checking if that deleted entry exists which it wont.
--log:warn('active mark to be removed: $1', id)
name = mist.marker.list[id].name or id
removeMark(id)
elseif usedMarks[id] then
--log:info('exists in usedMarks: $1', id)
removeMark(usedMarks[id])
elseif name and usedMarks[name] then
--log:info('exists in usedMarks: $1', name)
removeMark(usedMarks[name])
end
usedId = iterate()
usedMarks[id] = usedId -- redefine the value used
end end
if name then
if usedId == 0 then
usedId = iterate()
end
usedMarks[name] = usedId
end
if mType then
if type(mType) == 'string' then
for i = 1, #tNames do
--log:warn(tNames[i])
if mist.stringMatch(mType, tNames[i]) then
mType = i
break
end
end
elseif type(mType) == 'number' and mType > #tNames then
mType = 0
end
end
--log:warn(mType)
local markScope = 'all' local markScope = 'all'
local markForTable = {} local markForTable = {}
if pos then
pos = mist.utils.makeVec3(pos) if pos then
if pos[1] then
for i = 1, #pos do
pos[i] = mist.utils.makeVec3(pos[i])
end
else
pos[1] = mist.utils.makeVec3(pos)
end
end end
if text and type(text) ~= string then if text and type(text) ~= string then
text = tostring(text) text = tostring(text)
else
text = ''
end end
if markFor then if markForCoa then
if type(markForCoa) == 'string' then
if tonumber(markForCoa) then
coa = coas[tonumber(markForCoa)]
markScope = 'coa'
else
for ind, cName in pairs(coas) do
if mist.stringMatch(cName, markForCoa) then
coa = ind
markScope = 'coa'
break
end
end
end
end
elseif markFor then
if type(markFor) == 'number' then -- groupId if type(markFor) == 'number' then -- groupId
if mist.DBs.groupsById[markFor] then if mist.DBs.groupsById[markFor] then
markScope = 'group' markScope = 'group'
@ -6667,12 +7029,10 @@ do
end end
elseif type(markFor) == 'table' then -- multiple groupName, country, coalition, all elseif type(markFor) == 'table' then -- multiple groupName, country, coalition, all
markScope = 'table' markScope = 'table'
log:info(markFor) --log:warn(markFor)
for forIndex, forData in pairs(markFor) do -- need to rethink this part and organization. Gotta be a more logical way to send messages to coa, groups, or all. for forIndex, forData in pairs(markFor) do -- need to rethink this part and organization. Gotta be a more logical way to send messages to coa, groups, or all.
log:info(forIndex)
log:info(forData)
for list, listData in pairs(forData) do for list, listData in pairs(forData) do
log:info(listData) --log:warn(listData)
forIndex = string.lower(forIndex) forIndex = string.lower(forIndex)
if type(listData) == 'string' then if type(listData) == 'string' then
listData = string.lower(listData) listData = string.lower(listData)
@ -6681,18 +7041,29 @@ do
markScope = 'all' markScope = 'all'
break break
elseif (forIndex == 'coa' or forIndex == 'ca') then -- mark for coa or CA. elseif (forIndex == 'coa' or forIndex == 'ca') then -- mark for coa or CA.
for name, index in pairs (coalition.side) do local matches = 0
for name, index in pairs (coalition.side) do
if listData == string.lower(name) then if listData == string.lower(name) then
markScope = 'coalition' markScope = 'coa'
markFor = index
coa = index
matches = matches + 1
end end
end end
elseif (forIndex == 'countries' and string.lower(clientData.country) == listData) or (forIndex == 'units' and string.lower(clientData.unitName) == listData) then if matches > 1 then
markForTable = markSpamFilter(markForTable, clientData.groupId) markScope = 'all'
end
elseif forIndex == 'countries' then
for clienId, clientData in pairs(mist.DBs.humansById) do
if (string.lower(clientData.country) == listData) or (forIndex == 'units' and string.lower(clientData.unitName) == listData) then
markForTable = markSpamFilter(markForTable, clientData.groupId)
end
end
elseif forIndex == 'unittypes' then -- mark to group elseif forIndex == 'unittypes' then -- mark to group
-- iterate play units -- iterate play units
for clientId, clientData in pairs(mist.DBs.humansById) do for clientId, clientData in pairs(mist.DBs.humansById) do
for typeId, typeData in pairs(listData) do for typeId, typeData in pairs(listData) do
log:info(typeData) --log:warn(typeData)
local found = false local found = false
if list == 'all' or clientData.coalition and type(clientData.coalition) == 'string' and mist.stringMatch(clientData.coalition, list) then if list == 'all' or clientData.coalition and type(clientData.coalition) == 'string' and mist.stringMatch(clientData.coalition, list) then
if mist.matchString(typeData, clientData.type) then if mist.matchString(typeData, clientData.type) then
@ -6738,58 +7109,141 @@ do
markScope = 'all' markScope = 'all'
end end
if mType == 0 then
local data = {markId = usedId, text = text, pos = pos[1], markScope = markScope, markFor = markFor, markType = 'panel', name = name, time = timer.getTime()}
if markScope ~= 'table' then
-- create marks
mist.marker.list[usedId] = data-- add to the DB
else
if #markForTable > 0 then
--log:info('iterate')
local list = {}
if id and not name then
name = id
end
for i = 1, #markForTable do
local newId = iterate()
local data = {markId = newId, text = text, pos = pos[i], markFor = markForTable[i], markType = 'panel', name = name, readOnly = readOnly, time = timer.getTime()}
mist.marker.list[newId] = data
table.insert(list, data)
draw(data)
end
return list
end
end
draw(data)
return data
elseif mType > 0 then
local newId = iterate()
local fCal = {}
fCal[#fCal+1] = mType
fCal[#fCal+1] = coa
fCal[#fCal+1] = usedId
for i = 1, #pos do
fCal[#fCal+1] = pos[i]
end
if radius and mType == 2 then
fCal[#fCal+1] = radius
end
if not color then
color = checkDefs('color', coa)
else
color = validateColor(color)
end
fCal[#fCal+1] = color
if not fillColor then
fillColor = checkDefs('fillColor', coa)
else
fillColor = validateColor(fillColor)
end
fCal[#fCal+1] = fillColor
if mType == 5 then -- text to all
if not fontSize then
fontSize = checkDefs('fondSize', coa) or 16
end
fCal[#fCal+1] = fontSize
else
if not lineType then
lineType = checkDefs('lineType', coa) or 2
end
end
fCal[#fCal+1] = lineType
if not readOnly then
readOnly = true
end
fCal[#fCal+1] = readOnly
fCal[#fCal+1] = message
local data = {coa = coa, markId = usedId, pos = pos, markFor = markFor, color = color, readOnly = readOnly, message = message, fillColor = fillColor, lineType = lineType, markType = tNames[mType], name = name, radius = radius, text = text, fontSize = fontSize, time = timer.getTime()}
mist.marker.list[usedId] = data
if markScope ~= 'table' then if mType == 7 or mType == 1 then
local newId = iterate() local s = "trigger.action.markupToAll("
local data = {markId = newId, text = text, pos = pos, markScope = markScope, markFor = markFor}
-- create marks for i = 1, #fCal do
if markScope == 'coa' then --log:warn(fCal[i])
trigger.action.markToCoalition(newId, text, pos, markFor) if type(fCal[i]) == 'table' or type(fCal[i]) == 'boolean' then
elseif markScope == 'group' then s = s .. mist.utils.oneLineSerialize(fCal[i])
trigger.action.markToGroup(newId, text, pos, markFor) else
else s = s .. fCal[i]
trigger.action.markToAll(iterate(), text, pos) end
end if i < #fCal then
table.insert(mist.marker.list, data) -- add to the DB s = s .. ','
else end
if #markForTable > 0 then end
log:info('iterate')
for i = 1, #markForTable do
local newId = iterate()
local data = {markId = newId, text = text, pos = pos, markFor = markFor}
log:info(data)
table.insert(mist.marker.list, data)
trigger.action.markToGroup(newId, text, pos, markForTable[i])
end
end
end
s = s .. ')'
if name then
usedMarks[name] = usedId
end
draw(s)
else
draw(data)
end
return data
end
end end
function mist.marker.remove(id) function mist.marker.remove(id)
for i, data in pairs(mist.marker.list) do removeMark(id)
if id == data.markId then
trigger.action.removeMark(id)
end
end
end end
function mist.marker.get(id) function mist.marker.get(id)
if mist.marker.lis[id] then
return mist.marker.lis[id]
end
local names = {}
for markId, data in pairs(mist.marker.list) do
if data.name and data.name == id then
table.insert(names, data)
end
end
if #names > 0 then
return names
end
end end
function mist.marker.coords(pos, cType, markFor, id) -- wrapper function to just display coordinates of a specific format at location --function mist.marker.coords(pos, cType, markFor, id) -- wrapper function to just display coordinates of a specific format at location
end --end
]]
end end
--- Time conversion functions. --- Time conversion functions.
-- @section mist.time -- @section mist.time
@ -7790,7 +8244,8 @@ do -- mist.Logger scope
-- @usage -- log everything -- @usage -- log everything
--myLogger:setLevel(3) --myLogger:setLevel(3)
function mist.Logger:setLevel(level) function mist.Logger:setLevel(level)
if not level then env.info('set Level ' .. level)
if not level then
self.level = 2 self.level = 2
else else
if type(level) == 'string' then if type(level) == 'string' then

View File

@ -39,12 +39,14 @@ mist.build = 98
-- forward declaration of log shorthand -- forward declaration of log shorthand
local log local log
local dbLog
local mistSettings = { local mistSettings = {
errorPopup = false, -- errors printed by mist logger will create popup warning you errorPopup = false, -- errors printed by mist logger will create popup warning you
warnPopup = false, warnPopup = false,
infoPopup = false, infoPopup = false,
logLevel = 'warn', logLevel = 'warn',
dbLog = 'warn',
} }
do -- the main scope do -- the main scope
@ -73,7 +75,7 @@ do -- the main scope
mist.nextGroupId = 1 mist.nextGroupId = 1
mist.nextUnitId = 1 mist.nextUnitId = 1
local dbLog
local function initDBs() -- mist.DBs scope local function initDBs() -- mist.DBs scope
mist.DBs = {} mist.DBs = {}
@ -1233,6 +1235,7 @@ do -- the main scope
end end
--- init function. --- init function.
-- creates logger, adds default event handler -- creates logger, adds default event handler
-- and calls main the first time. -- and calls main the first time.
@ -1601,7 +1604,7 @@ do -- the main scope
newGroup.country = newCountry newGroup.country = newCountry
-- update and verify any self tasks -- update and verify any self tasks
if newGroup.route and newGroup.routes.points then if newGroup.route and newGroup.route.points then
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
@ -2622,6 +2625,126 @@ do
return units_tbl return units_tbl
end end
function mist.getUnitsByAttribute(att, rnum, id)
local cEntry = {}
cEntry.typeName = att.type or att.typeName or att.typename
cEntry.country = att.country
cEntry.coalition = att.coalition
cEntry.skill = att.skill
cEntry.categry = att.category
local num = rnum or 1
if cEntry.skill == 'human' then
cEntry.skill = {'Client', 'Player'}
end
local checkedVal = {}
local units = {}
for uName, uData in pairs(mist.DBs.unitsByName) do
local matched = 0
for cName, cVal in pairs(cEntry) do
if type(cVal) == 'table' then
for sName, sVal in pairs(cVal) do
if (uData[cName] and uData[cName] == sVal) or (uData[cName] and uData[cName] == sName) then
matched = matched + 1
end
end
else
if uData[cName] and uData[cName] == cVal then
matched = matched + 1
end
end
end
if matched >= num then
if id then
units[uData.unitId] = true
else
units[uName] = true
end
end
end
local rtn = {}
for name, _ in pairs(units) do
table.insert(rtn, name)
end
return rtn
end
function mist.getGroupsByAttribute(att, rnum, id)
local cEntry = {}
cEntry.typeName = att.type or att.typeName or att.typename
cEntry.country = att.country
cEntry.coalition = att.coalition
cEntry.skill = att.skill
cEntry.categry = att.category
local num = rnum or 1
if cEntry.skill == 'human' then
cEntry.skill = {'Client', 'Player'}
end
local groups = {}
for gName, gData in pairs(mist.DBs.groupsByName) do
local matched = 0
for cName, cVal in pairs(cEntry) do
if type(cVal) == 'table' then
for sName, sVal in pairs(cVal) do
if cName == 'skill' or cName == 'typeName' then
local lMatch = 0
for uId, uData in pairs(gData.units) do
if (uData[cName] and uData[cName] == sVal) or (gData[cName] and gData[cName] == sName) then
lMatch = lMatch + 1
break
end
end
if lMatch > 0 then
matched = matched + 1
end
end
if (gData[cName] and gData[cName] == sVal) or (gData[cName] and gData[cName] == sName) then
matched = matched + 1
break
end
end
else
if cName == 'skill' or cName == 'typeName' then
local lMatch = 0
for uId, uData in pairs(gData.units) do
if (uData[cName] and uData[cName] == sVal) then
lMatch = lMatch + 1
break
end
end
if lMatch > 0 then
matched = matched + 1
end
end
if gData[cName] and gData[cName] == cVal then
matched = matched + 1
end
end
end
if matched >= num then
if id then
groups[gData.groupid] = true
else
groups[gName] = true
end
end
end
local rtn = {}
for name, _ in pairs(groups) do
table.insert(rtn, name)
end
return rtn
end
function mist.getDeadMapObjsInZones(zone_names) function mist.getDeadMapObjsInZones(zone_names)
-- zone_names: table of zone names -- zone_names: table of zone names
-- returns: table of dead map objects (indexed numerically) -- returns: table of dead map objects (indexed numerically)
@ -3543,7 +3666,7 @@ do -- group functions scope
end end
function mist.teleportToPoint(vars) -- main teleport function that all of teleport/respawn functions call function mist.teleportToPoint(vars) -- main teleport function that all of teleport/respawn functions call
--log:info(vars) --log:warn(vars)
local point = vars.point local point = vars.point
local gpName local gpName
if vars.gpName then if vars.gpName then
@ -3607,7 +3730,7 @@ do -- group functions scope
local newCoord, origCoord local newCoord, origCoord
local validTerrain = {'LAND', 'ROAD', 'SHALLOW_WATER', 'WATER', 'RUNWAY'} local validTerrain = {'LAND', 'ROAD', 'SHALLOW_WATER', 'WATER', 'RUNWAY'}
if vars.anyTarrain then if vars.anyTerrain then
-- do nothing -- do nothing
elseif vars.validTerrain then elseif vars.validTerrain then
validTerrain = vars.validTerrain validTerrain = vars.validTerrain
@ -3638,7 +3761,7 @@ do -- group functions scope
---- old ---- old
for i = 1, 100 do for i = 1, 100 do
newCoord = mist.getRandPointInCircle(point, radius, innerRadius) newCoord = mist.getRandPointInCircle(point, radius, innerRadius)
if mist.isTerrainValid(newCoord, validTerrain) then if vars.anyTerrain or mist.isTerrainValid(newCoord, validTerrain) then
origCoord = mist.utils.deepCopy(newCoord) origCoord = mist.utils.deepCopy(newCoord)
diff = {x = (newCoord.x - newGroupData.units[1].x), y = (newCoord.y - newGroupData.units[1].y)} diff = {x = (newCoord.x - newGroupData.units[1].x), y = (newCoord.y - newGroupData.units[1].y)}
valid = true valid = true
@ -3724,19 +3847,21 @@ do -- group functions scope
tempRoute = mist.getGroupRoute(gpName, true) tempRoute = mist.getGroupRoute(gpName, true)
elseif vars.route then elseif vars.route then
-- log:warn('routeExist') -- log:warn('routeExist')
tempRoute = mist.utils.deepCopy(route) tempRoute = mist.utils.deepCopy(vars.route)
end end
-- log:warn(tempRoute) -- log:warn(tempRoute)
if tempRoute and (vars.offsetRoute or vars.offsetWP1 or vars.initTasks) then if tempRoute then
for i = 1, #tempRoute do if (vars.offsetRoute or vars.offsetWP1 or vars.initTasks) then
-- log:warn(i) for i = 1, #tempRoute do
if (vars.offsetRoute) or (i == 1 and vars.offsetWP1) or (i == 1 and vars.initTasks) then -- log:warn(i)
-- log:warn('update offset') if (vars.offsetRoute) or (i == 1 and vars.offsetWP1) or (i == 1 and vars.initTasks) then
tempRoute[i].x = tempRoute[i].x + diff.x -- log:warn('update offset')
tempRoute[i].y = tempRoute[i].y + diff.y tempRoute[i].x = tempRoute[i].x + diff.x
elseif vars.initTasks and i > 1 then tempRoute[i].y = tempRoute[i].y + diff.y
--log:warn('deleteWP') elseif vars.initTasks and i > 1 then
tempRoute[i] = nil --log:warn('deleteWP')
tempRoute[i] = nil
end
end end
end end
newGroupData.route = tempRoute newGroupData.route = tempRoute
@ -4065,13 +4190,19 @@ do -- group functions scope
return choices[rtnVal] return choices[rtnVal]
end end
function mist.stringCondense(s)
local exclude = {'%-', '%(', '%)', '%_', '%[', '%]', '%.', '%#', '% ', '%{', '%}', '%$', '%%', '%?', '%+', '%^'}
for i , str in pairs(exclude) do
s = string.gsub(s, str, '')
end
return s
end
function mist.stringMatch(s1, s2, bool) function mist.stringMatch(s1, s2, bool)
local exclude = {'%-', '%(', '%)', '%_', '%[', '%]', '%.', '%#', '% ', '%{', '%}', '%$', '%%', '%?', '%+', '%^'}
if type(s1) == 'string' and type(s2) == 'string' then if type(s1) == 'string' and type(s2) == 'string' then
for i , str in pairs(exclude) do s1 = mist.stringCondense(s1)
s1 = string.gsub(s1, str, '') s2 = mist.stringCondense(s2)
s2 = string.gsub(s2, str, '')
end
if not bool then if not bool then
s1 = string.lower(s1) s1 = string.lower(s1)
s2 = string.lower(s2) s2 = string.lower(s2)
@ -4893,6 +5024,25 @@ end
do -- mist.debug scope do -- mist.debug scope
mist.debug = {} mist.debug = {}
function mist.debug.changeSetting(s)
if type(s) == 'table' then
for sName, sVal in pairs(s) do
env.info(sName)
env.info(sVal)
if type(sVal) == 'string' or type(sVal) == 'number' then
if sName == 'log' then
mistSettings[sName] = sVal
log:setLevel(sVal)
elseif sName == 'dbLog' then
mistSettings[sName] = sVal
dblog:setLevel(sVal)
end
else
mistSettings[sName] = sVal
end
end
end
end
--- Dumps the global table _G. --- Dumps the global table _G.
-- This dumps the global table _G to a file in -- This dumps the global table _G to a file in
-- the DCS\Logs directory. -- the DCS\Logs directory.
@ -6543,6 +6693,7 @@ do -- mist.demos scope
end end
end end
do do
--[[ stuff for marker panels --[[ stuff for marker panels
marker.add() add marker. Point of these functions is to simplify process and to store all mark panels added. marker.add() add marker. Point of these functions is to simplify process and to store all mark panels added.
@ -6562,10 +6713,20 @@ do
If mark added to a group before a client joins slot is synced. If mark added to a group before a client joins slot is synced.
Mark made for cliet A in Slot A. Client A leaves, Client B joins in slot A. What do they see? Mark made for cliet A in Slot A. Client A leaves, Client B joins in slot A. What do they see?
May need to automate process... May need to automate process...
Could release this. But things I might need to add/change before doing so.
- removing marks and re-adding in same sequence doesn't appear to work. May need to schedule adding mark if updating an entry.
- I really dont like the old message style code for which groups get the message. Perhaps change to unitsTable and create function for getting humanUnitsTable.
= Event Handler, and check it, for marks added via script or user to deconflict Ids.
- Full validation of passed values for a specific shape type.
]] ]]
--[[
local usedMarks = {}
local typeBase = { local typeBase = {
['Mi-8MT'] = {'Mi-8MTV2', 'Mi-8MTV', 'Mi-8'}, ['Mi-8MT'] = {'Mi-8MTV2', 'Mi-8MTV', 'Mi-8'},
['MiG-21Bis'] = {'Mig-21'}, ['MiG-21Bis'] = {'Mig-21'},
@ -6576,14 +6737,56 @@ do
local mDefs = { local mDefs = {
coa = { coa = {
['red'] = {fillColor = {.8, 0 , 0, .5}, color = {.8, 0 , 0, .5}, lineType = 2}, ['red'] = {fillColor = {.8, 0 , 0, .5}, color = {.8, 0 , 0, .5}, lineType = 2, fontSize = 16},
['blue'] = {fillColor = {0, 0 , 0.8, .5}, color = {0, 0 , 0.8, .5}, lineType = 2}, ['blue'] = {fillColor = {0, 0 , 0.8, .5}, color = {0, 0 , 0.8, .5}, lineType = 2, fontSize = 16},
['all'] = {fillColor = {.1, .1 , .1, .5}, color = {.9, .9 , .9, .5}, lineType = 2, fontSize = 16},
['neutral'] = {fillColor = {.1, .1 , .1, .5}, color = {.2, .2 , .2, .5}, lineType = 2, fontSize = 16},
}, },
} }
local userDefs = {} local userDefs = {['red'] = {},['blue'] = {},['all'] = {},['neutral'] = {}}
local mId = 1337 local mId = 1000
local tNames = {'line', 'circle','rect', 'arrow', 'text', 'quad', 'freeform'}
local tLines = {[0] = 'no line', [1] = 'solid', [2] = 'dashed',[3] = 'dotted', [4] = 'dot dash' ,[5] = 'long dash', [6] = 'two dash'}
local coas = {[-1] = 'all', [0] = 'neutral', [1] = 'red', [2] = 'blue'}
local altNames = {['poly'] = 7, ['lines'] = 1, ['polygon'] = 7 }
local function draw(s)
--log:warn(s)
if type(s) == 'table' then
local mType = s.markType
if mType == 'panel' then
if markScope == 'coa' then
trigger.action.markToCoalition(s.markId, s.text, s.pos, s.markFor, s.readOnly)
elseif markScope == 'group' then
trigger.action.markToGroup(s.markId, s.text, s.pos, s.markFor, s.readOnly)
else
trigger.action.markToAll(s.markId, s.text, s.pos, s.readOnly)
end
elseif mType == 'line' then
trigger.action.lineToAll(s.coa, s.markId, s.pos[1], s.pos[2], s.color, s.fillColor, s.lineType, s.readOnly, s.message)
elseif mType == 'circle' then
trigger.action.circleToAll(s.coa, s.markId, s.pos[1], s.radius, s.color, s.fillColor, s.lineType, s.readOnly, s.message)
elseif mType == 'rect' then
trigger.action.rectToAll(s.coa, s.markId, s.pos[1], s.pos[2], s.color, s.fillColor, s.lineType, s.readOnly, s.message)
elseif mType == 'arrow' then
trigger.action.arrowToAll(s.coa, s.markId, s.pos[1], s.pos[2], s.color, s.fillColor, s.lineType, s.readOnly, s.message)
elseif mType == 'text' then
trigger.action.textToAll(s.coa, s.markId, s.pos[1], s.color, s.fillColor, fontSize, s.readOnly, s.text)
elseif mType == 'quad' then
trigger.action.quadToAll(s.coa, s.markId, s.pos[1], s.pos[2], s.pos[3], s.pos[4], s.color, s.fillColor, s.lineType, s.readOnly, s.message)
end
if s.name and not usedMarks[s.name] then
usedMarks[s.name] = s.markId
end
elseif type(s) == 'string' then
--log:warn(s)
mist.utils.dostring(s)
end
end
mist.marker = {} mist.marker = {}
mist.marker.list = {} mist.marker.list = {}
@ -6591,20 +6794,100 @@ do
for id, name in pairs(recList) do for id, name in pairs(recList) do
if name == spamBlockOn then if name == spamBlockOn then
log:info('already on recList') --log:info('already on recList')
return recList return recList
end end
end end
log:info('add to recList') --log:info('add to recList')
table.insert(recList, spamBlockOn) table.insert(recList, spamBlockOn)
return recList return recList
end end
local function iterate() local function iterate()
mId = mId + 1 while mId < 10000000 do
return mist.utils.deepCopy(mId) if usedMarks[mId] then
mId = mId + 1
else
return mist.utils.deepCopy(mId)
end
end
return mist.utils.deepCopy(mId)
end end
local function validateColor(val)
if type(val) == 'table' then
for i = 1, #val do
if type(val[i]) == 'number' and val[i] > 1 then
val[i] = val[i]/255 -- convert RGB values from 0-255 to 0-1 equivilent.
end
end
end
return val
end
local function checkDefs(vName, coa)
--log:warn('CheckDefs: $1 $2', vName, coa)
local coaName
if type(coa) == 'number' then
if coas[coa] then
coaName = coas[coa]
end
elseif type(coa) == 'string' then
coaName = coa
end
-- log:warn(coaName)
if userDefs[coaName] and userDefs[coaName][vName] then
return userDefs[coaName][vName]
elseif mDefs.coa[coaName] and mDefs.coa[coaName][vName] then
return mDefs.coa[coaName][vName]
end
end
function mist.marker.getNextId()
return iterate()
end
local handle = {}
function handle:onEvent(e)
if world.event.S_EVENT_MARK_ADDED == e.id and e.idx then
usedMarks[e.idx] = e.idx
if not mist.marker.list[e.idx] then
--log:info('create maker DB: $1', e.idx)
mist.marker.list[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
mist.marker.list[e.idx].unit = e.initiaor:getName()
end
--log:info(mist.marker.list[e.idx])
end
elseif world.event.S_EVENT_MARK_CHANGE == e.id and e.idx then
if mist.marker.list[e.idx] then
mist.marker.list[e.idx].text = e.text
end
elseif world.event.S_EVENT_MARK_REMOVE == e.id and e.idx then
if mist.marker.list[e.idx] then
mist.marker.list[e.idx] = nil
end
end
end
local function removeMark(id)
--log:info("Removing Mark: $1", id)
if type(id) == 'table' then
for ind, val in pairs(id) do
trigger.action.removeMark(val)
mist.marker.list[val] = nil
end
else
trigger.action.removeMark(id)
mist.marker.list[id] = nil
end
end
world.addEventHandler(handle)
function mist.marker.setDefault(vars) function mist.marker.setDefault(vars)
if vars and type(vars) == 'table' then if vars and type(vars) == 'table' then
for l1, l1Data in pairs(vars) do for l1, l1Data in pairs(vars) do
@ -6625,37 +6908,116 @@ do
end end
function mist.marker.add(vars) function mist.marker.add(vars)
log:warn('markerFunc') --log:warn('markerFunc')
log:info(vars) --log:warn(vars)
local pos = vars.point or vars.points or vars.pos local pos = vars.point or vars.points or vars.pos
local text = vars.text local text = vars.text or ''
local markFor = vars.markFor local markFor = vars.markFor
local id = vars.id local markForCoa = vars.markForCoa -- optional, can be used if you just want to mark to a specific coa/all
local mType = vars.mType local id = vars.id or vars.markId or vars.markid
local mType = vars.mType or 0
local color = vars.color local color = vars.color
local fillColor = vars.fillColor local fillColor = vars.fillColor
local lineType = vars.lineType local lineType = vars.lineType or 2
local readOnly = vars.readOnly local readOnly = vars.readOnly or true
local displayMessage= vars.displayMessage local message = vars.message
local fontSize = vars.fontSize
local name = vars.name
local radius = vars.radius or 500
local coa = -1
local usedId = 0
if not id then
else if id then
if type(id) ~= 'number' then
name = id
usedId = iterate()
end
--log:info('checkIfIdExist: $1', id)
--[[
Maybe it should treat id or name as the same thing/single value.
If passed number it will use that as the first Id used and will delete/update any marks associated with that same value.
]]
local lId = id or name
if mist.marker.list[id] then ---------- NEED A BETTER WAY TO ASSOCIATE THE ID VALUE. CUrrnetly deleting from table and checking if that deleted entry exists which it wont.
--log:warn('active mark to be removed: $1', id)
name = mist.marker.list[id].name or id
removeMark(id)
elseif usedMarks[id] then
--log:info('exists in usedMarks: $1', id)
removeMark(usedMarks[id])
elseif name and usedMarks[name] then
--log:info('exists in usedMarks: $1', name)
removeMark(usedMarks[name])
end
usedId = iterate()
usedMarks[id] = usedId -- redefine the value used
end end
if name then
if usedId == 0 then
usedId = iterate()
end
usedMarks[name] = usedId
end
if mType then
if type(mType) == 'string' then
for i = 1, #tNames do
--log:warn(tNames[i])
if mist.stringMatch(mType, tNames[i]) then
mType = i
break
end
end
elseif type(mType) == 'number' and mType > #tNames then
mType = 0
end
end
--log:warn(mType)
local markScope = 'all' local markScope = 'all'
local markForTable = {} local markForTable = {}
if pos then
pos = mist.utils.makeVec3(pos) if pos then
if pos[1] then
for i = 1, #pos do
pos[i] = mist.utils.makeVec3(pos[i])
end
else
pos[1] = mist.utils.makeVec3(pos)
end
end end
if text and type(text) ~= string then if text and type(text) ~= string then
text = tostring(text) text = tostring(text)
else
text = ''
end end
if markFor then if markForCoa then
if type(markForCoa) == 'string' then
if tonumber(markForCoa) then
coa = coas[tonumber(markForCoa)]
markScope = 'coa'
else
for ind, cName in pairs(coas) do
if mist.stringMatch(cName, markForCoa) then
coa = ind
markScope = 'coa'
break
end
end
end
end
elseif markFor then
if type(markFor) == 'number' then -- groupId if type(markFor) == 'number' then -- groupId
if mist.DBs.groupsById[markFor] then if mist.DBs.groupsById[markFor] then
markScope = 'group' markScope = 'group'
@ -6667,12 +7029,10 @@ do
end end
elseif type(markFor) == 'table' then -- multiple groupName, country, coalition, all elseif type(markFor) == 'table' then -- multiple groupName, country, coalition, all
markScope = 'table' markScope = 'table'
log:info(markFor) --log:warn(markFor)
for forIndex, forData in pairs(markFor) do -- need to rethink this part and organization. Gotta be a more logical way to send messages to coa, groups, or all. for forIndex, forData in pairs(markFor) do -- need to rethink this part and organization. Gotta be a more logical way to send messages to coa, groups, or all.
log:info(forIndex)
log:info(forData)
for list, listData in pairs(forData) do for list, listData in pairs(forData) do
log:info(listData) --log:warn(listData)
forIndex = string.lower(forIndex) forIndex = string.lower(forIndex)
if type(listData) == 'string' then if type(listData) == 'string' then
listData = string.lower(listData) listData = string.lower(listData)
@ -6681,18 +7041,29 @@ do
markScope = 'all' markScope = 'all'
break break
elseif (forIndex == 'coa' or forIndex == 'ca') then -- mark for coa or CA. elseif (forIndex == 'coa' or forIndex == 'ca') then -- mark for coa or CA.
for name, index in pairs (coalition.side) do local matches = 0
for name, index in pairs (coalition.side) do
if listData == string.lower(name) then if listData == string.lower(name) then
markScope = 'coalition' markScope = 'coa'
markFor = index
coa = index
matches = matches + 1
end end
end end
elseif (forIndex == 'countries' and string.lower(clientData.country) == listData) or (forIndex == 'units' and string.lower(clientData.unitName) == listData) then if matches > 1 then
markForTable = markSpamFilter(markForTable, clientData.groupId) markScope = 'all'
end
elseif forIndex == 'countries' then
for clienId, clientData in pairs(mist.DBs.humansById) do
if (string.lower(clientData.country) == listData) or (forIndex == 'units' and string.lower(clientData.unitName) == listData) then
markForTable = markSpamFilter(markForTable, clientData.groupId)
end
end
elseif forIndex == 'unittypes' then -- mark to group elseif forIndex == 'unittypes' then -- mark to group
-- iterate play units -- iterate play units
for clientId, clientData in pairs(mist.DBs.humansById) do for clientId, clientData in pairs(mist.DBs.humansById) do
for typeId, typeData in pairs(listData) do for typeId, typeData in pairs(listData) do
log:info(typeData) --log:warn(typeData)
local found = false local found = false
if list == 'all' or clientData.coalition and type(clientData.coalition) == 'string' and mist.stringMatch(clientData.coalition, list) then if list == 'all' or clientData.coalition and type(clientData.coalition) == 'string' and mist.stringMatch(clientData.coalition, list) then
if mist.matchString(typeData, clientData.type) then if mist.matchString(typeData, clientData.type) then
@ -6738,58 +7109,141 @@ do
markScope = 'all' markScope = 'all'
end end
if mType == 0 then
local data = {markId = usedId, text = text, pos = pos[1], markScope = markScope, markFor = markFor, markType = 'panel', name = name, time = timer.getTime()}
if markScope ~= 'table' then
-- create marks
mist.marker.list[usedId] = data-- add to the DB
else
if #markForTable > 0 then
--log:info('iterate')
local list = {}
if id and not name then
name = id
end
for i = 1, #markForTable do
local newId = iterate()
local data = {markId = newId, text = text, pos = pos[i], markFor = markForTable[i], markType = 'panel', name = name, readOnly = readOnly, time = timer.getTime()}
mist.marker.list[newId] = data
table.insert(list, data)
draw(data)
end
return list
end
end
draw(data)
return data
elseif mType > 0 then
local newId = iterate()
local fCal = {}
fCal[#fCal+1] = mType
fCal[#fCal+1] = coa
fCal[#fCal+1] = usedId
for i = 1, #pos do
fCal[#fCal+1] = pos[i]
end
if radius and mType == 2 then
fCal[#fCal+1] = radius
end
if not color then
color = checkDefs('color', coa)
else
color = validateColor(color)
end
fCal[#fCal+1] = color
if not fillColor then
fillColor = checkDefs('fillColor', coa)
else
fillColor = validateColor(fillColor)
end
fCal[#fCal+1] = fillColor
if mType == 5 then -- text to all
if not fontSize then
fontSize = checkDefs('fondSize', coa) or 16
end
fCal[#fCal+1] = fontSize
else
if not lineType then
lineType = checkDefs('lineType', coa) or 2
end
end
fCal[#fCal+1] = lineType
if not readOnly then
readOnly = true
end
fCal[#fCal+1] = readOnly
fCal[#fCal+1] = message
local data = {coa = coa, markId = usedId, pos = pos, markFor = markFor, color = color, readOnly = readOnly, message = message, fillColor = fillColor, lineType = lineType, markType = tNames[mType], name = name, radius = radius, text = text, fontSize = fontSize, time = timer.getTime()}
mist.marker.list[usedId] = data
if markScope ~= 'table' then if mType == 7 or mType == 1 then
local newId = iterate() local s = "trigger.action.markupToAll("
local data = {markId = newId, text = text, pos = pos, markScope = markScope, markFor = markFor}
-- create marks for i = 1, #fCal do
if markScope == 'coa' then --log:warn(fCal[i])
trigger.action.markToCoalition(newId, text, pos, markFor) if type(fCal[i]) == 'table' or type(fCal[i]) == 'boolean' then
elseif markScope == 'group' then s = s .. mist.utils.oneLineSerialize(fCal[i])
trigger.action.markToGroup(newId, text, pos, markFor) else
else s = s .. fCal[i]
trigger.action.markToAll(iterate(), text, pos) end
end if i < #fCal then
table.insert(mist.marker.list, data) -- add to the DB s = s .. ','
else end
if #markForTable > 0 then end
log:info('iterate')
for i = 1, #markForTable do
local newId = iterate()
local data = {markId = newId, text = text, pos = pos, markFor = markFor}
log:info(data)
table.insert(mist.marker.list, data)
trigger.action.markToGroup(newId, text, pos, markForTable[i])
end
end
end
s = s .. ')'
if name then
usedMarks[name] = usedId
end
draw(s)
else
draw(data)
end
return data
end
end end
function mist.marker.remove(id) function mist.marker.remove(id)
for i, data in pairs(mist.marker.list) do removeMark(id)
if id == data.markId then
trigger.action.removeMark(id)
end
end
end end
function mist.marker.get(id) function mist.marker.get(id)
if mist.marker.lis[id] then
return mist.marker.lis[id]
end
local names = {}
for markId, data in pairs(mist.marker.list) do
if data.name and data.name == id then
table.insert(names, data)
end
end
if #names > 0 then
return names
end
end end
function mist.marker.coords(pos, cType, markFor, id) -- wrapper function to just display coordinates of a specific format at location --function mist.marker.coords(pos, cType, markFor, id) -- wrapper function to just display coordinates of a specific format at location
end --end
]]
end end
--- Time conversion functions. --- Time conversion functions.
-- @section mist.time -- @section mist.time
@ -7790,7 +8244,8 @@ do -- mist.Logger scope
-- @usage -- log everything -- @usage -- log everything
--myLogger:setLevel(3) --myLogger:setLevel(3)
function mist.Logger:setLevel(level) function mist.Logger:setLevel(level)
if not level then env.info('set Level ' .. level)
if not level then
self.level = 2 self.level = 2
else else
if type(level) == 'string' then if type(level) == 'string' then