Jump to content

Power of ME Scripts: Example


Habu_69

Recommended Posts

For mission creators who may not have yet discovered the power of scripts, I offer this simple example, using MOOSE in this instance:

 

 

BanditWP = STATIC:FindByName( "My Static" )
BanditWPVec2 = BanditWP:GetVec2()  -- location spawned aircraft will fly to

MyAircraft = SPAWN:New( "My ME Aircraft")
                  :InitLimit( 4, 1 )
                  :InitRandomizePosition( true, 60000, 40000) -- Radius band in meters
                  :OnSpawnGroup(function (SpawnGroup)
                      SpawnGroup:TaskRouteToVec2( BanditWPVec2, 600 )  -- Flight destination and speed km/hr.
                      end  
                      )

MyAircraft:Spawn()

 

 

These few lines will spawn one group of up to 4 aircraft (set to LATE ACTIVATION in the ME) at a random position within a radius band of 40000 - 60000 meters from its ME position and direct its flight path to "My Static's" location. Very handy for introducing a bandit at a random location. Script could also easily randomize spawn timing and type and number of aircraft. I have no previous coding or scripting experience, and while I am far from a scripting guru, I have become literate in the basics,

Link to comment
Share on other sites

You can also set up a fairly complex bombing range - complete with an F10 Radio Menu, ability to mark the targets with smoke, and a scoring system. All by dropping a handful of statics in the ME, and adding these four lines of code:

local bombing_targets = {"Conex_NW","Conex_NE","Conex_SE","Conex_SW","CenterTarget"}
BombingRange = RANGE:New("My Bombing Range")
BombingRange:AddBombingTargets(bombing_targets, 50)
BombingRange:Start()

 

In this example, 5 statics are named according to the names in the first line. The "My Bombing Range" in the second line could be any random string to name the range.

 

I was hesitant to learn MOOSE at first simply because I had zero experience with the Mission Editor, no experience in Object Oriented Programming, and no experience with MOOSE. But, the time I spent in learning to script was more than made up for in time saved using just the ME to create missions.

Wayz Out

 

 

Intel Core i9 9900K | ASUS ROG Strix Z390E Gaming MB | G.Skill Ripjaws V 32gb DDR4-3200 | GeForce RTX 2080 Ti | Samsung 970 EVO Plus NVMe

HTC Vive Pro VR | Logitech G x56 HOTAS | Logitech G PRO Pedals

Link to comment
Share on other sites

BombingRange = RANGE:New("My Bombing Range")
BombingRange:AddBombingTargets(bombing_targets, 50)
BombingRange:Start()

 

Please, don't take this the wrong way, but I don't get why some people use the variable in its own declaration (I'm assuming this is meant to be the full declaration of the variable BombingRange).

 

Is this meant to "isolate" RANGE:New() or something like that?

 

Normally, I'd do it like this:

BombingRange = RANGE:New("My Bombing Range")
:AddBombingTargets(bombing_targets, 50)
:Start()

 

Which is the same as this:

BombingRange = RANGE:New("My Bombing Range"):AddBombingTargets(bombing_targets, 50):Start()

Link to comment
Share on other sites

Please, don't take this the wrong way, but I don't get why some people use the variable in its own declaration (I'm assuming this is meant to be the full declaration of the variable BombingRange).

 

Is this meant to "isolate" RANGE:New() or something like that?

 

Normally, I'd do it like this:

BombingRange = RANGE:New("My Bombing Range")
:AddBombingTargets(bombing_targets, 50)
:Start()

 

Which is the same as this:

BombingRange = RANGE:New("My Bombing Range"):AddBombingTargets(bombing_targets, 50):Start()

 

Hey, coder here.

 

While that is correct this is whats known as a train wreck method chain. I don't know how Lua handles nulls but in most OOP languages, running methods on newly instanced classes before checking that construction has occured properly (ie checking for null) can cause an exception. It's called a train wreck because you are calling methods one after the other without check it's predecessor.

 

But like I said, I'm not sure how Lua treats this but just a heads up.

 

In the example you cited, it could be updated to check that BombingRange != null before calling any methods

Link to comment
Share on other sites

Please, don't take this the wrong way, but I don't get why some people use the variable in its own declaration (I'm assuming this is meant to be the full declaration of the variable BombingRange).

 

Is this meant to "isolate" RANGE:New() or something like that?

 

 

The purpose of this thread is to induce Mission Creators, those who use ONLY the ME to create their missions, to take that leap to scripting. I've seen some incredible missions done only in the ME. But those same missions can be easier accomplished (in some cases) using scripting.

 

 

While your examples will work, they can be difficult to understand to a newcomer.

 

 

I subscribe to the theory of K.I.S.S. - Keep It Simple, Stupid.

 

 

I have used your first example quite often, but with my example, it's clear that those method calls can be separated, or made conditional. It makes the logic easier to follow. And it makes debugging much easier.

Wayz Out

 

 

Intel Core i9 9900K | ASUS ROG Strix Z390E Gaming MB | G.Skill Ripjaws V 32gb DDR4-3200 | GeForce RTX 2080 Ti | Samsung 970 EVO Plus NVMe

HTC Vive Pro VR | Logitech G x56 HOTAS | Logitech G PRO Pedals

Link to comment
Share on other sites

Certainly the ME is a powerful tool in itself and can accomplish most of the behaviors that scripting can. Scripting has 2 advantages, I think. Once learned, scripting can do more with less; and it is more CPU-efficient. Also, good script fragments are available for use in other missions.

But, hey. Different strokes for different folks.

Link to comment
Share on other sites

Please, don't take this the wrong way, but I don't get why some people use the variable in its own declaration (I'm assuming this is meant to be the full declaration of the variable BombingRange).

 

Is this meant to "isolate" RANGE:New() or something like that?

 

Normally, I'd do it like this:

BombingRange = RANGE:New("My Bombing Range")
:AddBombingTargets(bombing_targets, 50)
:Start()

 

Which is the same as this:

BombingRange = RANGE:New("My Bombing Range"):AddBombingTargets(bombing_targets, 50):Start()

 

Hi Hardcard,

 

professional developers (team lead) here also. I get what you are doing here and have no problem with this. You and I exchanged scripts in the past and you really come with good code.

 

However, I tend to avoid doing this in my day to day work for three reasons:

 

1. For the reason 112th_Rossi about the null value thing

2. By having variables assigned, it is easier for someone who is reading the code while providing support.

3. For debugging purpose. It is easier to see the contents of a variable if needed when debugging. you can throw it to a log, a message or live (not in lua, but lets in in visual studio).

 

Don't get me wrong, I would not have complained seeing the code snippet you sent. Just explained why personally I rarely do this. Just coders chatting here on a Sunday morning.

 

ps: By the way, still using your Landing on Ship script like crazy ;) Just waiting for ED to fix the Huey Gunner AI before releasing a new mission of mine!

 

Have a good weekend guys.

Link to comment
Share on other sites

@DrummerNL

Here is the full script and Bombing Range mission

 

 

 

local bombing_targets =                             --5 static targets defined and placed from the ME on the abandoned airfield SW of Kobeleti 
 {                                                    -- I'm using Conex Containers from 476th Range Targets Package that can be D/Led from:
   "Conex_NW",                                        -- https://forums.eagle.ru/showthread.php?t=181232
   "Conex_NE",
   "Conex_SE",
   "Conex_SW",
   "CenterTarget"
 }
Range_42MDP = RANGE:New("42MDP Bombing Range")      -- Creates the range and defines the Range Name as appears in the F10 Other... menu
Range_42MDP:AddBombingTargets(bombing_targets, 50)    -- Add the targets to the range
Range_42MDP:Start()                                    --Start the range

local bridge_range =                                 -- 10 Bridges (scenery) between Kobeleti and Batumi  (Had to place a static Conex 
   {                                                -- container on each bridge to get the smoke and scoring to work)
   "Road Bridge #001",
   "Road Bridge #002",
   "Road Bridge #003",
   "Road Bridge #004",
   "Road Bridge #005",
   "Road Bridge #006",
   "Road Bridge #007",
   "Rail Bridge #001",
   "Rail Bridge #002",
   "Rail Bridge #003"
 }
Bridges_42MDP= RANGE:New("42MDP Bridge Busting")    --Create the Bridge bombing range
Bridges_42MDP:AddBombingTargets(bridge_range, 20)    --Add the Conex containers placed on each brige to the range
Bridges_42MDP:Start()                                --Start the Bridge Range

 

 

Bombing Range Demo.miz

Wayz Out

 

 

Intel Core i9 9900K | ASUS ROG Strix Z390E Gaming MB | G.Skill Ripjaws V 32gb DDR4-3200 | GeForce RTX 2080 Ti | Samsung 970 EVO Plus NVMe

HTC Vive Pro VR | Logitech G x56 HOTAS | Logitech G PRO Pedals

Link to comment
Share on other sites

I use both techniques.

 

When it's a simple spawn without a lot of methods, it's easier to put it on one line.

 

But when the declaration ( :New( ) )is outside the function where you are calling Target:Spawn() from, you sort of have to use the variable because it's broken up.

 

An example of this would be generating a bogey every time a radio menu item is selected. If the declaration is outside the function, you'll get a new one every time (resulting in multiple bogeys).

 

If it's inside, it will respawn the same one, and that's all you'll ever have.

 

Banner EDForum2020.jpg

Have fun. Don't suck. Kill bad guys. 👍

https://discord.gg/blacksharkden/

Link to comment
Share on other sites

  • Recently Browsing   0 members

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