------------------------------------------------------------------ -- VEAF markers function library for DCS World -- By zip (2018) -- -- Features: -- --------- -- * Listen to marker events and execute event handlers. -- -- See the documentation : https://veaf.github.io/documentation/ ------------------------------------------------------------------ veafMarkers = {} ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Global settings. Stores the script constants ------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Identifier. All output in DCS.log will start with this. veafMarkers.Id = "MARKERS" --- Version. veafMarkers.Version = "1.1.0" --- DCS bug regarding wrong marker vector components was fixed. If so, set to true! veafMarkers.DCSbugfixed = true -- trace level, specific to this module --veafMarkers.LogLevel = "trace" veaf.loggers.new(veafMarkers.Id, veafMarkers.LogLevel) veafMarkers.MarkerAdd = 1 veafMarkers.MarkerChange = 2 veafMarkers.MarkerRemove = 3 ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Do not change anything below unless you know what you are doing! ------------------------------------------------------------------------------------------------------------------------------------------------------------- veafMarkers.eventHandlerId = 0 veafMarkers.onEventMarkChangeEventHandlers = {} veafMarkers.onEventMarkAddEventHandlers = {} veafMarkers.onEventMarkRemoveEventHandlers = {} ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Utility methods ------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Event handler. ------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Event handler. veafMarkers.eventHandler = {} --- Handle world events. function veafMarkers.eventHandler:onEvent(Event) -- Only interested in S_EVENT_MARK_* if Event == nil or Event.idx == nil then return true end -- Debug output. if Event.id == world.event.S_EVENT_MARK_ADDED then veaf.loggers.get(veafMarkers.Id):debug("S_EVENT_MARK_ADDED") elseif Event.id == world.event.S_EVENT_MARK_CHANGE then veaf.loggers.get(veafMarkers.Id):debug("S_EVENT_MARK_CHANGE") elseif Event.id == world.event.S_EVENT_MARK_REMOVED then veaf.loggers.get(veafMarkers.Id):debug("S_EVENT_MARK_REMOVED") end veaf.loggers.get(veafMarkers.Id):trace(string.format("Event id = %s", tostring(Event.id))) veaf.loggers.get(veafMarkers.Id):trace(string.format("Event time = %s", tostring(Event.time))) veaf.loggers.get(veafMarkers.Id):trace(string.format("Event idx = %s", tostring(Event.idx))) veaf.loggers.get(veafMarkers.Id):trace(string.format("Event coalition = %s", tostring(Event.coalition))) veaf.loggers.get(veafMarkers.Id):trace(string.format("Event group id = %s", tostring(Event.groupID))) veaf.loggers.get(veafMarkers.Id):trace(string.format("Event pos X = %s", tostring(Event.pos.x))) veaf.loggers.get(veafMarkers.Id):trace(string.format("Event pos Y = %s", tostring(Event.pos.y))) veaf.loggers.get(veafMarkers.Id):trace(string.format("Event pos Z = %s", tostring(Event.pos.z))) if Event.initiator ~= nil and Event.initiator.getName then local _unitname = Event.initiator:getName() veaf.loggers.get(veafMarkers.Id):trace(string.format("Event ini unit = %s", tostring(_unitname))) end veaf.loggers.get(veafMarkers.Id):trace(string.format("Event text = \n%s", tostring(Event.text))) -- Call event function when a marker has changed, i.e. text was entered or changed. if Event.id == world.event.S_EVENT_MARK_CHANGE then veafMarkers.onEvent(Event, veafMarkers.onEventMarkChangeEventHandlers) elseif Event.id == world.event.S_EVENT_MARK_ADDED then veafMarkers.onEvent(Event, veafMarkers.onEventMarkAddEventHandlers) elseif Event.id == world.event.S_EVENT_MARK_REMOVED then veafMarkers.onEvent(Event, veafMarkers.onEventMarkRemoveEventHandlers) end end ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- Event handler functions. ------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Function executed when a marker event occurs. function veafMarkers.onEvent(event, eventHandlersTable) local vec3 = nil -- Check if marker has a text and the veafMarkers.keyphrase keyphrase. if event.text ~= nil then -- browse all the event handlers registered for this type of event for i = 1, #eventHandlersTable do -- compute the event position if not already done if vec3 == nil then if veafMarkers.DCSbugfixed then vec3 = {x = event.pos.x, y = event.pos.y, z = event.pos.z} else -- Convert (wrong x-->z, z-->x) vec3 vec3 = {x = event.pos.z, y = event.pos.y, z = event.pos.x} end -- By default, alt of mark point is always 5 m! Adjust for the correct ASL height. vec3.y = veaf.getLandHeight(vec3) end -- call the event handler local eventHandler = eventHandlersTable[i] veaf.loggers.get(veafMarkers.Id):debug("Calling eventHandler #" .. eventHandler.id) local err, errmsg = pcall(eventHandler.f, vec3, event) if not err then veaf.loggers.get(veafMarkers.Id):error('Error in event handler #' .. eventHandler.id .. ' : '.. errmsg) end veaf.loggers.get(veafMarkers.Id):debug("Returning after eventHandler #" .. eventHandler.id) end end end --- Register an event handler -- @tparam function f event handling function (the first parameter is always the event position, and the second is the event) -- @treturn number event handler id. function veafMarkers.registerEventHandler(eventType, eventHandler) --verify correct types assert(type(eventHandler) == 'function', 'variable 1, expected function, got ' .. type(eventHandler)) if not vars then vars = {} end veafMarkers.eventHandlerId = veafMarkers.eventHandlerId + 1 if eventType == veafMarkers.MarkerAdd then table.insert(veafMarkers.onEventMarkAddEventHandlers, {f = eventHandler, id = veafMarkers.eventHandlerId}) elseif eventType == veafMarkers.MarkerChange then table.insert(veafMarkers.onEventMarkChangeEventHandlers, {f = eventHandler, id = veafMarkers.eventHandlerId}) elseif eventType == veafMarkers.MarkerRemove then table.insert(veafMarkers.onEventMarkRemoveEventHandlers, {f = eventHandler, id = veafMarkers.eventHandlerId}) else -- wrong event type end return veafMarkers.eventHandlerId end function veafMarkers.removeItemFromList(list, id) local i = 1 while i <= #list do if list[i].id == id then table.remove(list, i) return true else i = i + 1 end end return false end --- Removes an event handler -- @tparam number id event handler id -- @treturn boolean true if event handler was successfully removed, false otherwise. function veafMarkers.unregisterEventHandler(id) local result = veafMarkers.removeItemFromList(veafMarkers.onEventMarkAddEventHandlers, id) if not(result) then result = veafMarkers.removeItemFromList(veafMarkers.onEventMarkChangeEventHandlers, id) end if not(result) then result = veafMarkers.removeItemFromList(veafMarkers.onEventMarkRemoveEventHandlers, id) end return result end ------------------------------------------------------------------------------------------------------------------------------------------------------------- -- initialisation ------------------------------------------------------------------------------------------------------------------------------------------------------------- --- Add event handler. world.addEventHandler(veafMarkers.eventHandler) --- Enable/Disable error boxes displayed on screen. env.setErrorMessageBoxEnabled(false) veaf.loggers.get(veafMarkers.Id):info(string.format("Loading version %s", veafMarkers.Version))