ked Posted March 6, 2017 Share Posted March 6, 2017 Hey guys i'm using ATME to spawn air unit groups based on an activation retarded group as a model. This group has waypoints but they seem to not follow them at first, right now they spawn , go for the nearest target and once it's destroyed they go back to follow their waypoints. I've got no idea how to make them follow waypoints and attack units within a certain range while still following waypoints (i'd like a real patrol but this doesn't seem to work) Any idea ? PS: i've got AWACS but i've tried without it and it doesn't see to change much Link to comment Share on other sites More sharing options...
MadDog-IC Posted March 7, 2017 Share Posted March 7, 2017 Hey guys i'm using ATME to spawn air unit groups based on an activation retarded group as a model. This group has waypoints but they seem to not follow them at first, right now they spawn , go for the nearest target and once it's destroyed they go back to follow their waypoints. I've got no idea how to make them follow waypoints and attack units within a certain range while still following waypoints (i'd like a real patrol but this doesn't seem to work) Any idea ? PS: i've got AWACS but i've tried without it and it doesn't see to change much Not sure what ATME does, haven't looked into it (assuming it does dynamic spawning, etc), but in normal Mission editor flight groups which have CAS -a or SEAD, -a or like instructions in the advanced way point commands it will do exactly as your description of not following waypoints when enemy's on map. Solution is to remove those lines or disable them and add in search and engage commands at certain other waypoints for them to attack in only the areas you want them to. Regards, Ian. Asus p877v-pro, Intel I7 3770k 4.2ghz, 32gb Ripjaw X ram, Nvidia RTX-2070 Super, Samsung 32" TV, Saitek x52 pro Joystick and Combat rudder pedals, TrackIR 5, Win8.1 x64 with SSD and SSHD protected by (Avast AV). DCS Tech Support. Link to comment Share on other sites More sharing options...
feefifofum Posted March 7, 2017 Share Posted March 7, 2017 Hey ked, Not sure exactly how ATME treats assigning tasking but if it just spawns things you've set up in the ME the following will work: Select your CAP flight Go to Advanced Waypoint Actions at WP0 (or SP for Russian birds) DELETE the default CAP tasking Click ADD -》 Start Enroute Task -》Search then Engage in Zone Drag the engagement area to the desired location and expand the radius to the desired size. The flight will follow its waypoints and only attack if something enters the zone you've set in Advanced Waypoint Actions. Good luck! EDIT: Sniped by Ian! :) THE GEORGIAN WAR - OFFICIAL F-15C DLC Link to comment Share on other sites More sharing options...
ked Posted March 7, 2017 Author Share Posted March 7, 2017 Thanks , will try that Link to comment Share on other sites More sharing options...
sunski34 Posted March 7, 2017 Share Posted March 7, 2017 (edited) Hi, actually, ATME doesn't change tasks defined in Mission Editor. You cannot assign new tasks with ATME too (except indirect task full managed by ATME like waypoint tracking or managing boarding/unboarding units). Those abilities are in the roadmap for the future (no release date). My priority is to stabilize actual lua code, finalise basics abilities and leave beta version. If you want to assign or modify specific tasks, you have to define or modify them in Mission Editor only (like explained above). When you spawn a group with ATME, you can assign route of another group. So in ME you can create desactivated group with route correctly defined (with good tasks) and assign this route to another group. Hope that help Sunski Edited March 7, 2017 by sunski34 Link to comment Share on other sites More sharing options...
ked Posted March 7, 2017 Author Share Posted March 7, 2017 feefifofum's solution works perfectly thanks everyone for the help ! Link to comment Share on other sites More sharing options...
feefifofum Posted March 8, 2017 Share Posted March 8, 2017 :thumbup: Now share your mission so we can all enjoy it! :) THE GEORGIAN WAR - OFFICIAL F-15C DLC Link to comment Share on other sites More sharing options...
ked Posted March 8, 2017 Author Share Posted March 8, 2017 It might be i little laggy right now, still working on a way to do some things better. For exemple there's no way to do polygonal areas so i've got to do several circal areas and check every single one of them to make sure nobody's in there. And with ATME, looking at the doc i've only found player:isInDCSZone("zonename") which checks if player is in zone, but it would be much more effective to get the zone he is actualy in and then do a switch with functions spawning units. I'm looking at events handled by ATME but no sucess so far. I have to say i've only tested it with maximum 3 players on a medium PC (4th gen i5 and 8go of ram) and people were feeling some lags sometimes when i was going throug menus changing my commands. I'm looking to optimise this, you can find the full mision and luas here : mission my code local thisModule local moduleName = "QuickResponse" local function onCreatePlayer(player) player.modules[moduleName].inZoneBravo = false player.modules[moduleName].inZoneCharlie = false player.modules[moduleName].inZoneDelta = false player.modules[moduleName].inZoneFoxtrott = false player.modules[moduleName].inZoneGolf = false player.modules[moduleName].inZoneHotel = false player.modules[moduleName].inZoneIndia = false player.modules[moduleName].inZoneJuliett = false player.modules[moduleName].coalitionName = player:getCoalitionName() end local function onZonePass(player, events) -- Bravo if (player:isInDCSZone("Bravo 1") == true or player:isInDCSZone("Bravo 2") == true or player:isInDCSZone("Bravo 3") == true or player:isInDCSZone("Bravo 4") == true or player:isInDCSZone("Bravo 5") == true or player:isInDCSZone("Bravo 6") == true) and player.modules[moduleName].coalitionName == "BLUE" then if player.modules[moduleName].inZoneBravo == false then -- Test the flag to do it once local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas("Bravo Quick Response M21B", "Bravo Quick Response M21B" .. math.random(10000)) if err == false then var1:spawn("Bravo 1") end -- and just after, set flag to true. player.modules[moduleName].inZoneBravo = true end else -- Player leaves zone, flag has to set to false once. if player.modules[moduleName].inZoneBravo == true then player.modules[moduleName].inZoneBravo = false end end -- Charlie if (player:isInDCSZone("Charlie 1") == true or player:isInDCSZone("Charlie 2") == true or player:isInDCSZone("Charlie 3") == true or player:isInDCSZone("Charlie 4") == true or player:isInDCSZone("Charlie 5") == true or player:isInDCSZone("Charlie 6") == true) and player.modules[moduleName].coalitionName == "RED" then if player.modules[moduleName].inZoneCharlie == false then -- Test the flag to do it once local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas("Charlie Quick Response F5", "Charlie Quick Response F5" .. math.random(10000)) if err == false then var1:spawn("Delta") end -- and just after, set flag to true. player.modules[moduleName].inZoneCharlie = true end else -- Player leaves zone, flag has to set to false once. if player.modules[moduleName].inZoneCharlie == true then player.modules[moduleName].inZoneCharlie = false end end -- Delta if player:isInDCSZone("Delta") == true and player.modules[moduleName].coalitionName == "RED" then if player.modules[moduleName].inZoneDelta == false then -- Test the flag to do it once local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas("Delta Quick Response F5", "Delta Quick Response F5" .. math.random(10000)) if err == false then var1:spawn("Delta") end -- and just after, set flag to true. player.modules[moduleName].inZoneDelta = true end else -- Player leaves zone, flag has to set to false once. if player.modules[moduleName].inZoneDelta == true then player.modules[moduleName].inZoneDelta = false end end -- Foxtrott if (player:isInDCSZone("Foxtrott 1") == true or player:isInDCSZone("Foxtrott 2") == true or player:isInDCSZone("Foxtrott 3") == true or player:isInDCSZone("Foxtrott 4") == true or player:isInDCSZone("Foxtrott 5") == true or player:isInDCSZone("Foxtrott 5") == true or player:isInDCSZone("Foxtrott 6") == true) and player.modules[moduleName].coalitionName == "RED" then if player.modules[moduleName].inZoneFoxtrott == false then -- Test the flag to do it once local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas("Foxtrott Quick Response F5", "Foxtrott Quick Response F5" .. math.random(10000)) if err == false then var1:spawn("Golf 3") end -- and just after, set flag to true. player.modules[moduleName].inZoneFoxtrott = true end else -- Player leaves zone, flag has to set to false once. if player.modules[moduleName].inZoneFoxtrott == true then player.modules[moduleName].inZoneFoxtrott = false end end -- Golf if (player:isInDCSZone("Golf 1") == true or player:isInDCSZone("Golf 2") == true) and player.modules[moduleName].coalitionName == "RED" then if player.modules[moduleName].inZoneGolf == false then -- Test the flag to do it once local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas("Golf Quick Response F5", "Golf Quick Response F5" .. math.random(10000)) if err == false then var1:spawn("Golf 3") end -- and just after, set flag to true. player.modules[moduleName].inZoneGolf = true end else -- Player leaves zone, flag has to set to false once. if player.modules[moduleName].inZoneGolf == true then player.modules[moduleName].inZoneGolf = false end end -- Hotel if (player:isInDCSZone("Hotel 1") == true or player:isInDCSZone("Hotel 2") == true or player:isInDCSZone("Hotel 3") == true or player:isInDCSZone("Hotel 4") == true) and player.modules[moduleName].coalitionName == "BLUE" then if player.modules[moduleName].inZoneHotel == false then -- Test the flag to do it once local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas("Hotel Quick Response M21B", "Hotel Quick Response M21B" .. math.random(10000)) if err == false then var1:spawn("Hotel 3") end -- and just after, set flag to true. player.modules[moduleName].inZoneHotel = true end else -- Player leaves zone, flag has to set to false once. if player.modules[moduleName].inZoneHotel == true then player.modules[moduleName].inZoneHotel = false end end -- India if (player:isInDCSZone("India 1") == true or player:isInDCSZone("India 2") == true or player:isInDCSZone("India 3") == true) and player.modules[moduleName].coalitionName == "BLUE" then if player.modules[moduleName].inZoneIndia == false then -- Test the flag to do it once local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas("India Quick Response M21B", "India Quick Response M21B" .. math.random(10000)) if err == false then var1:spawn("India 2") end -- and just after, set flag to true. player.modules[moduleName].inZoneIndia = true end else -- Player leaves zone, flag has to set to false once. if player.modules[moduleName].inZoneIndia == true then player.modules[moduleName].inZoneIndia = false end end -- Juliett if player:isInDCSZone("Juliett") == true and player.modules[moduleName].coalitionName == "BLUE" then if player.modules[moduleName].inZoneJuliett == false then -- Test the flag to do it once local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas("Juliett Quick Response M21B", "Juliett Quick Response M21B" .. math.random(10000)) if err == false then var1:spawn("Mike") end -- and just after, set flag to true. player.modules[moduleName].inZoneJuliett = true end else -- Player leaves zone, flag has to set to false once. if player.modules[moduleName].inZoneJuliett == true then player.modules[moduleName].inZoneJuliett = false end end end -- MAIN do local newHandlers = { onCreatePlayerHandler = onCreatePlayer, onDeletePlayerHandler = nil, onUpdatePlayerHandler = onZonePass, onTakeoffPlayerHandler = nil, onLandingPlayerHandler = nil, onStartEnginePlayerHandler = nil, onStopEnginePlayerHandler = nil, onCreateAIUnitHandler = nil, onDeleteAIUnitHandler = nil, onDisableAIUnitHandler = nil, onTakeoffAIUnitHandler = nil, onLandingAIUnitHandler = nil, onStartEngineAIUnitHandler = nil, onStopEngineAIUnitHandler = nil, onCreateGroupHandler = nil, onDeleteGroupHandler = nil, onDisableGroupHandler = nil, onCreateStaticObjectHandler = nil, onDeleteStaticObjectHandler = nil, onTimerHandler = nil, onModuleStartHandler = nil, } thisModule = ATME.C_Module(moduleName, newHandlers, true) end I know sunski is watching so if you have an idea mate i'll take it :p Link to comment Share on other sites More sharing options...
feefifofum Posted March 8, 2017 Share Posted March 8, 2017 You can create polygonal zones using units in both MOOSE and MIST...I imagine ATME also has a function for this. Generally it's done using either a plane's route or a set of ground units to define the borders of the area. THE GEORGIAN WAR - OFFICIAL F-15C DLC Link to comment Share on other sites More sharing options...
ked Posted March 8, 2017 Author Share Posted March 8, 2017 Sunski confirmed me that polygonal zones are not possible to create with ATME. I'm not sure about using MIST or MOOSE with ATME, will the zone be recognized in my ATME then ? will the mission be stable enough with 10 players ? anyway i need to clean up that code which is pretty heavy and not optimised. So i'm focused on getting the zone the player is in right now rather than seaching zones for the player. Now if adding another library doesn't slow it down i might do that aswell Link to comment Share on other sites More sharing options...
sunski34 Posted March 9, 2017 Share Posted March 9, 2017 (edited) Concerning polygons, yes ATME doesn't support it actually. The problem is spawning surely a group inside a complex polygon. ATME can work with MIST but with MOOSE I don't know. I understood in Mist lua code that Mist tries random several times and test if point is inside a polygon. I know it's possible to be sure that random point will be in complex polygon but code isn't easy and needs a lot of tests. Concerning lags, when you spawn groups you can have lags, not at each time but sometimes. There's no link between lags and menus. So lags is not an ATME problem (if you only have 3 players), but I'm interesting to have your DCS log file to be sure. Of course having more ram is better. Concerning your code : ATME has ATME.C_Area class which can help you to simplify your code. You can create several areas, each area can include several DCS zones. link here https://forums.eagle.ru/showpost.php?p=3039210&postcount=42 So for example : if (player:isInDCSZone("Bravo 1") == true or player:isInDCSZone("Bravo 2") == true or player:isInDCSZone("Bravo 3") == true or player:isInDCSZone("Bravo 4") == true or player:isInDCSZone("Bravo 5") == true or player:isInDCSZone("Bravo 6") == true) and player.modules[moduleName].coalitionName == "BLUE" then can be replace by : local bravoArea = ATME.C_Area() bravoArea:add("Bravo 1") bravoArea:add("Bravo 2") bravoArea:add("Bravo 3") bravoArea:add("Bravo 4") bravoArea:add("Bravo 5") bravoArea:add("Bravo 6") if player:isInArea(bravoArea) == true and player.modules[moduleName].coalitionName == "BLUE" then bravoArea can be a player, global or local variable of course. Another possibility is to link player (or player group) and area , link here :https://forums.eagle.ru/showpost.php?p=3069903&postcount=55 This can be done in onCreatePlayer function for example : local bravoArea = ATME.C_Area() bravoArea:add("Bravo 1") bravoArea:add("Bravo 2") bravoArea:add("Bravo 3") bravoArea:add("Bravo 4") bravoArea:add("Bravo 5") bravoArea:add("Bravo 6") -- Link player and area bravoArea:setAircraftTracking(player) and in your function onZonePass just use events parameter : for _id, _ in events:pairs() do if events:isCoreEvent(_id) == true then local typeEvent = events:getCoreEventType(_id) if typeEvent == "AREA_AIRCRAFT_ENTERS" then local datas = events:getCoreEventDatas(_id) -- player is in datas.unit variable -- area is in datas.area variable local player = datas.unit player:display("Player " .. player:getPseudo() .. " in Bravo zone", 5) elseif typeEvent == "AREA_AIRCRAFT_LEAVES" then local datas = events:getCoreEventDatas(_id) -- player is in datas.unit variable -- area is in datas.area variable local player = datas.unit player:display("Player " .. player:getPseudo() .. " leaves Bravo zone", 5) end end end I didn't test that code above but I think it works if I didn't make stupid mistake ;) So you have several possibilies to simplify your code using ATME.C_Area class, even if you want to spawn in a area you can use : datas:spawn(bravoArea) So ATME.C_Area class is not completly finished but I'm sure it's the best way to do what you want. Hope that help ! Sunski Edited March 9, 2017 by sunski34 Link to comment Share on other sites More sharing options...
ked Posted March 9, 2017 Author Share Posted March 9, 2017 Hey thanks it helps a lot, right now i'm also looking to know which zone he enters so if i do local function init() ATME.modules[moduleName].BravoArea = ATME.C_Area() ATME.modules[moduleName].BravoArea:add("Bravo 1") ATME.modules[moduleName].BravoArea:add("Bravo 2") ATME.modules[moduleName].BravoArea:add("Bravo 3") ATME.modules[moduleName].BravoArea:add("Bravo 4") ATME.modules[moduleName].BravoArea:add("Bravo 5") ATME.modules[moduleName].BravoArea:add("Bravo 6") ATME.modules[moduleName].CharlieArea = ATME.C_Area() ATME.modules[moduleName].CharlieArea:add("Charlie 1") ATME.modules[moduleName].CharlieArea:add("Charlie 2") ATME.modules[moduleName].CharlieArea:add("Charlie 3") ATME.modules[moduleName].CharlieArea:add("Charlie 4") ATME.modules[moduleName].CharlieArea:add("Charlie 5") ATME.modules[moduleName].CharlieArea:add("Charlie 6") ATME.modules[moduleName].DeltaArea = ATME.C_Area() ATME.modules[moduleName].DeltaArea:add("Delta") ATME.modules[moduleName].FoxtrottArea = ATME.C_Area() ATME.modules[moduleName].FoxtrottArea:add("Foxtrott 1") ATME.modules[moduleName].FoxtrottArea:add("Foxtrott 2") ATME.modules[moduleName].FoxtrottArea:add("Foxtrott 3") ATME.modules[moduleName].FoxtrottArea:add("Foxtrott 4") ATME.modules[moduleName].FoxtrottArea:add("Foxtrott 5") ATME.modules[moduleName].FoxtrottArea:add("Foxtrott 6") ATME.modules[moduleName].GolfArea = ATME.C_Area() ATME.modules[moduleName].GolfArea:add("Golf 1") ATME.modules[moduleName].GolfArea:add("Golf 2") ATME.modules[moduleName].HotelArea = ATME.C_Area() ATME.modules[moduleName].HotelArea:add("Hotel 1") ATME.modules[moduleName].HotelArea:add("Hotel 2") ATME.modules[moduleName].HotelArea:add("Hotel 3") ATME.modules[moduleName].HotelArea:add("Hotel 4") ATME.modules[moduleName].IndiaArea = ATME.C_Area() ATME.modules[moduleName].IndiaArea:add("India 1") ATME.modules[moduleName].IndiaArea:add("India 2") ATME.modules[moduleName].IndiaArea:add("India 3") ATME.modules[moduleName].JuliettArea = ATME.C_Area() ATME.modules[moduleName].JuliettArea:add("Juliett") end On module start, then i'd like to be able to know which zone the player enters, maybe with datas.area ? i couldnt find any doc about that :( Thanks for the help Link to comment Share on other sites More sharing options...
sunski34 Posted March 10, 2017 Share Posted March 10, 2017 (edited) Hi ked, Your onZonePass function callback have to be changed to an onTimerHandler, no needs to use onUpdatePlayerHandler in that case because event core for areas have player (or AI unit) instance in their datas. So : -- MAIN do local newHandlers = { onCreatePlayerHandler = onCreatePlayer, onDeletePlayerHandler = nil, onUpdatePlayerHandler = nil, onTakeoffPlayerHandler = nil, onLandingPlayerHandler = nil, onStartEnginePlayerHandler = nil, onStopEnginePlayerHandler = nil, onCreateAIUnitHandler = nil, onDeleteAIUnitHandler = nil, onDisableAIUnitHandler = nil, onTakeoffAIUnitHandler = nil, onLandingAIUnitHandler = nil, onStartEngineAIUnitHandler = nil, onStopEngineAIUnitHandler = nil, onCreateGroupHandler = nil, onDeleteGroupHandler = nil, onDisableGroupHandler = nil, onCreateStaticObjectHandler = nil, onDeleteStaticObjectHandler = nil, onTimerHandler = onZonePass, onModuleStartHandler = init, } thisModule = ATME.C_Module(moduleName, newHandlers, true) end You have an example of using events for entering and leaving areas here : https://forums.eagle.ru/showpost.php?p=3069903&postcount=55 You just have to change setAircraftsGroupTracking by setAircraftTracking as explained above. For your areas I suggest you to put them in a table in onStartHandler but do not forgot the parameter. This callback is called twice when ATME starts : Once before units and players initialized, in that case parameter will be false, Once after, parameter is true. So if you don't use the parameter, your code will be executed twice. So : local function init(areUnitsAndPlayersInitialized) -- Do not forgot parameter onStartHandler if areUnitsAndPlayersInitialized == true then --players and units mission datas are initialized ATME.modules[moduleName].areas = {} ATME.modules[moduleName].areas[1] = { area = ATME.C_Area(), name = "Bravo", } ATME.modules[moduleName].areas[1].area:add("Bravo 1") ... ATME.modules[moduleName].areas[2] = { area = ATME.C_Area(), name = "Charlie", } ATME.modules[moduleName].areas[2].area:add("Charlie 1") ... ... end end in onCreatePlayer callback function, add : -- Link player and areas ATME.modules[moduleName].areas[1].area:setAircraftTracking(player) ATME.modules[moduleName].areas[2].area:setAircraftTracking(player) ... -- for all your areas then in onZonePass add code below (now only one parameter because onTimerHandler). To find the good area then do a loop. So, finally : local function onZonePass(events) for _id, _ in events:pairs() do if events:isCoreEvent(_id) == true then local typeEvent = events:getCoreEventType(_id) if typeEvent == "AREA_AIRCRAFT_ENTERS" then local datas = events:getCoreEventDatas(_id) -- player is in datas.unit variable -- area is in datas.area variable local player = datas.unit -- loop on your areas here when player enters a zone for _i = 1, #ATME.modules[moduleName].areas do if ATME.modules[moduleName].areas[i].area == datas.area then if ATME.modules[moduleName].areas[i].name == "Bravo" then -- Code when player enters Bravo Area elseif .... -- Test other area names and add specific code end end end elseif typeEvent == "AREA_AIRCRAFT_LEAVES" then local datas = events:getCoreEventDatas(_id) -- player is in datas.unit variable -- area is in datas.area variable local player = datas.unit -- loop on your areas here when player leaves a zone for _i = 1, #ATME.modules[moduleName].areas do if ATME.modules[moduleName].areas[i].area == datas.area then if ATME.modules[moduleName].areas[i].name == "Bravo" then -- Code when player leaves Bravo Area elseif .... -- Test other area names and add specific code end end end end end end end events parameter of onTimer callback function (or onZonePass in your case) contains all core events and user trigger events which has been fired by ATME since last timer trigger. It's a particular table. Of course, if player (or AI unit or group) has been killed or desactivated since the last call, the core event isn't in the table anymore ; in that case, core event has been delete. All core events have a player, an AI unit or a group in theirs datas depending of their type. If unit (player or AI unit), you may test if unit is ATME.C_Player or ATME.C_AIUnit in your code if necessary, in your case all units are players, so no test. Note that instances of ATME.C_Area class will have their own name in next version to find directly an area by its name, so, that will be easier soon. Of course, in documentation, you will find functions using core events and ATME.C_Area class. And you can find French doc p54, English doc p51, the Module 4 which explains how to use Core events. My answer is just a example of a particular Core event Sunski. Edited March 11, 2017 by sunski34 Link to comment Share on other sites More sharing options...
ked Posted March 10, 2017 Author Share Posted March 10, 2017 (edited) Ok thanks for the help i've got this error 02560.326 ERROR DCS: Mission script error: : [string "C:\Users\kedke\AppData\Local\Temp\DCS\/~mis00003ECC"]:96: attempt to index field 'areas' (a nil value) stack traceback: [C]: ? [string "C:\Users\kedke\AppData\Local\Temp\DCS\/~mis00003ECC"]:96: in function 'onCreatePlayerHandler' [string "C:\Users\kedke\AppData\Local\Temp\DCS\/~mis00005421"]:8772: in function 'C_Player_create' [string "C:\Users\kedke\AppData\Local\Temp\DCS\/~mis00005421"]:12265: in function 'run' [string "ATME.run("FR")"]:1: in main chunk On the particular line ATME.modules[moduleName].areas[1].area:setAircraftTracking(player) full code is local thisModule local moduleName = "QuickResponse" local function init(areUnitsAndPlayersInitialized) if areUnitsAndPlayersInitialized == true then ATME.modules[moduleName].areas = {} ATME.modules[moduleName].areas[1] = { area = ATME.C_Area(), name = "Bravo", spawn = "Bravo 1", } ATME.modules[moduleName].areas[2] = { area = ATME.C_Area(), name = "Charlie", spawn = "Delta", } ATME.modules[moduleName].areas[3] = { area = ATME.C_Area(), name = "Delta", spawn = "Delta", } ATME.modules[moduleName].areas[4] = { area = ATME.C_Area(), name = "Foxtrott", spawn = "Golf 3", } ATME.modules[moduleName].areas[5] = { area = ATME.C_Area(), name = "Golf", spawn = "Golf 3", } ATME.modules[moduleName].areas[6] = { area = ATME.C_Area(), name = "Hotel", spawn = "Hotel 3", } ATME.modules[moduleName].areas[7] = { area = ATME.C_Area(), name = "India", spawn = "India 2" } ATME.modules[moduleName].areas[8] = { area = ATME.C_Area(), name = "Juliett", spawn = "Mike" } ATME.modules[moduleName].responses = {} ATME.modules[moduleName].responses[1] = { old = "M21B" } ATME.modules[moduleName].responses[2] = { old = "F5" } ATME.modules[moduleName].areas[1].area:add("Bravo 1") ATME.modules[moduleName].areas[1].area:add("Bravo 2") ATME.modules[moduleName].areas[1].area:add("Bravo 3") ATME.modules[moduleName].areas[1].area:add("Bravo 4") ATME.modules[moduleName].areas[1].area:add("Bravo 5") ATME.modules[moduleName].areas[1].area:add("Bravo 6") ATME.modules[moduleName].areas[2].area:add("Charlie 1") ATME.modules[moduleName].areas[2].area:add("Charlie 2") ATME.modules[moduleName].areas[2].area:add("Charlie 3") ATME.modules[moduleName].areas[2].area:add("Charlie 4") ATME.modules[moduleName].areas[2].area:add("Charlie 5") ATME.modules[moduleName].areas[2].area:add("Charlie 6") ATME.modules[moduleName].areas[3].area:add("Delta") ATME.modules[moduleName].areas[4].area:add("Foxtrott 1") ATME.modules[moduleName].areas[4].area:add("Foxtrott 2") ATME.modules[moduleName].areas[4].area:add("Foxtrott 3") ATME.modules[moduleName].areas[4].area:add("Foxtrott 4") ATME.modules[moduleName].areas[4].area:add("Foxtrott 5") ATME.modules[moduleName].areas[4].area:add("Foxtrott 6") ATME.modules[moduleName].areas[5].area:add("Golf 1") ATME.modules[moduleName].areas[5].area:add("Golf 2") ATME.modules[moduleName].areas[6].area:add("Hotel 1") ATME.modules[moduleName].areas[6].area:add("Hotel 2") ATME.modules[moduleName].areas[6].area:add("Hotel 3") ATME.modules[moduleName].areas[6].area:add("Hotel 4") ATME.modules[moduleName].areas[7].area:add("India 1") ATME.modules[moduleName].areas[7].area:add("India 2") ATME.modules[moduleName].areas[7].area:add("India 3") ATME.modules[moduleName].areas[8].area:add("Juliett") end end local function onCreatePlayer(player) ATME.modules[moduleName].areas[1].area:setAircraftTracking(player) ATME.modules[moduleName].areas[2].area:setAircraftTracking(player) ATME.modules[moduleName].areas[3].area:setAircraftTracking(player) ATME.modules[moduleName].areas[4].area:setAircraftTracking(player) ATME.modules[moduleName].areas[5].area:setAircraftTracking(player) ATME.modules[moduleName].areas[6].area:setAircraftTracking(player) ATME.modules[moduleName].areas[7].area:setAircraftTracking(player) ATME.modules[moduleName].areas[8].area:setAircraftTracking(player) player.modules[moduleName].coalitionName = player:getCoalitionName() player.modules[moduleName].coalitionNumber = nil if player.modules[moduleName].coalitionName == "BLUE" then player.modules[moduleName].coalitionNumber = 1 else player.modules[moduleName].coalitionNumber = 2 end end local function onZonePass(events) for _id, _ in events:pairs() do if events:isCoreEvent(_id) == true then local typeEvent = events:getCoreEventType(_id) if typeEvent == "AREA_AIRCRAFT_ENTERS" then local datas = events:getCoreEventDatas(_id) -- player is in datas.unit variable -- area is in datas.area variable local player = datas.unit -- loop on your areas here when player enters a zone for _i = 1, #ATME.modules[modulesName].areas do if ATME.modules[modulesName].areas[i].area == datas.area then local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas(ATME.modules[modulesName].areas[i].name+" Quick Response "+ATME.modules[moduleName].responses[player.modules[moduleName].coalitionNumber].old, ATME.modules[modulesName].areas[i].name+" Quick Response "+ATME.modules[moduleName].responses[player.modules[moduleName].coalitionNumber].old .. math.random(10000)) player:display("areas.area = datas.area",5) if err == false then var1:spawn(ATME.modules[modulesName].areas[i].spawn) player:display("Spawn "+ATME.modules[modulesName].areas[i].name+" Quick Response "+ATME.modules[moduleName].responses[player.modules[moduleName].coalitionNumber].old,5) end end end elseif typeEvent == "AREA_AIRCRAFT_LEAVES" then local datas = events:getCoreEventDatas(_id) -- player is in datas.unit variable -- area is in datas.area variable local player = datas.unit -- loop on your areas here when player leaves a zone -- nothing planned for this at the moment --for _i = 1, #ATME.modules[modulesName].areas do -- if ATME.modules[modulesName].areas[i].area == datas.area then -- if ATME.modules[modulesName].areas[i].name == "Bravo" then -- Code when player leaves Bravo Area -- elseif .... -- Test other area names and add specific code -- end -- end --end end end end end -- MAIN do local newHandlers = { onCreatePlayerHandler = onCreatePlayer, onDeletePlayerHandler = nil, onUpdatePlayerHandler = nil, onTakeoffPlayerHandler = nil, onLandingPlayerHandler = nil, onStartEnginePlayerHandler = nil, onStopEnginePlayerHandler = nil, onCreateAIUnitHandler = nil, onDeleteAIUnitHandler = nil, onDisableAIUnitHandler = nil, onTakeoffAIUnitHandler = nil, onLandingAIUnitHandler = nil, onStartEngineAIUnitHandler = nil, onStopEngineAIUnitHandler = nil, onCreateGroupHandler = nil, onDeleteGroupHandler = nil, onDisableGroupHandler = nil, onCreateStaticObjectHandler = nil, onDeleteStaticObjectHandler = nil, onTimerHandler = onZonePass, onModuleStartHandler = init, } thisModule = ATME.C_Module(moduleName, newHandlers, true) end i don't really get what's wrong, units and players might now be initialized when the init function executes EDIT: I've checked logs and the first error i have is 02437.327 INFO SCRIPTING: [ATME] - Init starts - version V1.0.11 beta 02437.329 INFO SCRIPTING: [ATME] - Init ok - Theatre : CAUCASUS 02455.780 ERROR DCS: Mission script error: : [string "C:\Users\kedke\AppData\Local\Temp\DCS\/~mis00003C72"]:106: 'then' expected near '=' on the line if player.modules[moduleName].coalitionName == "BLUE" then makes no sense Edited March 10, 2017 by ked Link to comment Share on other sites More sharing options...
sunski34 Posted March 11, 2017 Share Posted March 11, 2017 (edited) Hi, I see ... You have to initialize your module variables (areas) before creating player. As I said, init function (linked with onStartHandler) will be called twice, once before players initialized (for player in cockpit at start of mission, at least one) and once after. So, you have to change : if areUnitsAndPlayersInitialized == true then inif areUnitsAndPlayersInitialized == false then then your variables will be initialized before onCreatePlayer will be called. To understand, let me explain a little bit how that works in lua: When starting a mission, there's two possibilities with players : Players who are already in mission when ATME starts. So in that case, onCreatePlayerHandler will be called during the start of ATME Players who will enter DCS later, so of course, nothing is done when ATME starts. But, onStartHandler may help you to prepare some necessary code (depending of what you want to do) and in that case two possibilities : If what you do in your code is necessary for all players and units (example specific variables), and will be used in onCreate...Handler (AIUnit, Player or Groups), you have to set them before players and AI units initializations so onStartHandler areUnitsAndPlayersInitialized parameter will be test to false. If what you do in your code is not necessary for onCreate...Handler or need players and AI Units to be initialized, then, no problem, onStartHandler areUnitsAndPlayersInitialized parameter will be test to true. Of course you can do a mix. Edited March 11, 2017 by sunski34 Link to comment Share on other sites More sharing options...
sunski34 Posted March 11, 2017 Share Posted March 11, 2017 (edited) I see another problem with : var1:spawn(ATME.modules[modulesName].areas[i].spawn) That isn't good. Replace with : var1:spawn(ATME.modules[modulesName].areas[i].area) if you want to spawn anywhere in the area (random in all DCSZones defined in an area) except if you want to spawn in DCSZone called ATME.modules[modulesName].areas.spawn, that's isn't the same ! More information : If you don't need to know really the area, you can delete the loop and use directly datas.area like this : var1:spawn(datas.area) see here : https://forums.eagle.ru/showpost.php?p=3073466&postcount=11 in that thread Edited March 11, 2017 by sunski34 Link to comment Share on other sites More sharing options...
ked Posted March 11, 2017 Author Share Posted March 11, 2017 var1:spawn(ATME.modules[modulesName].areas[i].spawn) i dont see why it wouldn't work knowing the fact that i used to do this: if err == false then var1:spawn("Bravo 1") end "Bravo 1" is just a String, just like my spawn value in the areas table. Either way, it's still not working and i've got no idea why. I'll post the entire dcs.log because i see something weird, this line comes twice 00791.925 INFO SCRIPTING: [ATME] - Init starts - version V1.0.11 beta 00791.928 INFO SCRIPTING: [ATME] - Init ok - Theatre : CAUCASUS Once on the begining of the file and once way later when everything is supposed to be init for a long time. Link to comment Share on other sites More sharing options...
ked Posted March 11, 2017 Author Share Posted March 11, 2017 And this loop isn't executing once (i've tried to add player:display and nothing shows up) for _i = 1, #ATME.modules[modulesName].areas do player:display("blblblblbl",5) if ATME.modules[modulesName].areas[i].area == datas.area then local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas(ATME.modules[modulesName].areas[i].name+" Quick Response "+ATME.modules[moduleName].responses[player.modules[moduleName].coalitionNumber].old, ATME.modules[modulesName].areas[i].name+" Quick Response "+ATME.modules[moduleName].responses[player.modules[moduleName].coalitionNumber].old .. math.random(10000)) if err == false then var1:spawn(ATME.modules[modulesName].areas[i].spawn) player:display("Spawn "+ATME.modules[modulesName].areas[i].name+" Quick Response "+ATME.modules[moduleName].responses[player.modules[moduleName].coalitionNumber].old,5) end end end Link to comment Share on other sites More sharing options...
sunski34 Posted March 11, 2017 Share Posted March 11, 2017 (edited) Yes, documentation is not complete for spawn function : var1:spawn("Bravo 1") In that case spawn a group somewhere in DCS zone 'Bravo 1' var1:spawn(area) If area is an instance of ATME.C_Area then spawn somewhere in the area (even if area has several zones defined). So you can spawn at a point, somewhere in a DCSZone or somewhere in a defined area. For your second problem with loop, strange, can you send me your mission and lua file. Did you try display outside the loop ? You have to see message when player enters area (just enters not in area, state change) Edited March 11, 2017 by sunski34 Link to comment Share on other sites More sharing options...
ked Posted March 11, 2017 Author Share Posted March 11, 2017 You can download it here : http://gamers-squad.fr/public/training%20V1.1.5.zip ATME core seems to init in a loop according to my logs (like 3-4 times in less than a minute) and i can't acces the ATME.modules[moduleName].areas when i try to do for exemple player:display(ATME.modules[moduleName].areas[3].name,5) I've got no display Link to comment Share on other sites More sharing options...
sunski34 Posted March 11, 2017 Share Posted March 11, 2017 (edited) In my loop modulesName is bad, it's moduleName, moduleName is a global variable : so for _i = 1, #ATME.modules[modulesName].areas do and forward must be modified with moduleName (no s between module and Name) ; for _i = 1, #ATME.modules[moduleName].areas do Then that works. modulesName is not a defined variable so, that's why the loop didn't work. It's a lua problem, so be careful with that. onTimer is a function callback by a timer so no error in that case too. I modified my answer : https://forums.eagle.ru/showpost.php?p=3074739&postcount=13 Hope that helps Sunski Edited March 11, 2017 by sunski34 Link to comment Share on other sites More sharing options...
ked Posted March 11, 2017 Author Share Posted March 11, 2017 Damn i read the code 100 times and didn't find that ... :( It still doesn't spawn units here, seems to do only one iteration in the loop And in my logs i've got 36 times this thing appearing SCRIPTING: [ATME] - Init starts - version V1.0.11 beta for like 25 seconds of gameplay, seems weird. Isn't it supposed to happen once ? Link to comment Share on other sites More sharing options...
ked Posted March 11, 2017 Author Share Posted March 11, 2017 Ok i've got it working doing for i = 1,8,1 do if ATME.modules[moduleName].areas[i].area == datas.area then local err, var1 = ATME.C_GroupSpawnDatas.duplicateFromMissionDatas(ATME.modules[moduleName].areas[i].name .. " Quick Response " .. ATME.modules[moduleName].responses[player.modules[moduleName].coalitionNumber].old, ATME.modules[moduleName].areas[i].name .. " Quick Response " .. ATME.modules[moduleName].responses[player.modules[moduleName].coalitionNumber].old .. math.random(10000)) if err == false then var1:spawn(ATME.modules[moduleName].areas[i].spawn) else player:display("error spawn in " .. ATME.modules[moduleName].areas[i].spawn,5) end break end end Link to comment Share on other sites More sharing options...
sunski34 Posted March 11, 2017 Share Posted March 11, 2017 it has to work with for _i = 1, #ATME.modules[moduleName].areas do too it's the same #ATME.modules[moduleName].areas = 8 Link to comment Share on other sites More sharing options...
ked Posted March 11, 2017 Author Share Posted March 11, 2017 Another question :p Let's say i do var1:spawn(ATME.modules[moduleName].areas[i].spawn) And i want to set a global variable for that AI unit, i've tried to do var1.modules[moduleName].variable = value But it's not working. What is exactly var1 ? Link to comment Share on other sites More sharing options...
Recommended Posts