trainingSpawnZone = {} --- Identifier. All output in the log will start with this. trainingSpawnZone.Id = "TRAININGZONE - " --- Version. trainingSpawnZone.Version = "1.1.0" -- trace level, specific to this module trainingSpawnZone.Trace = false trainingSpawnZone.Debug = false trainingSpawnZone.MESSAGE_REGISTERED = "Zone [%s] has been registered" trainingSpawnZone.MESSAGE_ACTIVATED = "Zone [%s] has been activated" trainingSpawnZone.MESSAGE_DEACTIVATED = "Zone [%s] has been deactivated" trainingSpawnZone.MESSAGE_DURATION = 10 trainingSpawnZone.CHECK_FREQUENCY = 5 trainingSpawnZone.zones = {} function trainingSpawnZone.logError(message) env.error(trainingSpawnZone.Id, message) end function trainingSpawnZone.logWarning(message) env.warning(trainingSpawnZone.Id, message) end function trainingSpawnZone.logInfo(message) env.info(trainingSpawnZone.Id .."I - " .. message) end function trainingSpawnZone.logDebug(message) if message and trainingSpawnZone.Debug then env.info(trainingSpawnZone.Id .."D - " .. message) end end function trainingSpawnZone.logTrace(message) if message and trainingSpawnZone.Trace then env.info(trainingSpawnZone.Id .."T - " .. message) end end function trainingSpawnZone.p(o, level) local MAX_LEVEL = 20 if level == nil then level = 0 end if level > MAX_LEVEL then veafServerHook.logError("max depth reached in p : "..tostring(MAX_LEVEL)) return "" end local text = "" if (type(o) == "table") then text = "\n" for key,value in pairs(o) do for i=0, level do text = text .. " " end text = text .. ".".. key.."="..trainingSpawnZone.p(value, level+1) .. "\n"; end elseif (type(o) == "function") then text = "[function]"; elseif (type(o) == "boolean") then if o == true then text = "[true]"; else text = "[false]"; end else if o == nil then text = "[nil]"; else text = tostring(o); end end return text end function trainingSpawnZone.registerZone(zoneName, friendlies, ennemies, message) trainingSpawnZone.logDebug(string.format("trainingSpawnZone.registerZone([%s])", trainingSpawnZone.p(zoneName))) trainingSpawnZone.logDebug(string.format("friendlies = %s", trainingSpawnZone.p(friendlies))) trainingSpawnZone.logDebug(string.format("ennemies = %s", trainingSpawnZone.p(ennemies))) trainingSpawnZone.logTrace(string.format("message = %s", trainingSpawnZone.p(message))) if not zoneName or not friendlies or #friendlies < 1 or not ennemies or #ennemies < 1 then return false end local _zoneName = zoneName:lower() trainingSpawnZone.zones[_zoneName] = {} trainingSpawnZone.zones[_zoneName].name = zoneName trainingSpawnZone.zones[_zoneName].message = message trainingSpawnZone.zones[_zoneName].friendlies = friendlies trainingSpawnZone.zones[_zoneName].ennemies = ennemies trainingSpawnZone.zones[_zoneName].active = false if message then trigger.action.outText(string.format(trainingSpawnZone.MESSAGE_REGISTERED, zoneName), trainingSpawnZone.MESSAGE_DURATION) end trainingSpawnZone.logDebug(string.format("zone [%s] registered", trainingSpawnZone.p(zoneName))) end function trainingSpawnZone.activateZone(zoneName) trainingSpawnZone.logDebug(string.format("trainingSpawnZone.activateZone([%s])", trainingSpawnZone.p(zoneName))) if not zoneName then return false end local _zone = trainingSpawnZone.zones[zoneName:lower()] if not _zone.active then for _, groupName in pairs(_zone.ennemies) do mist.respawnGroup(groupName, true) end if _zone.message then trigger.action.outText(string.format(trainingSpawnZone.MESSAGE_ACTIVATED, zoneName), trainingSpawnZone.MESSAGE_DURATION) end _zone.active = true trainingSpawnZone.logDebug(string.format("zone [%s] activated", trainingSpawnZone.p(zoneName))) else trainingSpawnZone.logWarning(string.format("zone [%s] was already active", trainingSpawnZone.p(zoneName))) end end function trainingSpawnZone.deactivateZone(zoneName) trainingSpawnZone.logDebug(string.format("trainingSpawnZone.deactivateZone([%s])", trainingSpawnZone.p(zoneName))) if not zoneName then return false end local _zone = trainingSpawnZone.zones[zoneName:lower()] if _zone.active then for _, groupName in pairs(_zone.ennemies) do local _group = Group.getByName(groupName) if _group then _group:destroy() end end if _zone.message then trigger.action.outText(string.format(trainingSpawnZone.MESSAGE_DEACTIVATED, zoneName), trainingSpawnZone.MESSAGE_DURATION) end _zone.active = false trainingSpawnZone.logDebug(string.format("zone [%s] deactivated", trainingSpawnZone.p(zoneName))) else trainingSpawnZone.logWarning(string.format("zone [%s] was not active", trainingSpawnZone.p(zoneName))) end end function trainingSpawnZone.checkZone(zoneName) trainingSpawnZone.logTrace(string.format("trainingSpawnZone.checkZone([%s])", trainingSpawnZone.p(zoneName))) local function countUnitsInGroups(groupsNames) local _result = 0 for _, groupName in pairs(groupsNames) do local _group = Group.getByName(groupName) if _group then for _, unit in pairs(_group:getUnits()) do if (unit:isExist() and unit:isActive() and unit:getLife() > 0.01) then _result = _result + 1 end end end end return _result end if zoneName then local _zone = trainingSpawnZone.zones[zoneName:lower()] if _zone then if _zone.active then -- check if friendlies or ennemies have been destroyed local _remainingFriendlies = countUnitsInGroups(_zone.friendlies) trainingSpawnZone.logTrace(string.format("_remainingFriendlies = %s", trainingSpawnZone.p(_remainingFriendlies))) local _remainingEnnemies = countUnitsInGroups(_zone.ennemies) trainingSpawnZone.logTrace(string.format("_remainingEnnemies = %s", trainingSpawnZone.p(_remainingEnnemies))) if _remainingEnnemies == 0 or _remainingFriendlies == 0 then trainingSpawnZone.deactivateZone(zoneName) end else -- check for friendlies in zone local _groupsNamesForMist = {} for _, groupName in pairs(_zone.friendlies) do table.insert(_groupsNamesForMist, "[g]"..groupName) end trainingSpawnZone.logTrace(string.format("_groupsNamesForMist = %s", trainingSpawnZone.p(_groupsNamesForMist))) local _units = mist.makeUnitTable(_groupsNamesForMist) trainingSpawnZone.logTrace(string.format("_units = %s", trainingSpawnZone.p(_units))) local _unitsInZone = mist.getUnitsInZones(_units, {zoneName}, 'cylinder') trainingSpawnZone.logTrace(string.format("_unitsInZone = %s", trainingSpawnZone.p(_unitsInZone))) local _friendliesInZone = (#_unitsInZone > 0) if _friendliesInZone then trainingSpawnZone.activateZone(zoneName) end end end end mist.scheduleFunction(trainingSpawnZone.checkZone, { zoneName }, timer.getTime() + trainingSpawnZone.CHECK_FREQUENCY) end function trainingSpawnZone.start() trainingSpawnZone.logTrace(string.format("trainingSpawnZone.start()")) local _separation = 0 for _, zone in pairs(trainingSpawnZone.zones) do _separation = _separation + 0.3 trainingSpawnZone.logDebug(string.format("scheduling call to trainingSpawnZone.checkZone([%s])", trainingSpawnZone.p(zone.name))) mist.scheduleFunction(trainingSpawnZone.checkZone, { zone.name }, timer.getTime() + _separation) end end