Guide / Tutorial Get your Basic TARGET Script - PIPs and Curves here.

I can confirm that the Request Docking macro still works fine after the update.
Thanks @Maenden for checking this out for me.

Cheers
Clicker
You're welcome.

I've found your macros most interesting and useful.

To be honest I've made a couple of tweaks.
I extended the delay from the default so you could see the panels being accessed. Rather than just flickering for a microsecond.
So all the D() are now D(250)

Also I wasn't keen on lowering the landing gear before docking so I haven't used your latest update.

However I've got the new auto-docking module now, so I added a couple of lines which cut power to the engines (the X key in the default layout) which triggers the autodock procedure after you get permission to land. The landing gear then gets dropped just above the pad by Elite's inbuilt autodock procedure.

I don't want to steal your code, but i would be quite happy, with your permission, to show people my version.
 
Absolutely!

Any and all tweaks, modifications, improvements and suggestions are welcome.
That's what this thread is meant to be about!

Whilst some of the code I'm using here, I've done, there's a LOT of ideas, inspiration and code I've used from others which I'm using to demonstrate how things work, such as Aussiedroid, DarKcyde0 and CMDR Touille to name a few. A classic example is the PIPMapper function...I don't know who wrote this but it appears in almost every Elite Dangerous TARGET script I've seen.

Cheers
Clicker
 
Last edited:
How to make your joystick buttons do more than just one thing - Part 2: TEMPO

In this installment, I will show how to use the TEMPO statement to enable a joytsick button to do more than one thing depending on how long you hold down the switch or button.

Quoting the scripting manual, "TEMPO is a sub-function of MapKey. TEMPO gives the player the possibility
of having 2 functions on a single button. A short press will generate the first output; a long press will generate the
other output."

Syntax: TEMPO(key1, key2, delay) where delay is optional (500 milliseconds is a good value)

Desired outcome for our new functionality:
Use a short press of our PIP Management HAT switch to fire a single PIP.
Use a longer press of the same PIP Management HAT switch to use the initPIPMapper() function.

First of all we should define the delay time for the TEMPO function.
In the EDGlobalVars.tmh add the following;

Code:
define TempoDelay    500        // Set variable for Tempo to 500 msec
Now whilst 500msec may be fine, you can make this delay shorter or longer depending on your own personal preferences.

Next, we modify our PIP managment settings in the EDScript.tmc file to use TEMPO.
For the 4x Mapkey buttons we previously used for initPIPMapper(), change them to...

...for WARTHOG...
MapKey(&Joystick, H3U, TEMPO(PULSE+PowerEng, EXEC("initPIPMapper(ENG,WEP);"), TempoDelay));
MapKey(&Joystick, H3L, TEMPO(PULSE+PowerSys, EXEC("initPIPMapper(SYS,ENG);"), TempoDelay));
MapKey(&Joystick, H3R, TEMPO(PULSE+PowerWep, EXEC("initPIPMapper(WEP,ENG);"), TempoDelay));
MapKey(&Joystick, H3D, EXEC("initPIPMapper();")); // this stays as is

...for T16000...
MapKey(&T16000, H1U, TEMPO(PULSE+PowerEng, EXEC("initPIPMapper(ENG,WEP);"), TempoDelay));
MapKey(&T16000, H1L, TEMPO(PULSE+PowerSys, EXEC("initPIPMapper(SYS,ENG);"), TempoDelay));
MapKey(&T16000, H1R, TEMPO(PULSE+PowerWep, EXEC("initPIPMapper(WEP,ENG);"), TempoDelay));
MapKey(&T16000, H1D, EXEC("initPIPMapper();")); // this stays as is

Note 1: If you changed the PIP distribution in your scripts from my original examples, please be careful about just cutting/pasting the above over the top of what you have!
Note 2: for the HatD (down) switch, instead of EXEC("initPIPMapper();") we can use PULSE+BalancePower if preferred ... they both do exactly the same thing.

USAGE:
In the above, and for example, when we hit the hat (UP) momentarily, the joystick would send a single "Up-Arrow" to the game which is a single pip to Engines.
If we hold the hat (UP) for more than half a second, the Joystick fires the initPIPMapper function (in our case, resulting in [0, 4, 2]).

In part 3, I'll have a go at showing how we can get one switch to do more than one thing via LAYERS.

Cheers
Clicker
 
How to make your joystick buttons do more than just one thing - Part 3: Layers.

This tutorial assumes you have a Thrustmaster Throttle controller as well as a joystick AND have enabled it by adding comment delimiters in the
"Configure()" statements for your specific Throttle at the top of the EDScript.tmc file. If, however, you do not, then you can substitute any 2 unused Joystick
buttons or switches in the SetShiftButton() statement.
WARTHOG Example: SetShiftButton(&Joystick, S3, &Joystick, H1L, H1R);
T16000 Example: SetShiftButton(&T16000, B6, &T16000, B1, B2);

Following on from my last tutorial on this topic I introduce the concept of Layers.

Quoting the scripting manual;
"Using layers is like using several parallel programs. You select the layer you want to use by an action on a
“master button”. The layer selector can be a single button or several buttons, but you will have to set the nature of
the button. Keep in mind that in order to access a layer, the associated “master button” must be pressed."

Hmmm...or, to put it another way, we can use a switch or button on the joystick or throttle to act as a SHIFT key.
Using this "shift modifier" we can program a button to do something different to when it is un-shifted.
Very similar in theory to the shift key on a keyboard (or "ALT", or "CTRL" etc).

At this point I have made a conscious decision NOT to explain layers or the required MapKey syntax further within this tutorial as it would make this post too wordy.
The danger here is people will turn off if they have to read and absorb too much if all they want are quick functionality additions to the script.
The explanations are all in the TARGET Scripting manual along with some additional examples for anyone interested in nutting this out for themselves.
Having said that, if people ask for more info in this forum thread, or via direct PM, I'll be only too happy to explain my understanding.

Desired outcome for this tutorial:
In a previous post I showed how to use macros to clear the chatbox and request docking.
Then, in a more recent post I expanded on the simple macro to also drop the landing gear and set full power to shields.
In this example we'll use a single button to fire the two different macros we previously created using layers.

To do this we need to...
a) Define what our modifier (or SHIFT) buttons are using the built in SetShiftButton() function.
b) Change one previously used button to use the layers and define what they should do.
c) Free up another previously used macro button (I use it as the shift modifier here actually)

Here's how...
a) define modifiers

In the EDSCript.tmc file, directly after the "fnCustomCommands():" statement add...

...for WARTHOG...
SetShiftButton(&Joystick, S3, &Throttle, PSF, PSB); // S3 = IO, PSF/PSB = UMD

...for T16000...
SetShiftButton(&T16000, B6, &TWCSThrottle, TBTN4, TBTN5); // B6 = IO, TBTN4/TBTN5 = UMD

b) Change previous macro button to use layers and define which layer does what...

...for WARTHOG...
Change: MapKey(&Joystick, S1, EXEC("fnAdvancedDockingRequest();"));
To: MapKeyIO(&Joystick, S1,
EXEC("fnAdvancedDockingRequest();"),
PULSE+mClearChatbox);


Change: MapKey(&Joystick, S3, PULSE+mClearChatBox);
To: MapKey(&Joystick, S3, 0);

...for T16000...
Change: MapKey(&T16000, B5, EXEC("fnAdvancedDockingRequest();"));
To: MapKeyIO(&T16000, B5,
EXEC("fnAdvancedDockingRequest();"),
PULSE+mClearChatBox);


Change: MapKey(&T16000, B6, PULSE+mClearChatBox);
To: MapKey(&T16000, B6, 0);

USAGE:
Using the button designated above for your device without pressing the modifier (shift) button, fires the fnAdvancedDockingRequest() function.
Press+Hold the modifier button then press the designated button, fires the mClearChatBox macro instead.

Using modifiers in this way gives us up to 6 different options for each MapKey we define in the script.
In this example we are not using the other defined modifier buttons, but we MUST declare them in the SetShiftButton() function or the script will not compile.
(edit: just learned you can substitute the IO defines with '0"s if you aren't using IO and do not wish to tie up a button)
(eg. SetShiftButton(0, 0, &Throttle, PSF, PSB); )

In the next tutorial, I'll expand on my simple macro module to allow you to send a bunch of canned chat messages to the Comms Panel

Cheers
Clicker
 
Last edited:
Here's a quick enhancement for your script using the techniques explained in the last tutorial.

We'll use layers to enable the trigger to function three different ways.

1) Fire a pulse once every 7 seconds until we press the trigger again. Handy for the pulse wave scanner
2) default action
3) Press and hold for 6.1 seconds each time we press the trigger. Handy for the discovery scanner

Ok first up let's define a variable for the Primary Trigger.

In EDGlobalVars file add the following;

Code:
    define PrimaryFire        DX1                // JOY 1
    define SecondaryFire    DX3                // JOY 3
Then, in EDScript file add the following in the KeyMap section of the script'

WARTHOG
Code:
//        (Gun Trigger)
//        -----------------------

        MapKeyUMD(&Joystick, TG1,        // (Gun Trigger - Stage 1)
            SEQ(REXEC(0, 7000, "ActKey(KEYON+PULSE+PrimaryFire);", RNOSTOP), EXEC("StopAutoRepeat(0);")),    // U - Fires every 7 seconds until stopped (eg pulse wave scanner)
            PrimaryFire,                                                                                    // M - default trigger action
            EXEC("ActKey(KEYON+DOWN+PrimaryFire); DeferCall(6100, &ActKey, KEYON+UP+PrimaryFire);")            // D - holds trigger for 6.1 seconds (eg discovery scanner)
            );

T16000
Code:
//        (Gun Trigger)
//        -----------------------

        MapKeyUMD(&T16000, TS1,        // (Gun Trigger)
            SEQ(REXEC(0, 7000, "ActKey(KEYON+PULSE+PrimaryFire);", RNOSTOP), EXEC("StopAutoRepeat(0);")),    // U - Fires every 7 seconds until stopped (eg pulse wave scanner)
            PrimaryFire,                                                                                    // M - default trigger action
            EXEC("ActKey(KEYON+DOWN+PrimaryFire); DeferCall(6100, &ActKey, KEYON+UP+PrimaryFire);")            // D - holds trigger for 6.1 seconds (eg discovery scanner)
            );

Lastly, make sure you've registered the trigger in ED Controller Settings (should be listed as JOY1).
You can use a key to be sent using the trigger if you prefer, ED doesn't really care, just make sure whatever you bind in game is what "PrimaryFire" is defined as.

To be perfectly complete, you might also want to copy the functionality for which ever button you use for your second trigger.
On my Warthog Stick I use the Red Thumb Button on the stick which is coded for DX3...hence the define included above

Usage:
In our previous tutorial example on layers we used the PSF/PSB switch on the Warthog Throttle and TBTN4/TBTN5 on the TWCS for "UMD" functionality.
Up Layer (U) = Press+Hold PSF or TBTN4 then press and release the trigger and release PSF or TBTN4 and the Trigger will fire a single shot once every 7 seconds.
To cancel this, just repeat the action (PSF or TBTN + Trigger)

Mid Layer (M) = Do not use the modifier (shift) buttons and the trigger fires as normal.

Down Layer (D) = Press+Hold PSB or TBTN5 then press release the trigger, then release PSF/TBTN5 and the trigger will fire and hold for 6.1 seconds...just longer than required for the Discovery Scanner honk.

And that's it...enjoy.

Clicker
 
Last edited:
In this tutorial, we'll expand on a couple of earlier tutorials by incorporating layers and use several buttons to send short, canned chat messages to the Comms Panel.

Desired outcome for this tutorial:
Using the additions from the "Layers" tutorial, we'll use the modifier keys PLUS an unused button (or three) to send canned chat messages to the chat window in game.

What we need...
a) include a new file which defines our chat messages
b) a new function which can send our chat messages to the comms panel chat box (I've provided a pre-written function in it's own file)
c) MapKey some buttons to trigger the chat messages

Here's how...
Download the attached zip file and unzip into the same folder as your other script files.

Edit EDScript.tmc and add the following at the end of the "include section"

include "EDChatProc.tmh"

Note: when the script is compiled/run EDChatProc.tmh will issue an "include EDChatMessages.tmh" command which will go ahead and load the canned messages file.
You'll note there's plenty of examples within this file but do feel free to get in and change the text messages to whatever you like.
Likewise, you may change the string variable names (starting with "chat_"), just be mindful when calling the "SendChatString();" function...the variable names are case sensitive.

WARNING: Try to keep the text strings relatively short. This function, unlike CHAIN() cannot LOCK the script or keyboard from sending other keys whilst its "typing", so if you hit other buttons etc, they'll end up inside the text stream in the chat window.

Next, select the button/s you wish to use and create MapKey statements for them within EDScript.tmc to use the new function.

Examples

...for WARTHOG...
(using the Countermeasures switch H4 as example)
In the EDSCript file, add the following to the MapKey section...
Code:
//        (Countermeasures Switch)        // Send canned chat messages
//        ------------------------

        MapkeyUMD(&Joystick, H4U,
            EXEC("SendChatString(chat_HostileAttack);"),            // U - send Hostile Attack message to chat window
            EXEC("SendChatString(chat_HostileDemand);"),            // M - send Hostile Demand message to chat window
            EXEC("SendChatString(chat_HostileScanning);")            // D - send Hostile Scanning message to chat window
        );
        MapkeyUMD(&Joystick, H4D,
            EXEC("SendChatString(chat_BasicHello);"),                // U - send Basic hello message to chat window
            EXEC("SendChatString(chat_BasicQuery);"),                // M - send Basic Query message to chat window
            EXEC("SendChatString(chat_BasicAttack);")                // D - send Basic Attack message to chat window
        );

...for T16000...
(using buttons 8, 9 as example)
In the EDSCript file, add the following to the MapKey section...
Code:
        MapkeyUMD(&T16000, B8,
            EXEC("SendChatString(chat_HostileAttack);"),            // U - send Hostile Attack message to chat window
            EXEC("SendChatString(chat_HostileDemand);"),            // M - send Hostile Demand message to chat window
            EXEC("SendChatString(chat_HostileScanning);")            // D - send Hostile Scanning message to chat window
        );
        MapkeyUMD(&T16000, B9,
            EXEC("SendChatString(chat_BasicHello);"),                // U - send Basic hello message to chat window
            EXEC("SendChatString(chat_BasicQuery);"),                // M - send Basic Query message to chat window
            EXEC("SendChatString(chat_BasicAttack);")                // D - send Basic Attack message to chat window
        );

USAGE:
Press and hold the Up modifier switch (Warthog Throttle = PSF & TWCS = TBTN4) we setup in the Layers Tutorial and press H4U or B8 to send the "Hostile Attack" message to the chat window.
No modifier (= Mid) plus the same switch for "Hostile Demand" message.
Down Modifier (PSB or TBTN5) + same switch for "Hostile Scanning" message.

Likewise for Up/Mid/Down + H4D/B9 for the "Basic..." messages.

TIP: If you find that some of the text sent to the chat window is missing, it's likely the function is sending keystrokes too quickly.
You can slow the typing rate down by modifying the "DeferCall()" delay number in the SendChatString(); function from "50" to something like "66" or "75".

By now hopefully you have a reasonable grounding on some of the powerful functionality of TARGET Script.

Acknowledgements: I'd like to thank @Aussiedroid for allowing me to use his canned chat messages for this tutorial.
Also, props to @sYfte from the HOTAS/HOSAS discord for the actual chat function...I struggled with this for months and when I finally cracked it, he came up with a much more elegant and efficient solution.
I have learned so much from you both, so, thank you!

As always, if you encounter any issues or need clarification or explanations, just let me know.

Cheers,
Clicker
 

Attachments

Last edited:
As a newcomer to Target scripting, I would welcome some advice. I use a T16000m and a TWCS Throttle. I tried once to use Target but could not get it to work. So I have been using Joystick Curves, and macros in Voice Attack to set specific pips on the POV on the throttle (I don't use Voice Attack for anything else). When I saw this thread I decided to give it a go - I like the idea of dynamic curves, and not having to use Voice Attack macros for pip management. Thanks Clicker!
However I have problems with using the POV on the joystick, as I use them for several other functions apart from pip management, and the solution suggested in Slange Lands' post did not solve this. Ideally I wanted to use the POV on the throttle rather than on the joystick, so I included the throttle in the script and changed the MapKey to THAT2U etc. This works for the pips, but when I try to enter the throttle axis, the ministick axes and the rocker axis for the usual functions in Controls settings,they do not register. Choosing the throttle axis for the Throttle Axis in Controls, for example, nothing happens.
Any suggestions for a solution would be most welcome!
 
Ok sorry to reply to my own post, but I think I've figured it out, I needed to MapAxis the axes on the throttle in the script, even though I didn't want to use curves on them. Just need to define all the settings in Controls again now...
 
Hi @Prasinus ,

In the EDScript.tmc file locate and change the throttle definition to the following;

Configure(&TWCSThrottle, MODE_FILTERED);

...and make sure it isn't commented out (ie remove the '//' from the start of the line if present)

This should allow the script to do its thing plus enable the game to see any inputs not specifically included in the script...such as the ministick and rocker.

See if that helps and let me know how you get on.

Cheers
 
I tried your suggestion, Clicker, but the POV did not work, did not do anything when pressed. So I switched back to MODE_EXCLUDED and mapping the throttle axes.
However I am having a problem with the Thrustmaster Combined in that both sets of buttons, on the joystick and on the throttle, cause the equivalent Combined button to be pressed. So pressing Fire button 1 fires, but also causes an attempt to hyperspace, as that is what button 1 on the throttle is set to.
I presume I need to MapKey the buttons on each device in EDScript.tmc, but I don't know how to force a distinction between the two sets of buttons.
 
Sorry, I don't have one of these...the "POV" on the Throttle isn't working? Or, do you mean the POV on the Joystick?

Changing it back to EXCLUDED will cause the Throttle to act as a stand alone controller and any Throttle related code in the TARGET script won't work.
The default "setting" in the script was to have the whole line commented out....which, as far as I know is the same as configuring it as "INCLUDED".

Your presumption is correct, when INCLUDING or commenting the device out in the script, you MUST MapKey all the buttons ans switches you want to use.
These can be coded as their DirectX equivalents or as keypresses.

Confusing, I know. Once you get your head around these things everything starts making sense but for a newbie...it's infuriating and little wonder a lot of people on these threads bag TARGET.

Stick with it...I'm happy to keep trying to help.

Cheers
 
I meant the POV on the throttle didn't work, and as well as reverting to EXCLUDED I commented the line out, as it was originally.
How do you know what is the DirectX equivalent to the buttons?
Thanks for the help, I'm finding it tricky but interesting.
 
Ok, you will need to MapKey the 4 POV switches (up, down, left and right) for it to work with the Configure statement commented out.

I assume when you had the statement uncommented and “FILTERED” you...
A) did NOT have any MapKey in your script set for it and
B) set the binds in ED Controller settings?

As for the DirectX stuff, you can actually assign any DX (ie DX1-DX32) via MapKey...and you still need to set via ED Controller settings

Hope this helps.
 
Thanks, that's what I needed to know about the DirectX values, I was thinking that the buttons needed a specific DX number.
I have the POV on the throttle working OK, I have mapped up, down, left and right.
 
Hi @epoch5 ,

I do not address this within the script in this thread.
If you have a WARTHOG, you can use the coolie switch on the throttle (for example) as a digital yaw.
(ie it’s either ON or OFF with no in-between)...not ideal but is do-able)

If you have started using my script and want to add yaw via the coolie (or other unused switch) and need help coding it, let me know and I’ll be happy to assist.

Another option is to take a look at Aussiedroid’s very comprehensive script...he has both pedal support and coolie switch support for yaw already coded in.

Clicker
 
Top Bottom