Jump to content

CAP not following flight plan


ked

Recommended Posts

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

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

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! :)

Link to comment
Share on other sites

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 by sunski34
Link to comment
Share on other sites

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

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

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 by sunski34
Link to comment
Share on other sites

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

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 by sunski34
Link to comment
Share on other sites

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 by ked
Link to comment
Share on other sites

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

 

in

if 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 by sunski34
Link to comment
Share on other sites

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 by sunski34
Link to comment
Share on other sites

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

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

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 by sunski34
Link to comment
Share on other sites

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 by sunski34
Link to comment
Share on other sites

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

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

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

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...