----------------------------------------------------------------------------------------------------------------------------------------------------------- -- __ __ ___ _ __ __ -- / //_/ / | __________(_)____/ /_____ _____ / /_ -- / ,< ______/ /| | / ___/ ___/ / ___/ __/ __ `/ __ \/ __/ -- / /| /_____/ ___ |(__ |__ ) (__ ) /_/ /_/ / / / / /_ --/_/ |_| /_/ |_/____/____/_/____/\__/\__,_/_/ /_/\__/ -- _____ __ ___ -- / ___/____ ____ __ ______ / |/ /___ _____ ____ _____ ____ _____ -- \__ \/ __ \/ __ `/ | /| / / __ \ / /|_/ / __ `/ __ \/ __ `/ __ `/ _ \/ ___/ -- ___/ / /_/ / /_/ /| |/ |/ / / / / / / / / /_/ / / / / /_/ / /_/ / __/ / --/____/ .___/\__,_/ |__/|__/_/ /_/ /_/ /_/\__,_/_/ /_/\__,_/\__, /\___/_/ -- /_/ /____/ ----------------------------------------------------------------------------------------------------------------------------------------------------------- -- v 2.2.2 ----------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------- -- DEV NOTES ----------------------------------------------------------------------------------------------------------------------------------------------------------- -- RREWORKS AND UPGRADES -- -- NEW FEATURES -- DONE - :InitRandomizeUnits opzionale per SPAWN SCHEDULED in v2.2.2 -- -- FIXES -- -- ************************************************************************ -- ********************* USER CONFIGURATION ***************************** -- ************************************************************************ --------------------------------------------------------------------------- ------------------------------- OPTIONS ----------------------------------- -- sm_Settings table allows you to enable/disable Spawn Managers functions -- and configure parameters and options --------------------------------------------------------------------------- sm_Settings = { ------------------------------------------------------------------------------------------------------------------------------------------------------ WecomeMessage = true, -- displays "K-Assistant: Spawn Manager - Loaded!" message at mission start for 3 seconds ------------------------------------------------------------------------------------------------------------------------------------------------------ SpawnManagerMenuName = "K-Ass Spawn Manager", -- define main menu Name ------------------------------------------------------------------------------------------------------------------------------------------------------ SimpleSpawn = { Enable = true, -- enable/disable SimpleSpawn - Spawn a group where planned by ME MenuName = "Simple Spawn", -- define dedicated menu Name Categories = true -- if true, radio menus will be generated for each spawnable group category (Airplanes, Helicopters, Ground, Ships) }, -- end of SimpleSpawn ------------------------------------------------------------------------------------------------------------------------------------------------------ ServiceSpawn = { Enable = true, -- enable/disable ServiceSpawn - Spawn a group where planned by ME - limited to only one group at a time, new spawned groups replace the previous one MenuName = "Service Spawn", -- define dedicated menu Name Categories = false -- if true, radio menus will be generated for each spawnable group category (Airplanes, Helicopters, Ground, Ships) }, -- end of ServiceSpawn ------------------------------------------------------------------------------------------------------------------------------------------------------ SpawnInZone = { Enable = true , -- enable/disable SpawnInZone - Spawn a group in a defined zone MenuName = "Spawn in Zone", -- define dedicated menu Name Categories = false, -- if true, radio menus will be generated for each spawnable group category (Airplanes, Helicopters, Ground, Ships) MarkSpawnZonesOnMap = true, -- if true Spawn Zones will be marked on F10 map RandomizeUnitsPosition = true, -- Randomizes the UNITs postitions that are spawned within a radius band RandomizeUnitsRadius = 250, -- The outer radius in meters where the units will be spawned. }, -- end of SpawnInZone ------------------------------------------------------------------------------------------------------------------------------------------------------ SpawnInRandomZone = { Enable = true, -- enable/disable SpawnInRandomZone - Spawn a group in a random zone defined by ME MenuName = "Spawn in Random Zone", -- define dedicated menu Name Categories = false, -- if true, radio menus will be generated for each spawnable group category (Airplanes, Helicopters, Ground, Ships) RandomizeUnitsPosition = true, -- Randomizes the UNITs postitions that are spawned within a radius band RandomizeUnitsRadius = 250, -- The outer radius in meters where the units will be spawned. }, -- end of SpawnInRandomZone ------------------------------------------------------------------------------------------------------------------------------------------------------ SearchAndDestroy = { Enable = true, -- enable/disable SearchAndDestroy - Spawn a group with random path in a random zone MenuName = "Search & Destroy", -- define dedicated menu Name RandomizeRoute = 25000, -- Ground Groups - radius within which the Waypoints from the first to the penultimate will be randomized AirRandomizeRoute = 30000, -- Airplanes Groups - radius within which the Waypoints from the first to the penultimate will be randomized HeliRandomizeRoute = 20000, -- Helicopters Groups - radius within which the Waypoints from the first to the penultimate will be randomized SuppressionTakeCover = true, -- if enabled, spawned ground units will take cover near map objects when attacked TakecoverWait = 320, -- Time in seconds that units will remain in coverage TakecoverRange = 700 -- Range in meters within which units will seek cover }, -- end of SearchAndDestroy ------------------------------------------------------------------------------------------------------------------------------------------------------ SpawnAtMark = { Enable = true, -- enable/disable SpawnAtMark (spawn un F10 map marks) MenuName = "Spawn at Mark", -- define dedicated menu Name Categories = true, -- if true, radio menus will be generated for each spawnable group category (Airplanes, Helicopters, Ground, Ships) OwnSpawnGroups = true, -- if true, the Spawn At Mark function will have its own spawnable groups, distinct from common spawnables. If false, Spawn at Mark will attach spawnable groups from common spawnables RandomizeUnitsPosition = false, -- Randomizes the UNITs postitions that are spawned within a radius band RandomizeUnitsRadius = 250, -- The outer radius in meters where the units will be spawned. }, -- end of SpawnAtMark ------------------------------------------------------------------------------------------------------------------------------------------------------ ScheduledSpawn = { Enable = true, -- enable/disable ScheduledSpawn - these groups will be spawned endlessly RandomizeUnitsPosition = true, -- Randomizes the UNITs postitions that are spawned within a radius band }, -- end of ScheduledSpawn ------------------------------------------------------------------------------------------------------------------------------------------------------ -- JtacSpawnAtMark = { Enable = false }, -- enable/disable JtacSpawnAtMark mappa F10 -- NOT USED -- NOT IN DEVELOP ------------------------------------------------------------------------------------------------------------------------------------------------------ DeleteSpawned = { Enable = true -- enable/disable Delete Spawned functions and Menus }, -- end of DeleteSpawned ------------------------------------------------------------------------------------------------------------------------------------------------------ ServerCleaner = { Enable = false, -- enable/disable Server Cleaner that will destroy all spawned groups if no active clients ScanTimer = 60, -- client scan interval - in minutes - if scan detects no clients connected then cleanup will be executed } -- end of ServerCleaner ------------------------------------------------------------------------------------------------------------------------------------------------------ } -- END OF sm_Settings -- ************************************************************************ -- ********************* END OF USER CONFIGURATION ********************** -- ********************* DO NOT EDIT BELOW THIS LINE ********************** -- ************************************************************************ --------------------------------------------------------------------------- -------------------------------- TAGS ------------------------------------- --------------------------------------------------------------------------- -- tags are used to identify groups and zones in order to associate theme to Spawn Manager Functions -- % are used to escape square brackets [] sm_Tags = { BLUE = { SimpleSpawn = "%[B_SS%]", ServiceSpawn = "%[B_SRV%]", SpawnAtMark = "%[B_SAM%]", Spawnable = "%[B_SPA%]", SearchAndDestroy = "%[B_SAD%]" , BaseSearchAndDestroy = "%[B_BC%]", Zones = { SpawnZone = "%[B_SPZ%]", RandomSpawnZone = "%[B_RSZ%]", RandomSearchAndDestroyZone = "%[B_SADZ%]" } -- end of BLUE }, RED = { SimpleSpawn = "%[R_SS%]", ServiceSpawn = "%[R_SRV%]", SpawnAtMark = "%[R_SAM%]", Spawnable = "%[R_SPA%]", SearchAndDestroy = "%[R_SAD%]" , BaseSearchAndDestroy = "%[R_BC%]", Zones = { SpawnZone = "%[R_SPZ%]", RandomSpawnZone = "%[R_RSZ%]", RandomSearchAndDestroyZone = "%[R_SADZ%]" } -- end of RED }, GENERIC = { ScheduledSpawn = "%[SCHED%]" }, MARK = "#SPW", -- define Mark Text to identify markers where to spawn. -- MARKJTAC = "#JTAC" -- definisce il tag per i mark point su cui far spawnare JTAC - non modificare se non sai esattamente cosa stai facendo. } -- end of sm_Tags ------------------------------------------------------------------------------------------------------------------------------------------------------ env.info("* * * K-ASSISTANT: SPAWN MANAGER START * * *",false) -- check if MOOSE il loaded if BASE == nil then env.error("MOOSE Framework not found! You must load MOOSE before K-Assistant!", true) end -- ************************************************************************ -- ****************************** DATA ********************************* -- ************************************************************************ sm_Menus = { BLUE = { SpawnManager = MENU_COALITION:New( coalition.side.BLUE, sm_Settings.SpawnManagerMenuName ), -- create Spawn Manager main menu SimpleSpawn = { main = nil, pages = {}, groups = {}, categories = {}, }, -- end of Simple Spawn ServiceSpawn = { main = nil, pages = {}, groups = {}, categories = {}, }, -- end of service spawn SpawnInZone = { main = nil, pages = {}, groups = {}, categories = {}, zones = {}, }, -- end of Spawn In Zone SpawnInRandomZone = { main = nil, pages = {}, groups = {}, categories = {}, }, -- end of Spawn In Random Zone SearchAndDestroy = { main = nil, groups = {}, }, -- end of SearchAndDestroy SpawnAtMark = { main = nil, pages = {}, groups = {}, marks = {}, categories = {}, }, -- end of SpawnAtMark Other = { main = nil, }, -- end of Other }, -- end of blue RED ={ SpawnManager = MENU_COALITION:New( coalition.side.RED, sm_Settings.SpawnManagerMenuName ), -- create Spawn Manager main menu SimpleSpawn = { main = nil, pages = {}, groups = {}, categories = {}, }, -- end of simple spawn ServiceSpawn = { main = nil, pages = {}, groups = {}, categories = {}, }, -- end of service spawn SpawnInZone = { main = nil, pages = {}, groups = {}, categories = {}, zones = {}, }, -- end of Spawn In Zone SpawnInRandomZone = { main = nil, pages = {}, groups = {}, categories = {}, }, -- end of Spawn In Random Zone SearchAndDestroy = { main = nil, groups = {}, }, -- end of SearchAndDestroy SpawnAtMark = { main = nil, pages = {}, groups = {}, marks = {}, categories = {}, }, -- end of SpawnAtMark Other = { main = nil, }, -- end of Other } -- end of red } -- end of sm_Menus sm_Coalitions = { BLUE = 2 , RED = 1} sm_GroupSets = { BLUE = {} , RED = {} , OTHER = {} } sm_ZoneSets = { BLUE = {} , RED = {} } -- ************************************************************************ -- ************************* SPAWN FUNCTIONS *************************** -- ************************************************************************ -- SCHEDULED SPAWN function sm_ScheduledSpawn(spawnTime, unitLimit) if not spawnTime or spawnTime < 1 then spawnTime = 10 end sm_GroupSets.OTHER.ScheduledSpawn:ForEachGroup( function (groupObject) local groupUnitsCount = groupObject:GetInitialSize() if not unitLimit or unitLimit < groupUnitsCount then unitLimit = groupUnitsCount end if groupObject:IsGround() then --MESSAGE:New("unitLimit = "..unitLimit,9):ToAll() local scheSpawn = SPAWN:NewWithAlias( groupObject:GetName(), "SpawnScheduled".." "..math.random(9999) ) scheSpawn:InitLimit(unitLimit,0) scheSpawn:InitRandomizeUnits(sm_Settings.ScheduledSpawn.RandomizeUnitsPosition, 100, 25) scheSpawn:SpawnScheduled(spawnTime,0) elseif groupObject:IsShip() then local scheSpawn = SPAWN:NewWithAlias( groupObject:GetName(), "SpawnScheduled".." "..math.random(9999) ) scheSpawn:InitLimit(unitLimit,0) scheSpawn:InitRandomizeUnits(sm_Settings.ScheduledSpawn.RandomizeUnitsPosition, 500, 100) scheSpawn:SpawnScheduled(spawnTime,0) elseif groupObject:IsAir() then local scheSpawn = SPAWN:NewWithAlias( groupObject:GetName(), "SpawnScheduled".." "..math.random(9999) ) scheSpawn:InitLimit(unitLimit,99) scheSpawn:InitCleanUp(120) scheSpawn:InitRepeatOnEngineShutDown() scheSpawn:SpawnScheduled(spawnTime,0) end end ) end -- end of sm_ScheduledSpawn -- SIMPLE SPAWN - Spawn a group where planned by ME function sm_SimpleSpawn(table) local GroupName = table[1] SPAWN:NewWithAlias( GroupName, string.gsub(GroupName,"%[.-%]", "").." ".."SPWD".." "..math.random(999) ):Spawn() end -- end of sm_SimpleSpawn -- SERVICE SPAWN - Spawn a group where planned by ME - limited to only one group at a time, new spawned groups replace the previous one function sm_ServiceSpawn(table) local GroupName = table[1] local addParams = table[2] local COALITION = addParams[1] ServiceSpawned[GroupName] = SPAWN:New( GroupName ):Spawn() MESSAGE:New(string.gsub(GroupName, "%[.-%]", "").." spawned!",15, sm_Settings.ServiceSpawn.MenuName):ToCoalition(coalition.side[COALITION]) end -- end of sm_ServiceSpawn -- SEARCH AND DESTROY - Spawn a group with random path in a random zone -- @params {GroupName, COALITION} function sm_SpawnSearchAndDestroy(table) local groupObject = table[1] local groupName = groupObject:GetName() local COALITION = table[2] if sm_ZoneSets[COALITION].SearchAndDestroy:Count() < 1 then MESSAGE:New("WARNING - No Search and Destroy Zones Set! Check in Mission Editor.",25):ToAll() return end if groupObject:IsAirPlane() then sm_RandomSearchAndDestroy = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :InitRandomizeZones(sm_ZoneSets[COALITION].SearchAndDestroy:GetSetObjects()) -- randomizza la zona di swpawn prendendola da una lista :InitRandomizeTemplate(sm_GroupSets[COALITION].SearchAndDestroy.AirSearchAndDestroy:GetSetNames()) -- randomizza il gruppo spawnato prendendolo da una lista di template :InitRandomizeRoute(1, 1, sm_Settings.SearchAndDestroy.AirRandomizeRoute) -- randomizza i wpt fra il primo e il penultimo in un'area di "X" metri per ogni wpt :Spawn() elseif groupObject:IsHelicopter() then sm_RandomSearchAndDestroy = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :InitRandomizeZones(sm_ZoneSets[COALITION].SearchAndDestroy:GetSetObjects()) -- randomizza la zona di swpawn prendendola da una lista :InitRandomizeTemplate(sm_GroupSets[COALITION].SearchAndDestroy.HeliSearchAndDestroy:GetSetNames()) -- randomizza il gruppo spawnato prendendolo da una lista di template :InitRandomizeRoute(1, 1, sm_Settings.SearchAndDestroy.HeliRandomizeRoute) -- randomizza i wpt fra il primo e il penultimo in un'area di "X" metri per ogni wpt :Spawn() elseif groupObject:IsGround() then sm_RandomSearchAndDestroy = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :InitRandomizeZones(sm_ZoneSets[COALITION].SearchAndDestroy:GetSetObjects()) -- randomizza la zona di swpawn prendendola da una lista :InitRandomizeTemplate(sm_GroupSets[COALITION].SearchAndDestroy.GroundSearchAndDestroy:GetSetNames()) -- randomizza il gruppo spawnato prendendolo da una lista di template :InitRandomizeRoute(1, 1, sm_Settings.SearchAndDestroy.RandomizeRoute) -- randomizza i wpt fra il primo e il penultimo in un'area di "X" metri per ogni wpt :Spawn() -- if sm_Settings.SearchAndDestroy.SuppressionTakeCover then -- TODO verificare funzionalità - forse meglio usare :OnSpawnGroup() -- sm_SearchAndDestroySuppression = SUPPRESSION:New(sm_RandomSearchAndDestroy) -- :Fallback(false) -- :Takecover(true) -- :SetTakecoverWait(sm_Settings.SearchAndDestroy.TakecoverWait) -- :SetTakecoverRange(sm_Settings.SearchAndDestroy.TakecoverRange) -- end sm_RandomSearchAndDestroy:ScheduleRepeat(10, 20, 0, 7200, markGroup, sm_RandomSearchAndDestroy:GetCoordinate()) end end -- end of sm_SpawnSearchAndDestroy -- SPAWN IN ZONE - Spawn a group in a defined zone -- @params {GroupName, ZoneName} function sm_SpawnInZone(table) local groupName = table[1] local groupObject = GROUP:FindByName(groupName) local spawnZone = ZONE:New(table[2]) -- TODO MIGLIORARE - COSI' GENERA UNA ZONA AD OGNI SPAWN local spawnedGroup = nil if groupObject:IsAirPlane() then local vec2Zone = spawnZone:GetVec2() local Coordinate = COORDINATE:NewFromVec2(vec2Zone) local groundLevel = Coordinate:GetLandHeight() local minSpawnHeight = groundLevel + 1000 spawnedGroup = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :SpawnInZone(spawnZone, true, minSpawnHeight, 8000 ) elseif groupObject:IsHelicopter() then local vec2Zone = spawnZone:GetVec2() local Coordinate = COORDINATE:NewFromVec2(vec2Zone) local groundLevel = Coordinate:GetLandHeight() local spawnMinAltitude = groundLevel + 100 local spawnMaxAltitude = groundLevel + 900 -- MESSAGE:New("min "..spawnMinAltitude,9):ToAll() -- MESSAGE:New("max "..spawnMaxAltitude,9):ToAll() spawnedGroup = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :SpawnInZone(spawnZone, true, spawnMinAltitude, spawnMaxAltitude ) else spawnedGroup = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :InitRandomizeUnits(sm_Settings.SpawnInZone.RandomizeUnitsPosition, sm_Settings.SpawnInZone.RandomizeUnitsRadius, 50) :SpawnInZone(spawnZone, true) end end -- end of sm_SpawnInZone -- SPAWN IN RANDOM ZONE - Spawn a group in a random zone defined by ME -- @params {GroupName, ZoneObjectsTable} function sm_SpawnInRandomZone(table) local GroupName = table[1] local ZoneTable = table[2] if ZoneTable == nil or #ZoneTable < 1 then MESSAGE:New("WARNING - No Random Spawn Zones Found! Check in Mission Editor.",25):ToAll() return end SPAWN:NewWithAlias( GroupName, string.gsub(GroupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :InitRandomizeZones(ZoneTable) -- randomizza la zona di swpawn prendendola da una lista :InitRandomizeUnits(sm_Settings.SpawnInRandomZone.RandomizeUnitsPosition, sm_Settings.SpawnInRandomZone.RandomizeUnitsRadius, 50) :Spawn() end -- end of sm_SpawnInRandomZone -- SPAWN AT POINT (MARKER) -- Spawn on Vec2 coordinate - used for Spawn at Marker function sm_SpawnAtPoint(table) local groupName = table[1] local addParams = table[2] local vec2Point = addParams[1] local markText = addParams[2] local zoneRadius = nil local spawnedGroup = nil if string.match(markText, "%((%d+)%)") then zoneRadius = tonumber(string.match(markText, "%((%d+)%)")) + 1 -- set zone radius if defined in markText between brakets end local RandomizePositionMin = 1 local RandomizePositionMax = zoneRadius or 20 local groupObject= GROUP:FindByName(groupName) if groupObject:IsAirPlane() == true then local groundLevel = math.ceil(vec2Point:GetLandHeight()) local spawnMinAltitude = 7000 -- groundLevel + 1000 spawnedGroup = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :SpawnFromPointVec2(vec2Point, spawnMinAltitude, 9000) elseif groupObject:IsHelicopter() == true then local groundLevel = math.ceil(vec2Point:GetLandHeight()) local spawnMinAltitude = groundLevel + 150 local spawnMaxAltitude = groundLevel + 800 spawnedGroup = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) :SpawnFromPointVec2(vec2Point, spawnMinAltitude, spawnMaxAltitude) else spawnedGroup = SPAWN:NewWithAlias( groupName, string.gsub(groupName, "%[.-%]", "").." ".."SPWD".." "..math.random(999) ) spawnedGroup:InitRandomizePosition(true , RandomizePositionMax, RandomizePositionMin) spawnedGroup:InitRandomizeUnits(sm_Settings.SpawnAtMark.RandomizeUnitsPosition, sm_Settings.SpawnAtMark.RandomizeUnitsRadius, 50) spawnedGroup:SpawnFromPointVec2(vec2Point) end end -- end of sm_SpawnAtPoint --function SpawnJtacAtPoint(table) -- Spawn di gruppo JTAC su Marker Mappa F10 -- local groupName = table[1] -- local vec2Point = table[2] -- local markName = table [3] -- local markID = table[4] -- JtacTable[markID] = {} -- local groupObject= GROUP:FindByName(groupName) -- if groupObject:GetCoalition() == 1 then -- JtacCoalition = "red" -- elseif groupObject:GetCoalition() == 2 then -- JtacCoalition = "blue" -- end -- if groupObject:IsGround() == true then -- JtacTable[markID].SpawnedJtac = SPAWN:NewWithAlias( groupName, "SPWD JTAC"..markID ) -- :SpawnFromPointVec2(vec2Point) -- -- --MESSAGE:New(SpawnedJtac:GetName(),9):ToAll() -- JtacTable[markID].JtacCommandCenter = COMMANDCENTER:New(JtacTable[markID].SpawnedJtac , "Jtac" ) -- JtacTable[markID].JtacSet = SET_GROUP:New():FilterCoalitions(JtacCoalition):FilterPrefixes(JtacTable[markID].SpawnedJtac:GetName()):FilterOnce() -- JtacTable[markID].JtacDetectionAreas = DETECTION_AREAS:New(JtacTable[markID].JtacSet,700):SetAcceptRange(15000) -- JtacTable[markID].JtacAttackSet = SET_GROUP:New():FilterActive(true):FilterCategories("plane", "helicopter"):FilterCoalitions(JtacCoalition):FilterStart() -- JtacTable[markID].JtacDesignation = DESIGNATE:New( JtacTable[markID].JtacCommandCenter, JtacTable[markID].JtacDetectionAreas, JtacTable[markID].JtacAttackSet ) -- :SetThreatLevelPrioritization( true ) -- designa prima unità anti aeree secondo la gravità della minaccia che rappresentano -- :AddMenuLaserCode( 1113, "Lase con %d per Su-25T" ) -- Add a specific lase code to the designate lase menu to lase targets with a specific laser code. -- :SetLaserCodes( { 1688, 1687, 1686, 1685 } ) -- Set the possible laser codes. -- :SetFlashStatusMenu( true ) -- Set the flashing of the status menu for all AttackGroups. -- :SetLaseDuration(240) -- :SetMaximumDistanceDesignations(12000) -- :SetDesignateName(markName) -- -- JtacTable[markID].JtacDesignation:__Detect( -5 ) -- end --end -- ************************************************************************ -- ************************ UTILITY FUNCTIONS ************************** -- ************************************************************************ -- DESTROY ALL SPAWNED - Destroys all currently active spawned groups - exept service spawned -- @params (SET_GROUP da distruggere) function sm_DestroyAllSpawned(warnPlayers) sm_GroupSets.OTHER.Spawned:ForEachGroup( function(groupObject) groupObject:Destroy(false) -- destroy group without generate a destroy event end ) if warnPlayers == true or warnPlayers == nil then MESSAGE:New("All spawned groups have been destroyed (exept Service Spawn)",15):ToAll() end env.info("K-ASSISTANT : SPAWN MANAGER - func: sm_DestroyAllSpawned - All spawned groups have been destroyed (exept Service Spawn)", false) end -- end of DESTROY ALL SPAWNED -- DESTROY ALL SERVICE SPAWNED - Destroys all currently active Service Spawned groups - not all spawned function sm_DestroyAllServiceSpawned(warnPlayers) for groupName, groupObject in pairs(ServiceSpawned) do if groupObject then groupObject:Destroy(false) -- destroy group without generate a destroy event end end if warnPlayers == true or warnPlayers == nil then MESSAGE:New("All Service Spawn groups have been destroyed",15):ToAll() end env.info("K-ASSISTANT : SPAWN MANAGER - func: sm_DestroyAllServiceSpawned - All Service Spawn groups have been destroyed", false) end -- end of DESTROY ALL SERVICE SPAWNED -- SERVER CLEANER - Cleanup server from spawned group and spawn markers when no active clients are detected function sm_ServerCleaner() env.info("K-ASSISTANT: SPAWN MANAGER - SERVER CLEANER", false) local clientList = net.get_player_list() if #clientList == 0 then -- is single player env.warning("SPAWN MANAGER - SERVER CLEANER : SINGLE PLAYER MODE DETECTED", false) env.warning("SPAWN MANAGER - SERVER CLEANER SHOULD BE ENABLED IN MULTIPLAYER ONLY!", false) sm_ServerCleanerTimer:Stop() env.warning("SERVER CLEANER KILLED ITSELF AND IS NOW DISABLED!", false) return elseif #clientList > 1 then -- clients are connected env.info("SPAWN MANAGER - SERVER CLEANER : CLIENTS CONNECTED TO SERVER - CLEANING SKIPPED ", false) env.info("CONNECTED CLIENTS : "..tostring(#clientList), false) return elseif #clientList == 1 then -- only server host is connected env.info("CONNECTED CLIENTS : "..tostring(#clientList), false) sm_DestroyAllSpawned(false) -- clean spawned sm_DestroyAllServiceSpawned(false) -- clean service spawned for COALITION, _ in pairs(sm_Coalitions) do for markID, markMenu in pairs(sm_Menus[COALITION].SpawnAtMark.marks) do -- clean spawn markers and spawn at mark menus trigger.action.removeMark(markID) sm_Menus[COALITION].SpawnAtMark.marks[markID] = nil end end env.info("SPAWN MANAGER - SERVER CLEANER : NO CONNECTED CLIENTS - CLEANING DONE ", false) end end -- end of Server Cleaner -- ************************************************************************ -- ******************* MENU GENERATION FUNCTIONS *********************** -- ************************************************************************ -- Generate the lowest level of menus, groups to spawn function sm_GroupMenuGenerator(groupNamesTable, COALITION, parentMenu, spawnModuleType, callBack, callBackAddParams) if #groupNamesTable >= 1 then table.sort(groupNamesTable) -- ordina la lista dei gruppi in ordine alfabetico if #groupNamesTable <= 10 then -- se il totale dei gruppi è inferiore a 11 inserisce tutti i gruppi direttamente sotto il menu Spawn in Random Zone for GroupIndex, GroupName in ipairs(groupNamesTable) do sm_Menus[COALITION][spawnModuleType].groups[GroupName] = MENU_COALITION_COMMAND:New( coalition.side[COALITION], string.gsub(GroupName, "%[.-%]", ""), parentMenu, callBack, {GroupName, callBackAddParams}) end else -- se lista gruppi maggiore di... occorre creare dei sotto menu di raggruppamento local GroupMenuTotal = math.ceil(#groupNamesTable / 10) -- determina il numero di menu di raggruppamento necessari local CommandMenuButtonCounter = 0 -- contatore bottoni comando per sotto menu local GroupMenuCounter = 1 -- contatore menu di raggruppamento for i=1, GroupMenuTotal do -- crea dei nuovi menu di raggruppamento sm_Menus[COALITION][spawnModuleType].pages[i] = MENU_COALITION:New( coalition.side[COALITION], "Page "..i, parentMenu ) end for GroupIndex, GroupName in ipairs (groupNamesTable) do -- crea i menu comando sotto i menu di raggruppamento if CommandMenuButtonCounter > 8 then -- passa al menu di raggruppamento successivo quando il precedente è pieno sm_Menus[COALITION][spawnModuleType].groups[GroupName] = MENU_COALITION_COMMAND:New( coalition.side[COALITION], string.gsub(GroupName, "%[.-%]", ""), sm_Menus[COALITION][spawnModuleType].pages[GroupMenuCounter], callBack, {GroupName, callBackAddParams} ) GroupMenuCounter = GroupMenuCounter + 1 CommandMenuButtonCounter = 0 else -- popola il menu di raggruppamento corrente sm_Menus[COALITION][spawnModuleType].groups[GroupName] = MENU_COALITION_COMMAND:New( coalition.side[COALITION], string.gsub(GroupName, "%[.-%]", ""), sm_Menus[COALITION][spawnModuleType].pages[GroupMenuCounter], callBack, {GroupName, callBackAddParams} ) CommandMenuButtonCounter = CommandMenuButtonCounter + 1 end end end end end -- end of sm_GroupMenuGenerator -- split spawnable into categories, generates category menus and calls other functions to fill theme function sm_CategoryMenuGenerator (spawnModuleType, COALITION, callBack, callBackAddParams, parentMenu, groupSetName) callBackAddParams = callBackAddParams or {} groupSetName = groupSetName or spawnModuleType parentMenu = parentMenu or sm_Menus[COALITION][spawnModuleType].main if sm_GroupSets[COALITION][groupSetName].Air == nil then sm_GroupSets[COALITION][groupSetName].Air = SET_GROUP:New():FilterCategoryAirplane():FilterPrefixes(sm_Tags[COALITION][groupSetName]):FilterOnce() -- il set di gruppi definiti da ME che sarà possibile spawnare end if sm_GroupSets[COALITION][groupSetName].Air:Count() >=1 then sm_Menus[COALITION][spawnModuleType].categories.air = MENU_COALITION:New( coalition.side[COALITION], "Airplanes", parentMenu ) sm_GroupMenuGenerator(sm_GroupSets[COALITION][groupSetName].Air:GetSetNames(), COALITION, sm_Menus[COALITION][spawnModuleType].categories.air, spawnModuleType, callBack, callBackAddParams) end if sm_GroupSets[COALITION][groupSetName].Helo == nil then sm_GroupSets[COALITION][groupSetName].Helo = SET_GROUP:New():FilterCategoryHelicopter():FilterPrefixes(sm_Tags[COALITION][groupSetName]):FilterOnce() end if sm_GroupSets[COALITION][groupSetName].Helo:Count() >=1 then sm_Menus[COALITION][spawnModuleType].categories.helo = MENU_COALITION:New( coalition.side[COALITION], "Helicopters", parentMenu ) sm_GroupMenuGenerator(sm_GroupSets[COALITION][groupSetName].Helo:GetSetNames(), COALITION, sm_Menus[COALITION][spawnModuleType].categories.helo, spawnModuleType, callBack, callBackAddParams) end if sm_GroupSets[COALITION][groupSetName].Ground == nil then sm_GroupSets[COALITION][groupSetName].Ground = SET_GROUP:New():FilterCategoryGround():FilterPrefixes(sm_Tags[COALITION][groupSetName]):FilterOnce() end if sm_GroupSets[COALITION][groupSetName].Ground:Count() >=1 then sm_Menus[COALITION][spawnModuleType].categories.ground = MENU_COALITION:New( coalition.side[COALITION], "Ground", parentMenu ) sm_GroupMenuGenerator(sm_GroupSets[COALITION][groupSetName].Ground:GetSetNames(), COALITION, sm_Menus[COALITION][spawnModuleType].categories.ground, spawnModuleType, callBack, callBackAddParams) end if sm_GroupSets[COALITION][groupSetName].Ship == nil then sm_GroupSets[COALITION][groupSetName].Ship = SET_GROUP:New():FilterCategoryShip():FilterPrefixes(sm_Tags[COALITION][groupSetName]):FilterOnce() end if sm_GroupSets[COALITION][groupSetName].Ship:Count() >=1 then sm_Menus[COALITION][spawnModuleType].categories.ship = MENU_COALITION:New( coalition.side[COALITION], "Ships", parentMenu ) sm_GroupMenuGenerator(sm_GroupSets[COALITION][groupSetName].Ship:GetSetNames(), COALITION, sm_Menus[COALITION][spawnModuleType].categories.ship, spawnModuleType, callBack, callBackAddParams) end end -- end of sm_CategoryMenuGenerator -- generate Spawn Zones menus anc call other functions to fill theme function sm_ZoneMenuGenerator (zoneSet, groupNamesTable, parentMenu, COALITION, spawnModuleType, groupSetName) COALITION = string.upper(COALITION) spawnModuleType = spawnModuleType or "SpawnInZone" groupSetName = groupSetName or spawnModuleType local zoneNamesTable = zoneSet:GetSetNames() if #zoneNamesTable >= 1 then table.sort( zoneNamesTable ) -- sort by zone name if sm_Settings.SpawnInZone.Categories == false then for ZoneIndex, ZoneName in ipairs(zoneNamesTable) do sm_Menus[COALITION].SpawnInZone.zones[ZoneName] = MENU_COALITION:New( coalition.side[COALITION], string.gsub(ZoneName, "%[.-%]", ""), parentMenu) -- Crea il menu Zona sm_GroupMenuGenerator(groupNamesTable, COALITION, sm_Menus[COALITION].SpawnInZone.zones[ZoneName], spawnModuleType, sm_SpawnInZone, ZoneName) end else for ZoneIndex, ZoneName in ipairs(zoneNamesTable) do sm_Menus[COALITION].SpawnInZone.zones[ZoneName] = MENU_COALITION:New( coalition.side[COALITION], string.gsub(ZoneName, "%[.-%]", ""), parentMenu) -- Crea il menu Zona sm_CategoryMenuGenerator (spawnModuleType, COALITION, sm_SpawnInZone, ZoneName, sm_Menus[COALITION].SpawnInZone.zones[ZoneName], groupSetName) end end end end -- end of sm_ZoneMenuGenerator -- generate Search & Destroy menus function sm_SearchAndDestroyMenuGenerator (baseSearchAndDestroySet, COALITION) sm_Menus[COALITION].SearchAndDestroy.main = MENU_COALITION:New( coalition.side[COALITION], sm_Settings.SearchAndDestroy.MenuName, sm_Menus[COALITION].SpawnManager ) if baseSearchAndDestroySet:Count() >= 1 then baseSearchAndDestroySet:ForEachGroup( function (groupObject) local groupName = groupObject:GetName() sm_Menus[COALITION].SearchAndDestroy.groups[groupName] = MENU_COALITION_COMMAND:New( coalition.side[COALITION], string.gsub(groupName, "%[.-%]", ""), sm_Menus[COALITION].SearchAndDestroy.main, sm_SpawnSearchAndDestroy, {groupObject, COALITION}) end ) end end -- end of SM_SearchAndDestroyMenuGenerator -- ************************************************************************ -- ********************************* INIT ******************************* -- ************************************************************************ -- Setup data and all what is needed and call menu generators functions function sm_BigSmith() env.info("SPAWN MANAGER func: sm_BigSmith - Starting Initialization!", false) for kCoalition, kValue in pairs(sm_Coalitions) do local COALITION = kCoalition local coalitionNumber = kValue -- Simple Spawn if sm_Settings.SimpleSpawn.Enable == true then local spawnModuleType = "SimpleSpawn" local callBack = sm_SimpleSpawn sm_GroupSets[COALITION][spawnModuleType] = {} sm_Menus[COALITION][spawnModuleType].main = MENU_COALITION:New( coalition.side[COALITION], sm_Settings[spawnModuleType].MenuName, sm_Menus[COALITION].SpawnManager ) if sm_Settings[spawnModuleType].Categories == false then sm_GroupSets[COALITION][spawnModuleType].Mixed = SET_GROUP:New():FilterPrefixes(sm_Tags[COALITION][spawnModuleType]):FilterOnce() -- il set di gruppi definiti da ME che sarà possibile spawnare sm_GroupMenuGenerator(sm_GroupSets[COALITION][spawnModuleType].Mixed:GetSetNames(), COALITION, sm_Menus[COALITION][spawnModuleType].main, spawnModuleType, callBack) else sm_CategoryMenuGenerator (spawnModuleType, COALITION, callBack) end env.info("SPAWN MANAGER - SIMPLE SPAWN ENABLED FOR "..COALITION.." COALITION", false) end -- end of Simple Spawn -- Service Spawn if sm_Settings.ServiceSpawn.Enable == true then local spawnModuleType = "ServiceSpawn" local callBack = sm_ServiceSpawn sm_GroupSets[COALITION][spawnModuleType] = {} sm_Menus[COALITION][spawnModuleType].main = MENU_COALITION:New( coalition.side[COALITION], sm_Settings[spawnModuleType].MenuName, sm_Menus[COALITION].SpawnManager ) ServiceSpawned = {} if sm_Settings[spawnModuleType].Categories == false then sm_GroupSets[COALITION][spawnModuleType].Mixed = SET_GROUP:New():FilterPrefixes(sm_Tags[COALITION][spawnModuleType]):FilterOnce() -- il set di gruppi definiti da ME che sarà possibile spawnare sm_GroupMenuGenerator(sm_GroupSets[COALITION][spawnModuleType].Mixed:GetSetNames(), COALITION, sm_Menus[COALITION][spawnModuleType].main, spawnModuleType, callBack, {COALITION}) else sm_CategoryMenuGenerator (spawnModuleType, COALITION, callBack, {COALITION}) end env.info("SPAWN MANAGER - SERVICE SPAWN ENABLED FOR "..COALITION.." COALITION", false) end -- end of Service Spawn -- Spawn In Zone if sm_Settings.SpawnInZone.Enable == true then local spawnModuleType = "SpawnInZone" local groupSetName = "Spawnable" local callBack = sm_SpawnInZone if sm_GroupSets[COALITION][groupSetName] == nil then sm_GroupSets[COALITION][groupSetName] = {} end sm_ZoneSets[COALITION].SpawnZones = SET_ZONE:New():FilterPrefixes(sm_Tags[COALITION].Zones.SpawnZone):FilterOnce() sm_Menus[COALITION][spawnModuleType].main = MENU_COALITION:New( coalition.side[COALITION], sm_Settings[spawnModuleType].MenuName, sm_Menus[COALITION].SpawnManager ) if sm_Settings[spawnModuleType].Categories == false then if sm_GroupSets[COALITION][groupSetName].Mixed == nil then sm_GroupSets[COALITION][groupSetName].Mixed = SET_GROUP:New():FilterPrefixes(sm_Tags[COALITION][groupSetName]):FilterOnce() -- il set di gruppi definiti da ME che sarà possibile spawnare end sm_ZoneMenuGenerator (sm_ZoneSets[COALITION].SpawnZones, sm_GroupSets[COALITION][groupSetName].Mixed:GetSetNames(), sm_Menus[COALITION][spawnModuleType].main , COALITION, spawnModuleType, groupSetName) else sm_ZoneMenuGenerator (sm_ZoneSets[COALITION].SpawnZones, nil, sm_Menus[COALITION][spawnModuleType].main , COALITION, spawnModuleType, groupSetName) end -- Zone Mark On Map if sm_Settings.SpawnInZone.MarkSpawnZonesOnMap == true then sm_ZoneSets[COALITION].SpawnZones:ForEachZone( function (zone) zone:DrawZone(coalitionNumber, {0,0,0}, 0.8, zone:GetColorRGB(), 0.15, 2, true) --zone:GetColorRGB() COORDINATE:NewFromVec2(zone:GetVec2()):TextToAll(string.gsub(zone:GetName(), "%[.-%]", ""), coalitionNumber, {0,0,0}, 0.8, zone:GetColorRGB(), 0.4, 14, true, "") end ) end -- end of Zone Mark On Map env.info("SPAWN MANAGER - SPAWN IN ZONE ENABLED FOR "..COALITION.." COALITION", false) end -- end of Spawn In Zone -- Spawn in Random Zone if sm_Settings.SpawnInRandomZone.Enable == true then local spawnModuleType = "SpawnInRandomZone" local groupSetName = "Spawnable" local callBack = sm_SpawnInRandomZone if sm_GroupSets[COALITION][groupSetName] == nil then sm_GroupSets[COALITION][groupSetName] = {} end sm_ZoneSets[COALITION].RandomSpawnZones = SET_ZONE:New():FilterPrefixes(sm_Tags[COALITION].Zones.RandomSpawnZone):FilterOnce() sm_Menus[COALITION][spawnModuleType].main = MENU_COALITION:New( coalition.side[COALITION], sm_Settings[spawnModuleType].MenuName, sm_Menus[COALITION].SpawnManager ) if sm_Settings[spawnModuleType].Categories == false then if sm_GroupSets[COALITION][groupSetName].Mixed == nil then sm_GroupSets[COALITION][groupSetName].Mixed = SET_GROUP:New():FilterPrefixes(sm_Tags[COALITION][groupSetName]):FilterOnce() -- il set di gruppi definiti da ME che sarà possibile spawnare end sm_GroupMenuGenerator(sm_GroupSets[COALITION][groupSetName].Mixed:GetSetNames(), COALITION, sm_Menus[COALITION][spawnModuleType].main, spawnModuleType, callBack, sm_ZoneSets[COALITION].RandomSpawnZones:GetSetObjects() ) else sm_CategoryMenuGenerator (spawnModuleType, COALITION, callBack, sm_ZoneSets[COALITION].RandomSpawnZones:GetSetObjects(), nil, groupSetName) end env.info("SPAWN MANAGER - SPAWN IN RANDOM ZONE ENABLED FOR "..COALITION.." COALITION", false) end -- end of Spawn in Random Zone -- Search & Destroy if sm_Settings.SearchAndDestroy.Enable == true then sm_GroupSets[COALITION].SearchAndDestroy = {} sm_GroupSets[COALITION].SearchAndDestroy.GroundSearchAndDestroy = SET_GROUP:New():FilterCategoryGround():FilterPrefixes(sm_Tags[COALITION].SearchAndDestroy):FilterOnce() -- il set di gruppi che sarà possibile spawnare in zona casuale come gruppi in movimento con rotta casuale sm_GroupSets[COALITION].SearchAndDestroy.AirSearchAndDestroy = SET_GROUP:New():FilterCategoryAirplane():FilterPrefixes(sm_Tags[COALITION].SearchAndDestroy):FilterOnce() -- il set di gruppi che sarà possibile spawnare in zona casuale come gruppi in movimento con rotta casuale sm_GroupSets[COALITION].SearchAndDestroy.HeliSearchAndDestroy = SET_GROUP:New():FilterCategoryHelicopter():FilterPrefixes(sm_Tags[COALITION].SearchAndDestroy):FilterOnce() -- il set di gruppi che sarà possibile spawnare in zona casuale come gruppi in movimento con rotta casuale sm_GroupSets[COALITION].SearchAndDestroy.BaseSearchAndDestroy = SET_GROUP:New():FilterPrefixes(sm_Tags[COALITION].BaseSearchAndDestroy):FilterOnce()-- i gruppi definiti nel ME da cui si prenderanno i parametri per il routing dei gruppi random in random zone sm_ZoneSets[COALITION].SearchAndDestroy = SET_ZONE:New():FilterPrefixes(sm_Tags[COALITION].Zones.RandomSearchAndDestroyZone):FilterOnce() sm_SearchAndDestroyMenuGenerator (sm_GroupSets[COALITION].SearchAndDestroy.BaseSearchAndDestroy, COALITION) env.info("SPAWN MANAGER - SEARCH AND DESTROY ENABLED FOR "..COALITION.." COALITION", false) end -- end of Search & Destroy -- SPAWN AT MARK if sm_Settings.SpawnAtMark.Enable then local spawnModuleType = "SpawnAtMark" local groupSetName = nil local callBack = sm_SpawnAtPoint if sm_Settings.SpawnAtMark.OwnSpawnGroups == true then groupSetName = "SpawnAtMark" elseif sm_Settings.SpawnAtMark.OwnSpawnGroups == false then groupSetName = "Spawnable" end sm_Menus[COALITION][spawnModuleType].main = MENU_COALITION:New( coalition.side[COALITION], sm_Settings.SpawnAtMark.MenuName, sm_Menus[COALITION].SpawnManager ) -- Crea il menu principale Spawn at Marker if sm_GroupSets[COALITION][groupSetName] == nil then sm_GroupSets[COALITION][groupSetName] = {} end if sm_Settings[spawnModuleType].Categories == false then if sm_GroupSets[COALITION][groupSetName].Mixed == nil then sm_GroupSets[COALITION][groupSetName].Mixed = SET_GROUP:New():FilterPrefixes(sm_Tags[COALITION][groupSetName]):FilterOnce() end end env.info("SPAWN MANAGER - SPAWN AT MARK ENABLED FOR "..COALITION.." COALITION", false) end -- end of Spawn At Mark -- Delete All Spawned and Delete all service spawned if sm_Settings.DeleteSpawned.Enable == true then sm_GroupSets.OTHER.Spawned = SET_GROUP:New():FilterActive(true):FilterPrefixes("SPWD"):FilterStart() if sm_Menus[COALITION].Other.main == nil then sm_Menus[COALITION].Other.main = MENU_COALITION:New( coalition.side[COALITION], "More", sm_Menus[COALITION].SpawnManager ) end local deleteSpawnedText = [[Are you SURE? This will delete all Spawned groups in mission!!!]] local deleteServiceSpawnedText = [[Are you SURE? This will delete all Service Spawned groups in mission!!!]] sm_Menus[COALITION].Other.DeleteSpawnedMain = MENU_COALITION:New( coalition.side[COALITION], "Delete all Spawned", sm_Menus[COALITION].Other.main ) sm_Menus[COALITION].Other.DeleteSpawnedConfirm = MENU_COALITION_COMMAND:New( coalition.side[COALITION], deleteSpawnedText, sm_Menus[COALITION].Other.DeleteSpawnedMain , sm_DestroyAllSpawned ) sm_Menus[COALITION].Other.DeleteServiceSpawnedMain = MENU_COALITION:New( coalition.side[COALITION], "Delete all Service Spawned", sm_Menus[COALITION].Other.main ) sm_Menus[COALITION].Other.DeleteServiceSpawnedConfirm = MENU_COALITION_COMMAND:New( coalition.side[COALITION], deleteServiceSpawnedText, sm_Menus[COALITION].Other.DeleteServiceSpawnedMain, sm_DestroyAllServiceSpawned ) env.info("SPAWN MANAGER - DELETE SPAWNED ENABLED FOR "..COALITION.." COALITION", false) end-- end of Delete All Spawned end -- end of coalitions for loop --------------------------------------------------------------------------------------------------------------------------------------- -- Generic - coalition does not metter --------------------------------------------------------------------------------------------------------------------------------------- -- SCHEDULED SPAWN if sm_Settings.ScheduledSpawn.Enable == true then sm_GroupSets.OTHER.ScheduledSpawn = SET_GROUP:New():FilterPrefixes(sm_Tags.GENERIC.ScheduledSpawn):FilterOnce() sm_ScheduledSpawn() env.info("SPAWN MANAGER - SCHEDULED SPAWN ENABLED", false) end -- end of SCHEDULED SPAWN -- Spawn At Mark if sm_Settings.SpawnAtMark.Enable then sm_MarkEvents = EVENTHANDLER:New() -- Crea EventHandler sm_MarkEvents:HandleEvent(EVENTS.MarkChange) -- Sottoscrive un tipo di Evento : quando un markpoint viene modificato sm_MarkEvents:HandleEvent(EVENTS.MarkRemoved) function sm_MarkEvents:OnEventMarkChange(EventData) -- esegue una funzione al verificarsi del tipo di evento precendentemente sottoscritto local markText = string.upper(EventData.MarkText) local MarkCoalition = nil local groupSetName = nil local spawnModuleType = "SpawnAtMark" if sm_Settings.SpawnAtMark.OwnSpawnGroups == true then groupSetName = "SpawnAtMark" elseif sm_Settings.SpawnAtMark.OwnSpawnGroups == false then groupSetName = "Spawnable" end if string.match(markText, sm_Tags.MARK) == sm_Tags.MARK then if EventData.MarkCoalition == 1 then MarkCoalition = "RED" elseif EventData.MarkCoalition == 2 then MarkCoalition = "BLUE" end local Vec2Coord = POINT_VEC2:NewFromVec3(EventData.MarkVec3) if sm_Menus[MarkCoalition].SpawnAtMark.marks[tostring(EventData.MarkID)] then sm_Menus[MarkCoalition].SpawnAtMark.marks[tostring(EventData.MarkID)]:Remove() end sm_Menus[MarkCoalition].SpawnAtMark.marks[tostring(EventData.MarkID)] = MENU_COALITION:New( coalition.side[MarkCoalition], markText, sm_Menus[MarkCoalition].SpawnAtMark.main) if sm_Settings.SpawnAtMark.Categories == false then sm_GroupMenuGenerator(sm_GroupSets[MarkCoalition][groupSetName].Mixed:GetSetNames(), MarkCoalition, sm_Menus[MarkCoalition].SpawnAtMark.marks[tostring(EventData.MarkID)], spawnModuleType, sm_SpawnAtPoint, {Vec2Coord, markText} ) elseif sm_Settings.SpawnAtMark.Categories == true then sm_CategoryMenuGenerator (spawnModuleType, MarkCoalition, sm_SpawnAtPoint, {Vec2Coord, markText} , sm_Menus[MarkCoalition].SpawnAtMark.marks[tostring(EventData.MarkID)], groupSetName) end end end -- removes the radio menu when mark point is deleted function sm_MarkEvents:OnEventMarkRemoved(EventData) local MarkCoalition if EventData.MarkCoalition == 1 then MarkCoalition = "RED" elseif EventData.MarkCoalition == 2 then MarkCoalition = "BLUE" end -- MESSAGE:New(tostring(EventData.MarkID.."REMOVED"),9):ToAll() if sm_Menus[MarkCoalition].SpawnAtMark.marks[tostring(EventData.MarkID)] then -- TODO è capitato desse errore verificare sm_Menus[MarkCoalition].SpawnAtMark.marks[tostring(EventData.MarkID)]:Remove() end end --env.info("SPAWN MANAGER - SPAWN AT MARK ENABLED", false) end -- end of Spawn At Mark -- SERVER CLEANER if sm_Settings.ServerCleaner.Enable == true then local TimerInSeconds = math.floor(sm_Settings.ServerCleaner.ScanTimer * 60) sm_ServerCleanerTimer = TIMER:New(sm_ServerCleaner) sm_ServerCleanerTimer:Start(TimerInSeconds, TimerInSeconds) env.info("K-ASSISTANT : SPAWN MANAGER - SERVER CLEANER ENABLED - CHECK WILL BE PERFORMED EVERY: "..TimerInSeconds.." seconds", false) end -- end of Server Cleaner end -- end of sm_BigSmith sm_BigSmith() if sm_Settings.WecomeMessage == true then MESSAGE:New( "K-Assistant: Spawn Manager - Loaded!" , 3):ToAll() end env.info("* * * K-ASSISTANT: SPAWN MANAGER LOADED * * *",false)