Jump to content

MOOSE - Mission Object Oriented Scripting Framework


Recommended Posts

I think your basic problem is that you can not spawn a set, only statics, groups or units; so you need code that extracts the groups from the set and then spawns them. Perhaps someone else can provide more specifics.

 

Yeah, i think you're right, so i've tried this but had no luck... still something wrong

 

local RecceSet = SET_GROUP:New():FilterPrefixes('RECCE'):FilterCoalitions("blue"):FilterStart()

local function confRecce()

 RecceSet:ForEachGroup(
 
   function(RecceSet)
     local RespawnReaper = SPAWN:New():InitLimit(1,1)
           RespawnReaper:InitRepeatOnLanding()
           RespawnReaper:InitDelayOff()
           RespawnReaper:SpawnScheduled(60,0)
     end
 )
end

--

[sIGPIC][/sIGPIC]

36° Stormo Virtuale - Italian Virtual Flight Community

www.36stormovirtuale.net

Link to comment
Share on other sites

i have to try this, maybe it will work...

 

local RecceSet = SET_GROUP:New():FilterPrefixes('RECCE'):FilterCoalitions("blue"):FilterStart()

Recceset:ForEachGroup( 

	function (group)
		local SpawnRecce = SPAWN:New(group)
		:InitLimit(1,0)
		:InitRepeatOnLanding()
		:InitDelayOff()
		:SpawnScheduled(60,0)
	end
	)


Edited by Kappa

--

[sIGPIC][/sIGPIC]

36° Stormo Virtuale - Italian Virtual Flight Community

www.36stormovirtuale.net

Link to comment
Share on other sites

@Kappa

 

Unless ED has changed the way this works, you can't form sets of unspawned groups/units (except for clients)

 

Just think about it, RecceSet won't be populated until the late-activated groups are spawned, therefore, if you put the SPAWN object declaration inside the for loop (:ForEachGroup), nothing will be spawned.

 

First you need to define the SPAWN object(s), then you need to spawn them, so they can be included in the set.

 

 

Also, I think that prefix and coalition filters conflict with each other, I'd recommend getting rid of the coalition filter and adding an active filter instead.

 

Like this:

RecceSet = SET_GROUP:New():FilterActive(Active):FilterPrefixes('RECCE'):FilterOnce()

 

 

 

You'll also need to put this set declaration inside a scheduler, though, otherwise it won't update as groups spawn and die.

 

 

Like this:

local function Set_Updater()

  RecceSet = SET_GROUP:New():FilterActive(true):FilterPrefixes('RECCE'):FilterOnce()
  
  return timer.getTime() + 60
end

timer.scheduleFunction(Set_Updater, nil, timer.getTime() + 1)

 

 

Or even better, just put it inside a function that will be called whenever you need to have the set updated:

 

local function Update_Set()

    RecceSet = SET_GROUP:New():FilterActive(Active):FilterPrefixes('RECCE'):FilterOnce()
    
    return RecceSet 
end

Update_Set() [color="Blue"]-- Use this to call the set update function[/color]


[color="Blue"]-- You can also store the updated set in a variable, like this:[/color]

local Updated_Set = Update_Set()

 

 

Anyway, all that jazz is just so you know how to work with sets...

 

 

Truth is that you can achieve the behaviour you're looking for without using SET_GROUPs.

 

Here, this script should have you covered (you just need to introduce the names of the late-activated group templates you're interested in, the location is marked in red):

 

 

local Groupname_Table = {[color="Red"]'RECCE-REAPER #001', 'RECCE-REAPER #002', 'RECCE-REAPER #003', 'RECCE-REAPER #004', 'RECCE-KIOWA #001', 'RECCE-KIOWA #002'[/color]}

local Spawned_Group_Table = {}

local Spawn_Object_Table = {}


for i, Group_Name in ipairs(Groupname_Table) do
   
   Spawn_Object_Table[i] = SPAWN:New(Group_Name)
   :InitLimit(1,10) [color="Blue"]-- Tweak the max unit and max respawn values as desired[/color]
   :OnSpawnGroup(
   function(grp) 

      table.insert(Spawned_Group_Table, grp)   
   end
   )  
end


local function Spawner()
     
     for k, Spawn_Object in ipairs(Spawn_Object_Table) do
         
         Spawn_Object:Spawn()
     end
end

Spawner()

local function Update_Group_Table()

     for j, Spawn_Group in ipairs(Spawned_Group_Table) do
  
         if Spawn_Group and Spawn_Group:IsAlive() == nil then
            j = nil
         end 
     end
end


Land_Event_Handler = EVENTHANDLER:New()

Land_Event_Handler:HandleEvent(EVENTS.Land)

function Land_Event_Handler:OnEventLand(EventData)
        
        Update_Group_Table() 
        
        for h, Spawn_Group in ipairs(Spawned_Group_Table) do
 
            if Spawn_Group and EventData.IniUnit:GetGroup() == Spawn_Group then

               EventData.IniUnit:Destroy() [color="Blue"]-- Use this line if you want to remove the spawned units when they land. Also comes in handy when you set [i][b]InitLimit[/b][/i] to 1 unit max per spawn group[/color] 
               
               Spawner()
            end
        end
end

 


Edited by Hardcard
Link to comment
Share on other sites

@Kappa

 

Unless ED has changed the way this works, you can't form sets of unspawned groups/units (except for clients)

 

Just think about it, RecceSet won't be populated until the late-activated groups are spawned, therefore, if you put the SPAWN object declaration inside the for loop (:ForEachGroup), nothing will be spawned.

 

First you need to define the SPAWN object(s), then you need to spawn them, so they can be included in the set.

 

 

Also, I think that prefix and coalition filters conflict with each other, I'd recommend getting rid of the coalition filter and adding an active filter instead.

 

Like this:

RecceSet = SET_GROUP:New():FilterActive(Active):FilterPrefixes('RECCE'):FilterStart()

 

 

 

You'll also need to put this set declaration inside a scheduler, though, otherwise it won't update as groups spawn and die.

 

 

Like this:

local function Set_Updater()

  RecceSet = SET_GROUP:New():FilterActive(true):FilterPrefixes('RECCE'):FilterStart()
  
  return timer.getTime() + 60
end

timer.scheduleFunction(Set_Updater, nil, timer.getTime() + 1)

 

 

Or even better, just put it inside a function that will be called whenever you need to have the set updated:

 

local function Update_Set()

    RecceSet = SET_GROUP:New():FilterActive(Active):FilterPrefixes('RECCE'):FilterStart()
    
    return RecceSet 
end

Update_Set() [color="Blue"]-- Use this to call the set update function[/color]


[color="Blue"]-- You can also store the updated set in a variable, like this:[/color]

local Updated_Set = Update_Set()

 

 

Anyway, all that jazz is just so you know how to work with sets...

 

 

Truth is that you can achieve the behaviour you're looking for without using SET_GROUPs.

 

Here, this script should have you covered (you just need to introduce the names of the late-activated group templates you're interested in, the location is marked in red):

 

 

local Groupname_Table = {[color="Red"]'RECCE-REAPER #001', 'RECCE-REAPER #002', 'RECCE-REAPER #003', 'RECCE-REAPER #004', 'RECCE-KIOWA #001', 'RECCE-KIOWA #002'[/color]}

local Spawned_Group_Table = {}

local Spawn_Object_Table = {}


for i, Group_Name in ipairs(Groupname_Table) do
   
   Spawn_Object_Table[i] = SPAWN:New(Group_Name)
   :InitLimit(1,10) [color="Blue"]-- Tweak the max unit and max respawn values as desired[/color]
   :OnSpawnGroup(
   function(grp) 

      table.insert(Spawned_Group_Table, grp)   
   end
   )  
end


local function Spawner()
     
     for k, Spawn_Object in ipairs(Spawn_Object_Table) do
         
         Spawn_Object:Spawn()
     end
end

Spawner()

local function Update_Group_Table()

     for j, Spawn_Group in ipairs(Spawned_Group_Table) do
  
         if Spawn_Group and Spawn_Group:IsAlive() == nil then
            j = nil
         end 
     end
end


Land_Event_Handler = EVENTHANDLER:New()

Land_Event_Handler:HandleEvent(EVENTS.Land)

function Land_Event_Handler:OnEventLand(EventData)
        
        Update_Group_Table() 
        
        for h, Spawn_Group in ipairs(Spawned_Group_Table) do
 
            if Spawn_Group and EventData.IniUnit:GetGroup() == Spawn_Group then

               EventData.IniUnit:Destroy() [color="Blue"]-- Use this line if you want to remove the spawned units when they land. Also comes in handy when you set [i][b]InitLimit[/b][/i] to 1 unit max per spawn group[/color] 
               
               Spawner()
            end
        end
end

 

Thank you Hardcard for your detailed reply, very kind of you.

 

I understand what you say, but my goal is to populate SETs (or arrays, or something) from prefixes, without defining all group names in the script manually, and then iterate some commands for each group in the set to make it spawn and cofigure it.

 

So you say, I can't use a GROUP_SET with unspawned groups, can you tell me why the following code works?

 

As you can see I define the RecceSet before to spawn RECCE Groups but in deeds they do their recce job within the Dispatcher :huh:

 

I think it is because a SET get automatically updated...What do you think?

 

Moose docs

https://flightcontrol-master.github.io/MOOSE_DOCS/Documentation/Core.Set.html

Module Core.Set

Core - Define collections of objects to perform bulk actions and logically group objects.

 

Features:

Dynamically maintain collections of objects.

Manually modify the collection, by adding or removing objects.

Collections of different types.

Validate the presence of objects in the collection.

Perform bulk actions on collection.

 

 

 

local HQ = GROUP:FindByName("HQ")

local CommandCenter = COMMANDCENTER:New(HQ , "Senaki HQ" )

local Mission = MISSION:New( CommandCenter , "Overlord" , "Prioritaria" , "Ingaggiare bersagli secondo designazione" , coalition.side.BLUE )

local RecceSet  = SET_GROUP:New():FilterPrefixes("RECCE"):FilterCoalitions("blue"):FilterStart()

 
local DetectionAreas = DETECTION_AREAS:New(RecceSet,5000)

local AttackSet = SET_GROUP:New():FilterCoalitions("blue"):FilterPrefixes("A2G"):FilterStart()



--RECCE RESPAWN
--Respawna i ricognitori (RECCE) quando atterrano
RespawnReaper1 = SPAWN:New('RECCE-REAPER #001'):InitLimit(1,0)
RespawnReaper2 = SPAWN:New('RECCE-REAPER #002'):InitLimit(1,0)
RespawnReaper3 = SPAWN:New('RECCE-REAPER #003'):InitLimit(1,0)
RespawnReaper4 = SPAWN:New('RECCE-REAPER #004'):InitLimit(1,0)

RespawnKiowa1 = SPAWN:New('RECCE-KIOWA #001'):InitLimit(1,0)
RespawnKiowa2 = SPAWN:New('RECCE-KIOWA #002'):InitLimit(1,0)



RespawnReaper1:InitRepeatOnLanding()
RespawnReaper1:InitDelayOff()

RespawnReaper2:InitRepeatOnLanding()
RespawnReaper2:InitDelayOff()

RespawnReaper3:InitRepeatOnLanding()
RespawnReaper3:InitDelayOff()

RespawnReaper4:InitRepeatOnLanding()
RespawnReaper4:InitDelayOff()

RespawnKiowa1:InitRepeatOnLanding()
RespawnKiowa1:InitDelayOff()

RespawnKiowa2:InitRepeatOnLanding()
RespawnKiowa2:InitDelayOff()


RespawnReaper1:SpawnScheduled(60,0)
RespawnReaper2:SpawnScheduled(60,0)
RespawnReaper3:SpawnScheduled(60,0)
RespawnReaper4:SpawnScheduled(60,0)

RespawnKiowa1:SpawnScheduled(60,0)
RespawnKiowa2:SpawnScheduled(60,0)
--END RECCE RESPAWN

TaskDispatcher = TASK_A2G_DISPATCHER:New(Mission,AttackSet,DetectionAreas)

 

 

 


Edited by Kappa

--

[sIGPIC][/sIGPIC]

36° Stormo Virtuale - Italian Virtual Flight Community

www.36stormovirtuale.net

Link to comment
Share on other sites

Ok,

 

i'm reading carefully the documentation.

 

I think SETs get dinamically updated and they get also late activated groups.

 

SET_GROUP.FilterActive: Builds the SET_GROUP with the groups that are only active. Groups that are inactive (late activation) won't be included in the set!

 

So if there is a filter for active groups that mean that by default, all groups (active and inactive) are considerated.

 

 

The problem is the :ForEachGroup...

Iterators works only with alive groups

 

SET_GROUP.ForEachGroup: Calls a function for each alive group it finds within the SET_GROUP.

 

 

There is another way to iterate a group set?

--

[sIGPIC][/sIGPIC]

36° Stormo Virtuale - Italian Virtual Flight Community

www.36stormovirtuale.net

Link to comment
Share on other sites

@Kappa

 

The reason your initial code works is probably because you're using :FilterStart() in your set declaration (this starts a scheduler, if I'm not mistaken, so the set gets updated over time...although it doesn't always work).

 

Since you're also spawning the late-activated groups using :SpawnScheduled(60,0), they are added to the database, then they're found and added to the set when the prefix filter runs again.

 

I'd say that if you do one of the following things, your script will stop working because the set won't be able to find the unspawned groups:

  • Remove :SpawnScheduled(60,0) and dump the set to dcs.log at the end of the script (I predict that it will be empty)
     
     
  • Use :FilterOnce() instead of :FilterStart() in your set declaration, then dump the set to dcs.log at the end of the script (I predict that it will be empty)

 

 

I understand that it's easier to just filter by prefixes and update the set automatically, but when working with late-activated units/groups, they need to be spawned first (unless ED has changed how this works in recent patches)

 

While developing SWAPR, I tried to build sets of groups/units directly from the database, it only worked with clients, regular AI groups/units couldn't be found (regardless of the filter I used).

 

 

In the script example that I posted, I made things really easy, you only need to provide the ME group names of the late-activated TEMPLATE groups.

You don't have to provide the names of all the groups that will be spawned from those (that's handled automatically)

 

For instance, you can have a single late-activated TEMPLATE group named 'RECCE-REAPER #001' in ME, from which you can spawn hundreds of copies using SPAWN class.

In that case you'll only need to add 'RECCE-REAPER #001' to Groupname_Table, the script will take care of the hundreds of copies automatically.

 

 

Happy new year, btw!

:yay:


Edited by Hardcard
Link to comment
Share on other sites

Here is one example:

 

 

mySet_Table = mySet:GetSetObjects() -- Make a table from a set

for i= #mySet_Table, 1, -1 do  -- iterate the table
 if mySet_Table[i] == Some Condition then
    table.remove( mySet_Table, i )
     do stuff, like Target:Destroy()
 break
 end 
end

 

 

Hi Habu and thank you.

 

i've tried this but still no luck, is my syntax correct?

 

function SetScroll ( group )
     local SpawnRecce = SPAWN:New( group )
     :InitLimit(1,0)
     :InitRepeatOnLanding()
     :InitDelayOff()
     :SpawnScheduled(10,0)
end

RecceSetTable = RecceSet:GetSetObjects()

for i = #RecceSetTable, 1, -1 do
 RecceGroup = RecceSetTable[i]
 SetScroll(RecceGroup)
end    

 

 

@Kappa

 

The reason your initial code works is probably because you're using :FilterStart() in your set declaration (this starts a scheduler, if I'm not mistaken, so the set gets updated over time...although it doesn't always work).

 

Since you're also spawning the late-activated groups using :SpawnScheduled(60,0), they are added to the database, then they're found and added to the set when the prefix filter runs again.

 

I'd say that if you do one of the following things, your script will stop working because the set won't be able to find the unspawned groups:

  • Remove :SpawnScheduled(60,0) and dump the set to dcs.log at the end of the script (I predict that it will be empty)
     
     
  • Use :FilterOnce() instead of :FilterStart() in your set declaration, then dump the set to dcs.log at the end of the script (I predict that it will be empty)

 

 

I understand that it's easier to just filter by prefixes and update the set automatically, but when working with late-activated units/groups, they need to be spawned first (unless ED has changed how this works in recent patches)

 

While developing SWAPR, I tried to build sets of groups/units directly from the database, it only worked with clients, regular AI groups/units couldn't be found (regardless of the filter I used).

 

 

In the script example that I posted, I made things really easy, you only need to provide the ME group names of the late-activated TEMPLATE groups.

You don't have to provide the names of all the groups that will be spawned from those (that's handled automatically)

 

For instance, you can have a single late-activated TEMPLATE group named 'RECCE-REAPER #001' in ME, from which you can spawn hundreds of copies using SPAWN class.

In that case you'll only need to add 'RECCE-REAPER #001' to Groupname_Table, the script will take care of the hundreds of copies automatically.

 

 

Happy new year, btw!

:yay:

 

HI Hardcard, can you tell me how to dump the set in dcs.log?

Sorry I am not an expert :)

 

 

 

Happy new year to everybody :D

--

[sIGPIC][/sIGPIC]

36° Stormo Virtuale - Italian Virtual Flight Community

www.36stormovirtuale.net

Link to comment
Share on other sites

@Kappa

 

function SetScroll ( [color="red"]group[/color] )
     local SpawnRecce = SPAWN:New( [color="red"]group[/color] ) [color="Blue"]-- SPAWN:New() requires a [u][i][b]string[/b][/i][/u] as parameter (the template group name in ME), NOT a group object[/color]
     :InitLimit(1,0)
     :InitRepeatOnLanding()
     :InitDelayOff()
     :SpawnScheduled(10,0)
end

RecceSetTable = [color="Red"]RecceSet:GetSetObjects()[/color] [color="Blue"]-- This will return a table containing all GROUP OBJECTS in the set, not their group names[/color]

for i = #RecceSetTable, 1, -1 do
 RecceGroup = RecceSetTable[i] [color="blue"] -- [b]RecceSetTable[i][/b] will return a group object, NOT a group name[/color]
 SetScroll([color="red"]RecceGroup[/color]) [color="Blue"]-- RecceGroup contains a group object, not a group name[/color]
end

[color="blue"]-- In order for RecceGroup to contain the group name, do this instead:[/color]

for i = #RecceSetTable, 1, -1 do
  
  if RecceSetTable[i] and RecceSetTable[i]:GetName() then 
     RecceGroup = RecceSetTable[i]:GetName()
     SetScroll(RecceGroup)
  end
end

[color="Blue"]-- Note that this script will only work if RecceSet is populated... if the set is empty, it won't work.[/color]

 

 

I'll run some tests, see if late-activated groups are reachable, things might've changed since I last tried this...

 

 

UPDATE: As I suspected, late-activated group templates can't be reached by SET_GROUPs when declared in the usual way... however, I've found a solution.

 

In order for late-activated group templates to be reachable by SET_GROUPs, you'll need to get them directly from a database object.

 

Here's how you need to declare the SET_GROUP (required parameter marked in red):

 

RecceSET = SET_GROUP:New(DATABASE:New()):FilterPrefixes('[color="Red"]Chosen common prefix/suffix in ME[/color]'):FilterOnce()

 

This set will include ALL objects in the mission (late-activated or not) whose names contain the specified prefix/suffix.

 

Once the set has been properly declared, you can get the table containing all set object names, which you will need for the SPAWN object declarations:

 

local Groupname_Table = RecceSET:GetSetNames() 

 

 

You can apply this to your initial script, or simply use the script I wrote (updated & tested):

 

RecceSET = SET_GROUP:New(DATABASE:New()):FilterPrefixes('[color="Red"]common prefix/suffix[/color]'):FilterOnce()

local Groupname_Table = RecceSET:GetSetNames()

local Spawned_Group_Table = {}

local Spawn_Object_Table = {}


for i, Group_Name in ipairs(Groupname_Table) do
   
   Spawn_Object_Table[i] = SPAWN:New(Group_Name)
   :InitLimit(1,10)[color="Blue"] -- Tweak the max unit and max respawn values as desired[/color]
   :OnSpawnGroup(
   function(grp) 

      table.insert(Spawned_Group_Table, grp)   
   end
   )  
end


local function Spawner()
     
     for k, Spawn_Object in ipairs(Spawn_Object_Table) do
         
         Spawn_Object:Spawn()
     end
end

Spawner()

local function Update_Group_Table()

     for j, Spawn_Group in ipairs(Spawned_Group_Table) do
  
         if Spawn_Group and Spawn_Group:IsAlive() == nil then
            j = nil
         end 
     end
end


Land_Event_Handler = EVENTHANDLER:New()

Land_Event_Handler:HandleEvent(EVENTS.Land)

function Land_Event_Handler:OnEventLand(EventData)
        
        Update_Group_Table() 
        
        for h, Spawn_Group in ipairs(Spawned_Group_Table) do
 
            if Spawn_Group and EventData.IniUnit:GetGroup() == Spawn_Group then
               
               EventData.IniUnit:Destroy()
               Spawner()
            end
        end
end

 


Edited by Hardcard
Link to comment
Share on other sites

OMG! Hardacard TY so much!

 

So if I understand it right:

 

  1. :FilterStart() enable a fliter that keep updating the set during the mission
  2. Late activated groups are not included in sets until they are spawned if :FilterStart is enabled, if I use FilterOnce() the filter is applied only at the beginning and will not be updated when the group will be spawned
  3. A GROUP_SET contains GROUP objects, not only group names

 

Your code is working great, may I ask you to comment it a bit so I can understand it better?

 

 

UPDATE

 

 

Will this work?

 

 


RecceSet = SET_GROUP:New(DATABASE:New()):FilterPrefixes("RECCE"):FilterOnce()


RecceSet:ForEachGroup( 

  function (RecceGroup)
	RecceGroupName = RecceGroup:GetSetName()
       local SpawnRecce = SPAWN:New(RecceGroupName)
      :InitLimit(1,0)
      :InitRepeatOnLanding()
      :InitDelayOff()
      :SpawnScheduled(10,0)
   end
   )


Edited by Kappa

--

[sIGPIC][/sIGPIC]

36° Stormo Virtuale - Italian Virtual Flight Community

www.36stormovirtuale.net

Link to comment
Share on other sites

Hi I'm trying to setup a simple CAP patrol using MOOSE but I'm getting weird behaviour.

 

I'm trying to setup a CAP patrol use the A2A_DISPATCHER. At first everthing seems to be working fine: I've setup the Zones, the planes take-off and fly to the patrol zone ... so far so good. However when they reach the zone, on the tactical display it changes from "Patrolling" to "Holding". At this point a replacement CAP flight is spawned. They immediately then burn round in a circle as hard as they can for a few minutes before returning to base. The patrol zone is really big (30nm radius) so they should be able to lazily cruise round it. How can I get the planes to actually just stay on CAP in the zone until they run low on fuel? Setting the SquadronFuelThreshold appears to make absolutely no difference to this behaviour. Setting the patrol speed in SetSquadronCap also does not appear to effect in any way the speed they go at in the "Holding" behaviour.

 

The second problem is grouping. I'd like my CAP flights to consist of pairs of planes because that's more realistic and immersive. However if I do this (using SetSquadronGrouping or SetDefaultGrouping) then the planes won't climb to altitude any more (they stay on the deck) and the wingman dives and climbs on burners like a crazy thing .. as if they had absolutely no idea how to fly formation.

 

I've tried using both MOOSE 2.4.13 and 2.5.0-pre and I get the same behaviour in both. I've uploaded the mission file and the lua script here


Edited by Tomsk
Link to comment
Share on other sites

Two things.

First the easy one.

AI afterburning around doing stupid things, that's DCS, it's just particularly weird. Not sure if restrict AB as an option works, currently without scripting then do 550kts with their wheels down trying to line up for approach. Sorry MOOSE cannot cure this.

 

Second... the patrol length and grouping. I've not had this issue, but I dont doubt you have. Your expectations on what it should be doign are correct from what you say. Unfortunatley without the mission, script and logs I'm not sure where to begin to help. I would suggest jumping on MOOSE Discord and talking it through in the A2A_Dispatcher channel when someone is around, along with your mission so we can try to reproduce.

 

 

ah sorry... i see you linked the miz. I will look now.


Edited by Pikey
missed the link....!

___________________________________________________________________________

SIMPLE SCENERY SAVING * SIMPLE GROUP SAVING * SIMPLE STATIC SAVING *

Link to comment
Share on other sites

Two things.

First the easy one.

AI afterburning around doing stupid things, that's DCS, it's just particularly weird. Not sure if restrict AB as an option works, currently without scripting then do 550kts with their wheels down trying to line up for approach. Sorry MOOSE cannot cure this.

 

Second... the patrol length and grouping. I've not had this issue, but I dont doubt you have. Your expectations on what it should be doign are correct from what you say. Unfortunatley without the mission, script and logs I'm not sure where to begin to help. I would suggest jumping on MOOSE Discord and talking it through in the A2A_Dispatcher channel when someone is around, along with your mission so we can try to reproduce.

 

Thanks for your reply :) I'm aware the AI in DCS is .. special. But the bit that seemed to be MOOSE related that was weird is as soon as it reaches the patrol zone the tactical display says "Holding" and a new CAP flight is immediately spawned as a replacement. Is that intended behaviour? I can't find any documentation of the "Holding" state in the CAP state machine. Also the burning around is one thing, but the bigger issue is the immediately returning to base. They still had tonnes of fuel left (more than 75%) .. so I don't understand why they decided to RTB?

 

I included a link to the mission and script in my post, but I could jump on Discord. Where is the server to be found?


Edited by Tomsk
Link to comment
Share on other sites

@Kappa

 

You almost got it, but you seem to be missing another important concept.

 

RecceSet:ForEachGroup( 

  function ([color="Red"][b]RecceGroup[/b][/color]) [color="Blue"]-- [b][i]RecceGroup[/i][/b] represents each GROUP OBJECT contained in [i][b]RecceSet[/b][/i]. Consider it a GROUP object [/color]
	RecceGroupName = RecceGroup[color="Red"]:GetSetName()[/color] [color="Blue"]-- This isn't a valid method for a GROUP object, it'll error. Also, the correct syntax is GetSetName[u][b]s[/b][/u](), in plural[/color]

       [color="Blue"]-- Simply get the name of each group in the usual way:[/color]
       RecceGroupName = RecceGroup:GetName() 

       local SpawnRecce = SPAWN:New(RecceGroupName)
      :InitLimit(1,0)
      :InitRepeatOnLanding()
      :InitDelayOff()
      :SpawnScheduled(10,0)
   end
   )

 

 

Keep in mind that the script I wrote uses standard Lua for loops, which is why I had to use :GetSetNames() in order to get all the group names in the set.

Your script uses MOOSE iterators (fancier for loops), which allow you to work directly with the MOOSE objects in the set, so you can just get the names using typical MOOSE methods.


Edited by Hardcard
Link to comment
Share on other sites

Hi I'm trying to setup a simple CAP patrol using MOOSE but I'm getting weird behaviour.

 

I'm trying to setup a CAP patrol use the A2A_DISPATCHER. At first everthing seems to be working fine: I've setup the Zones, the planes take-off and fly to the patrol zone ... so far so good. However when they reach the zone, on the tactical display it changes from "Patrolling" to "Holding". At this point a replacement CAP flight is spawned.

 

Hi Tomsk,

i think i've seen the additional CAP Spawn when the CAP flight is farther away from Squadron Base then the value of SetEngageRadius. could be wrong though.

Link to comment
Share on other sites

Hi Tomsk,

i think i've seen the additional CAP Spawn when the CAP flight is farther away from Squadron Base then the value of SetEngageRadius. could be wrong though.

 

Thanks, I think I've figured it out ... this is the script I'm using:

 

local detectionBlueGroup = SET_GROUP:New()
detectionBlueGroup:FilterPrefixes({"EWR Blue", "SAM Blue"})
detectionBlueGroup:FilterStart()

local detectionBlueArea = DETECTION_AREAS:New(detectionBlueGroup, 20*1000)
local blueDispatcher = AI_A2A_DISPATCHER:New(detectionBlueArea)
blueDispatcher:SetEngageRadius(100*1000)
blueDispatcher:SetDisengageRadius(150*1000)
blueDispatcher:SetDefaultLandingAtEngineShutdown()
blueDispatcher:SetDefaultTakeoffFromParkingCold()

local f5_1st = "1st F5"
local capBlue01 = ZONE:New("CAP Blue #001")
blueDispatcher:SetSquadron(f5_1st, AIRBASE.PersianGulf.Al_Dhafra_AB, {"1st F5 CAP"}, 20)
blueDispatcher:SetSquadronCap(f5_1st, capBlue01, 7000, 8000, 470, 500, 600, 800, "BARO")

 

If I comment out this line so it looks like this:

-- blueDispatcher:SetDisengageRadius(150*1000)

Then I do not see the "Holding" behaviour. Things patrol as they should. It's a bit weird as there are no "targets" in the mission (only BLUFOR planes). So I'm not sure why it would prevent patrolling .. or prevent pairs of planes from climbing to the right altitude .. but for some reason it does prevent those things.

Link to comment
Share on other sites

Second... the patrol length and grouping.

 

Figured out the grouping problem, it's in two parts. First there's the SetDisengageRadius radius problem. That prevents (for some weird reason) groups of units from climbing to the right altitude.

 

The second problem is the wingmen acting weirdly. This, I have found out, is specific to my choice of plane to fly the patrol: the F5 Tiger II. If I use M2000s instead then there is no problem, the wingmen behaves fine. However, for some reason with the F5 the wingmen behaves super weird and can't fly formation with the lead.

Link to comment
Share on other sites

Hi Tomsk!

 

 

Good news I think then on all fronts. I had to do some tinkering. I have a attached a single sqn example fixed from your mission that does something as close to realistic and expected as possible with F-5s. Bear in mind this is something of a black art in places and support is "best effort".

 

 

At 0820 the group of two F-5s are airborne and head to the zone you indicated. That first time varies and cannot be brought forward easily, its part of the problem and the "black art thing". I changed their CAP to a racetrack N-S to look a bit more professional. They sustained that until 12pm and RTB'd with 40% fuel at which point, a few minutes after, their handover CAP flight spawned in and began taxiing. That's a good performance for those guys, even if AI cheats physics.

 

 

 

I did not notice altitude issues with the grouping, but I definitely changed the speeds as they are in kmh (devs love metric but it rips my knitting).

 

 

I updated moose to latest Dev - I have to support a single version and it can only be latest.


--ZONES
local cap_blue_01 = ZONE:New("CAP Blue #001")
--DISPATCHER
local detectionBlueGroup = SET_GROUP:New()
detectionBlueGroup:FilterPrefixes({"EWR Blue", "SAM Blue"})
detectionBlueGroup:FilterStart()
local detectionBlueArea = DETECTION_AREAS:New(detectionBlueGroup, 20*1000)
local blueDispatcher = AI_A2A_DISPATCHER:New(detectionBlueArea)
--SQNS
-- 1st F5 Squadrdon --------------------------------------------
local f5_1st = "1st F5"
blueDispatcher:SetSquadron(f5_1st, AIRBASE.PersianGulf.Al_Dhafra_AB, {"1st F5 CAP"}, 20)
blueDispatcher:SetSquadronTakeoffFromParkingCold(f5_1st)
blueDispatcher:SetSquadronLandingAtEngineShutdown(f5_1st)
blueDispatcher:SetSquadronGrouping(f5_1st, 2)


blueDispatcher:SetSquadronCap(f5_1st, cap_blue_01, 6000, 7000, 500, 600, 700, 900, "BARO") --remember speeds are kmh.
blueDispatcher:SetSquadronFuelThreshold(f5_1st, 0.4) --default allowed 2% fuel on pure rtb, this returns them at 40% internal fuel which is a good mix for that range and time
blueDispatcher:SetSquadronCapInterval(f5_1st, 1, 1800, 1810)
blueDispatcher:SetDefaultCapRacetrack(22000, 22000, 0, 0, nil, nil, cap_blue_01:GetCoordinate())

 

Now... the thing that really is the tricky part is the blueDispatcher:SetSquadronCapInterval(f5_1st, 1, 1800, 1810).

I've set 30 minutes. I believe if these are shot down inside that 30mins (when does it start, who knows) then it shouldnt be filled as per sustained flights - that's optimistic figures for surge operations. However, i have found this method to be a complete mystery to me. It definitely is waaaaay too short by default. I think even as it was, it seems to force the CAP to land sooner, like this airforce has such amazing turnaround it can afford to keep engine time down and pilot hours short! I just dont understand it's inner workings but changing it this way allowed it to stop RTBing until the fuel threshold was met. Incidentally that fuel threshold is from 0 to 1.0 and covers ONLY internal fuel. So if they start with 170% fuel due to externals, 0.4 will still be 40% internal fuel.

 

Have fun!

mission.miz

___________________________________________________________________________

SIMPLE SCENERY SAVING * SIMPLE GROUP SAVING * SIMPLE STATIC SAVING *

Link to comment
Share on other sites

Hi Tomsk!

 

 

Good news I think then on all fronts. I had to do some tinkering. I have a attached a single sqn example fixed from your mission that does something as close to realistic and expected as possible with F-5s. Bear in mind this is something of a black art in places and support is "best effort".!

 

Wow Pikey, thank you for your effort that's hugely helpful of you!! It seems so much of this process is a bit of a "dark art" due to the intricacies of DCS .. thank you for sharing your knowledge :)

Link to comment
Share on other sites

@Kappa

 

You almost got it, but you seem to be missing another important concept.

 

RecceSet:ForEachGroup( 

  function ([color="Red"][b]RecceGroup[/b][/color]) [color="Blue"]-- [b][i]RecceGroup[/i][/b] represents each GROUP OBJECT contained in [i][b]RecceSet[/b][/i]. Consider it a GROUP object [/color]
	RecceGroupName = RecceGroup[color="Red"]:GetSetName()[/color] [color="Blue"]-- This isn't a valid method for a GROUP object, it'll error. Also, the correct syntax is GetSetName[u][b]s[/b][/u](), in plural[/color]

       [color="Blue"]-- Simply get the name of each group in the usual way:[/color]
       RecceGroupName = RecceGroup:GetName() 

       local SpawnRecce = SPAWN:New(RecceGroupName)
      :InitLimit(1,0)
      :InitRepeatOnLanding()
      :InitDelayOff()
      :SpawnScheduled(10,0)
   end
   )

 

 

Keep in mind that the script I wrote uses standard Lua for loops, which is why I had to use :GetSetNames() in order to get all the group names in the set.

Your script uses MOOSE iterators (fancier for loops), which allow you to work directly with the MOOSE objects in the set, so you can just get the names using typical MOOSE methods.

 

Hardcard I want to thank you so much.

 

I will use this knowledge to help other mission designers using MOOSE in a simplier way thanks to the use of prefixes.

 

:thumbup:

--

[sIGPIC][/sIGPIC]

36° Stormo Virtuale - Italian Virtual Flight Community

www.36stormovirtuale.net

Link to comment
Share on other sites

2 Questions

 

I am currently digging into MOOSE Framework, and the new features like the AIRBOSS is working fine.

 

 

But somehow I've got the feeling that I doesn't understand the DCS LUA Interface:

 

 

1.) For all clients, I want to set the bullseye as Waypoint 1. Is this possible at mission start? It looks like Waypoints have to be in the mission file and can only be swapped, but not added. Is this correct?

 

 

2.)

 

I want my scripts to be as generic as possible. Therefore I want to

a) get a list of airports

b.) foreach airport

 

-> Search for "Airportname_GCI" -> If present, assign GCI Task

-> Search for "Airportname_CAP" -> If present, assign CAP Task

 

...

 

 

In Moose, there's a SET_AIRPORT Class, but I get all the Airports on all maps. Is it easily possible to get an actual list of red and blue airports? Or do I have to go through all airports, do a "find" and than check coalition?

 

 

Best regards,

_X_

[sIGPIC][/sIGPIC]

Currently used modules:

- F16 Viper(primary)

- F/A 18 Hornet , F-5E Tiger, L-39, C-101 for fun

- (many more unused but great modules :-) )

Link to comment
Share on other sites

Just a quick response:

 

1. You cannot set client waypoints at all within the scripting framework.

 

2. SET_AIRBASE should only be giving you airbases on the current map as far as I know.

 

I am currently digging into MOOSE Framework, and the new features like the AIRBOSS is working fine.

 

 

But somehow I've got the feeling that I doesn't understand the DCS LUA Interface:

 

 

1.) For all clients, I want to set the bullseye as Waypoint 1. Is this possible at mission start? It looks like Waypoints have to be in the mission file and can only be swapped, but not added. Is this correct?

 

 

2.)

 

I want my scripts to be as generic as possible. Therefore I want to

a) get a list of airports

b.) foreach airport

 

-> Search for "Airportname_GCI" -> If present, assign GCI Task

-> Search for "Airportname_CAP" -> If present, assign CAP Task

 

...

 

 

In Moose, there's a SET_AIRPORT Class, but I get all the Airports on all maps. Is it easily possible to get an actual list of red and blue airports? Or do I have to go through all airports, do a "find" and than check coalition?

 

 

Best regards,

_X_

Link to comment
Share on other sites

Hey Guys,

 

Looking to create a standard server setup for missions.

 

 

Meaning

 

3 aircraft Groups of 4 spawned in Ramps

and get res-pawned after take off.

(in case of destroyed, so client can restart)

 

 

Would Moose do something like that?:book:

Where should I look.....

 

Thanx


Edited by Dispatch

~

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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