forked from X-Friese/FlyWithLua
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFlyWithLua_Manual_en.tex
3195 lines (2052 loc) · 167 KB
/
FlyWithLua_Manual_en.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
%% Dokumentenvorspann für Aufgabenblatt Friesen Freitage
%%
%% (c) 2008 Carsten Lynker
%%
%% Abgeleitet aus einer früheren Klassenarbeitsvorlage
%%
%% Die einzelnen Aufgaben sind mit \aufgabe einzuleiten, die
%% Aufzählungsumgebung enumerate hat die in Klassenarbeiten
%% übliche Form a) ... b) ...
%%
\documentclass[11pt,parskip=half,a4paper]{scrartcl}
%\usepackage{ngerman}
%\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{multicol}
\usepackage{graphicx}
\usepackage{pslatex}
\usepackage{helvet}
\usepackage{listings}
\lstset{numbers=left, numberstyle=\tiny, numbersep=4pt, breaklines=true, frame=single, showstringspaces=false, basicstyle=\scriptsize}
\include{lua.def}
\lstset{language=lua}
\usepackage[pdftitle={FlyWithLua Quick Reference Manual},pdfstartview={FitH},colorlinks=true]{hyperref}
\pdfcompresslevel=9
\pdfimageresolution=72
\usepackage{color}
\definecolor{hellgrau}{gray}{0.85}
\definecolor{dunkelgrau}{gray}{0.55}
\newcommand{\hinweis}[2]{%
\phantomsection\addcontentsline{toc}{section}{#1}
\begin{center}
\fcolorbox{dunkelgrau}{hellgrau}{\parbox{14cm}{\textbf{#1}#2}}
\end{center}
}
\newcounter{aufg}
\newcommand{\xsb}{XSquawkBox}
\newcommand{\punkte}[1]{\marginpar{\fcolorbox{dunkelgrau}{hellgrau}{\parbox{4.5ex}{\sffamily\tiny#1}}}}
\renewcommand{\labelenumi}{\alph{enumi})}
\newcommand{\aufgabe}{\stepcounter{aufg}\vspace{0.75cm}\pagebreak[3]{\phantomsection\addcontentsline{toc}{section}{Aufgabe~\arabic{aufg}}\Large\sffamily Aufgabe~\arabic{aufg}}}
\renewcommand{\labelenumi}{\alph{enumi})}
\usepackage{fancyhdr}
\usepackage{lastpage}
\pagestyle{fancy}
\setlength{\headheight}{2cm}
\chead{\includegraphics[width=2.0cm]{FlyWithLua_logo.JPG}\\[2ex]}
\cfoot{\footnotesize Seite \thepage\ von \pageref{LastPage}}
\renewcommand{\headrulewidth}{0.4pt}
\renewcommand{\footrulewidth}{0.4pt}
%%%%%%%%%%%%%%%%%%%%%%%%
%% Ende des Vorspanns %%
%%%%%%%%%%%%%%%%%%%%%%%%
\hyphenation{values- HIDAPI-}
\begin{document}
\title{FlyWithLua V2.2 Quick Reference Manual}
\author{Carsten Lynker}
\date{\today}
\maketitle
\vspace{2cm}
\begin{center}
\includegraphics[width=10cm]{FlyWithLua_logo.JPG}
\end{center}
\thispagestyle{empty}
\newpage
\verb||
\tableofcontents
\newpage
\section{Using the Plugin}
\subsection{What's needed}
To use FlyWithLua, you will need following:
\begin{enumerate}
\item The plugin itself.
\item A nice text editor (\href{http://www.vim.org/}{VIM}, \href{http://www.gnu.org/software/emacs/}{GNU Emacs}, \href{http://notepad-plus-plus.org/}{Notepad++}, ...).
\item The plugin >>\href{http://www.xsquawkbox.net/xsb/}{XSquawkBox}<< (optional, but usefull).
\item The plugin >>\href{http://wiki.x-plane.com/DataRefEditor}{DataRef Editor}<< (optional, but extremely high recommended).
\item Some skills in programming \href{http://www.lua.org}{Lua} (FlyWithLua uses \href{http://luajit.org/}{LuaJIT}, compatible to Lua 5.1).
\item Knowledge about \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{DataRefs}.
\end{enumerate}
\subsection{Installation}
To use the plugin, just copy the complete folder \verb|FlyWithLua| into X-Plane's main plugin folder. The main plugin folder looks like this:
\emph{<<place where you store the sim>>}\verb|/X-Plane 10/Resources/plugins/|\footnote{If you use X-Plane 9 instead of X-Plane 10, search for the README\_XP9.txt file and follow the instruction inside.}
When the plugin starts up, there must be a folder named
\emph{<<place where you store the sim>>}\verb|/X-Plane 10/Resources/plugins/FlyWithLua/Scripts/|\footnote{If you rename the plugin, it will stop working. So never change it's folder name.}
with at least one file in it (no matter if it is a Lua script or not). When you copy the complete folder, you will start with two subfolders, \verb|Scripts| and \verb|Scripts (disabled)|. All scripts inside the \verb|Scripts| folder will be run automatically by the plugin.
When the plugin starts, it will run all files inside the \verb|Scripts| folder, who end as:
\verb|.fwl|, \verb|.FWL|, \verb|.lua|, \verb|.Lua| or \verb|.LUA|
If a file is hidden (it's name begins with a single dot), the file will be ignored by the plugin.
This means, you have three ways to disable a script.
\begin{enumerate}
\item Change the endian.
\item Hide it (let the name start with >>\verb|.|<<).
\item Move it to another folder.
\end{enumerate}
I prefer the last way, so you find the folder \verb|Scripts (disabled)| filled with examples. All these examples may produce an enormous frustration, if you just copy them into the >>active<< folder. They may redefine your joystick setting for example. So be very carefully and modify them before usage. Lua scripts are a powerful weapon!
\subsection{How to interact with Lua}
If you have XSquawkBox installed, there is an easy way to talk to Lua. If you type in a line into XSquawkBox starting with a \verb|>| (a greater than sign), the line is send directly to Lua, instead of talking to your VATSIM channel (on COM1). Try the following code:
\verb|>print(2+3)|
If everything is fine, Lua will print a \verb|5| into the XSquawkBox's main text display. The output produced by Lua is not forwarded to the VATSIM COM1 channel. So don't be afraid of disturbing the controller. You can check this behavior as XSquawkBox prints all internal information in dark red color.
So FlyWithLua is a little pocket calculator? Hmm, why not. But this is not the intension of the plugin. FlyWithLua was made to interact with DataRefs.
\subsection{Lua variables and DataRefs}
Lua can handle variables. You can try it out:
\verb|>LuaIsNice = true|\\
\verb|>print(LuaIsNice)|
Not very spectacular, but wait, let's tell Lua to bind a variable to a DataRef:
\verb|>DataRef("battery", "sim/cockpit/electrical/battery_on", "writable")|\\
\verb|>print(battery)|
Wow! Lua prints out a \verb|1| if the battery is on, or a \verb|0| when the battery is off. That's magic! But it goes even better. Turn on your plane and type this:
\verb|>battery = 0|
Plopp -- your plane is down. If a variable is connected to a DataRef, and you define the connection as not readonly (the third parameter of the function call was \verb|"writable"|),
all changes on the variable will be pushed to the DataRef instandly.
\subsection{Writing a first config file}
With the knowledge now, we can write a little config script like this:
\begin{lstlisting}
DataRef("pitch_nullzone", "sim/joystick/joystick_pitch_nullzone", "writable" )
pitch_nullzone = 0.0
DataRef("roll_nullzone", "sim/joystick/joystick_roll_nullzone", "writable" )
roll_nullzone = 0.0
DataRef("heading_nullzone", "sim/joystick/joystick_heading_nullzone", "writable" )
heading_nullzone = 0.0
\end{lstlisting}
This works very well, but it is not really user friendly. So I decided to give FlyWithLua some extra functions, who make the code more cheerful. The config file can be alternatively written as:
\begin{lstlisting}
set( "sim/joystick/joystick_pitch_nullzone", 0.0 )
set( "sim/joystick/joystick_roll_nullzone", 0.0 )
set( "sim/joystick/joystick_heading_nullzone", 0.0 )
\end{lstlisting}
Much easier to read, isn't it?
\subsection{Pre-defined variables}
But what to code if you want a nullzone of 0.1 in your piston, but 0.0 in your helicopter? You can use the pre-defined variable \verb|PLANE_ICAO|.
\begin{lstlisting}
-- nullzone of my little Cessna
if (PLANE_ICAO == "C172") then
set( "sim/joystick/joystick_pitch_nullzone", 0.1 )
set( "sim/joystick/joystick_roll_nullzone", 0.1 )
set( "sim/joystick/joystick_heading_nullzone", 0.1 )
end
-- nullzone of my little coffee mill
if (PLANE_ICAO == "R22") then
set( "sim/joystick/joystick_pitch_nullzone", 0.0 )
set( "sim/joystick/joystick_roll_nullzone", 0.0 )
set( "sim/joystick/joystick_heading_nullzone", 0.0 )
end
\end{lstlisting}
\subsection{Loop Callbacks}
All your code will be calculated automatically during startup, if you change the plane or position, or when you click on \verb|Reload all Lua script files| in the plugin's main menu.
If this is not enough to you, you can generate code, that will be calculated continuously in a loop callback.
These two commands given to Lua (using XSquawkBox's input line) will produce an ugly behavior:
\verb|>DataRef("poslight", "sim/cockpit/electrical/nav_lights_on", "writable")|\\
\verb|>do_sometimes("poslight = 0")|
Now, from time to time, Lua will turn off your navigation lights. Try it out to see how it works. You will not bewitch the simulator for the rest of your life. A simple click on the menu entry \verb|Reload all Lua script files| will reset your magic spell.
\subsection{Menu entries}
Every time you get your little bird back to \href{http://nav.vatsim-germany.org/files/edgg/charts/edlp/public/EDLP_ILS24.pdf}{Paderborn/Lippstadt (EDLP)}, you want to talk to the tower controller (on frequency 133.375) to initialize your VFR approach, and want your needle pointing to PAD (on frequency 354). Maybe you want to tune in the ILS signal.
You can define an ATC menu entry to script it. This will help a lot, because the code will only be calculated if you click on the menu entry. Nobody always want to fly around Paderborn, right? Write a little file like this and name it >>\verb|EDLP_VFR_Approach.lua|<<.
\begin{lstlisting}
DataRef("COM1", "sim/cockpit/radios/com1_freq_hz", "writable")
DataRef("NAV1", "sim/cockpit/radios/nav1_freq_hz", "writable")
DataRef("ADF1", "sim/cockpit/radios/adf1_freq_hz", "writable")
add_ATC_macro("coming home", [[-- fly home to EDLP
COM1 = 13337
NAV1 = 10855
ADF1 = 354]])
\end{lstlisting}
As the code of your macro needs more than one line, you use the double brackets \verb|[[| and \verb|]]| to write down a multi line string as the second argument of the function \verb|add_ATC_macro|. So don't forget the closing normal bracket, as shown in the last line above.
\subsection{Menu switches}
If you want to toggle a special behavior of your simulator, defined in a script, but you do not want to rename or move the file and reload all scripts to use it or not, you can use menu entry switches.
It's just as easy as giving Lua's \verb|add_macro| function two additional string parameters. Write a file like this and name it >>\verb|transponder_helper.lua|<<.
If you don't want to copy\&paste the code, just take a look into the \verb|Scripts (disabled)| folder.
\begin{lstlisting}
-- The groundspeed is in m/s (meter per second), not kn (knots), and always readonly
DataRef("groundspeed", "sim/flightmodel/position/groundspeed")
-- The transponder code is a 4-digit integer
DataRef("transponder_code", "sim/cockpit/radios/transponder_code", "writable")
-- Transponder mode (off=0,stdby=1,on=2,test=3)
DataRef("transponder_mode", "sim/cockpit/radios/transponder_mode", "writable")
-- we start in Europe most of the time
transponder_code = 7000
-- turn on your transponder when flying faster than 20 m/s (about 40 kn)
function check_transponder()
if (transponder_help == true) then
if ((groundspeed > 20) and (transponder_mode ~= 2)) then
transponder_mode = 2
XPLMSpeakString("Transponder set to active")
end
if ((groundspeed < 20) and (transponder_mode > 1)) then
transponder_mode = 1
XPLMSpeakString("Transponder set to standby")
end
end
end
-- check it every 10 sec
do_sometimes("check_transponder()")
-- make a switchable menu entry, default is on
add_macro("Automatically set Transponder", "transponder_help = true", "transponder_help = false", "activate")
\end{lstlisting}
\newpage
\section{Reference}
\subsection{Predefined variables}
All predefined variables are readonly. If you change them, X-Plane will not recognize it.
\subsubsection{LONGITUDE}
Gives the actual longitude value in decimal as a double float value (remember Lua didn't know float but only number). As X-Plane uses the data type \verb|double|, but the numbers in Lua are only \verb|float|, you will get an approximation.
The value is readonly, like all predefined variables. So it isn't possible to replace the plane in it's position by changing the value.
Positive values in LONGITUDE are east, negative values are west.
\subsubsection{LATITUDE}
This gives the latitude value of the plane's position as a decimal value. So for example seven degree thirty minutes north is represented as 7.5 (a positive value, negative values are south).
\subsubsection{PLANE\_ICAO}
A string holding the plane's ICAO code in it.
\subsubsection{PLANE\_TAILNUMBER}
The Tailnumber of the plane as a string.
\subsubsection{SCREEN\_WIDTH}
The screen width in pixel.
\subsubsection{SCREEN\_HIGHT}
The screen hight in pixel.
\subsubsection{MOUSE\_X}
Horizontally position of the mouse pointer. Coordinates start on the left side with 0 (zero).
\subsubsection{MOUSE\_Y}
Vertically position of the mouse pointer. Coordinates start on the bottom side with 0 (zero).
\subsubsection{XSB\_METAR}
A string containing the last metar received by XSquawkBox. If you are not connected to VATSIM, the variable will be useless. It is readonly.
Readonly means, you can't modify the online weather by changing the \verb|XSB_METAR| variable!
\subsubsection{LUA\_RUN}
An integer value showing how often Lua was (re)started. During the very first run of Lua, it's value is 1. You can use it to do things only once after X-Plane was started, and do not repeat when a new plane was loaded or the airport was changed. (Both will force a Lua restart.)
\subsubsection{XPLANE\_VERSION}
An integer value showing the version number of X-Plane. FlyWithLua is designed to run on X-Plane version 10.x, but it may run on X-Plane 9. To check if you are really on X-Plane 10 (or newer), you can say: \verb|if XPLANE_VERSION > 1000 then ... end|.
Example given: the version \href{http://wiki.x-plane.com/Beta#X-Plane_10.10_RC_3}{X-Plane 10.10rc3} shows: \verb|XPLANE_VERSION = 10101|
\subsubsection{XPLANE\_HOSTID}
An integer value showing the HostID of X-Plane, an OS-specific value (totally unnecessary).
\subsubsection{SDK\_VERSION}
An integer value showing the version number of the SDK, FlyWithLua is running on. The SDK version should be 210 or above for X-Plane 10. If not, download a version for X-Plane 10 of FlyWithLua.
\subsubsection{SYSTEM}
A string telling you on witch computer system FlyWithLua (the simulator) is running. It's value is \verb|"IBM"| on Windows systems, \verb|"APL"| on Apple Macintosh systems and \verb|"LIN"| on Linux systems.
\subsubsection{SYSTEM\_ARCHITECTURE}
A number either 32 or 64, depending on the architecture. 64 means X-Plane is running in 64-bit, 32 means the simulator and all plugins are running in 32-bit.
\subsubsection{XPLANE\_LANGUAGE}
A string value showing the language of X-Plane's menus. The value can be \verb|"English"|, \verb|"French"|, \verb|"German"|, \verb|"Italian"|, \verb|"Spanish"|, \verb|"Korean"|, \verb|"Russian"|, \verb|"Greek"|, \verb|"Japanese"|, \verb|"Chinese"| or \verb|"Unknown"|.
\newpage
Since FlyWithLua version 2.0 all menu entries are no longer forced to English. To create a multiple language support for your plugin, write code like this\footnote{All text other than English or German was translated using \href{http://translate.google.com/}{Google Translator}.}:
\begin{lstlisting}
dataref("COM1", "sim/cockpit/radios/com1_freq_hz", "writable")
if XPLANE_LANGUAGE == "German" then
add_macro("Stelle das Funkgerät auf UNICOM", "COM1 = 12280")
elseif XPLANE_LANGUAGE == "French" then
add_macro("Fréquence radio point sur l'UNICOM", "COM1 = 12280")
elseif XPLANE_LANGUAGE == "Spanish" then
add_macro("Punto de frecuencia de radio en la UNICOM", "COM1 = 12280")
elseif XPLANE_LANGUAGE == "Italian" then
add_macro("Punto di frequenza radio sulla UNICOM", "COM1 = 12280")
else
add_macro("Set radio to UNICOM", "COM1 = 12280")
end
\end{lstlisting}
\subsubsection{DIRECTORY\_SEPARATOR}
A string containing the directory separator of the current OS.
\subsubsection{SCRIPT\_DIRECTORY}
The complete OS-specific path to the scripts including a directory separator as it's last character. If you want to write a file named \verb|my_info.txt| into the scripts directory (instead of X-Plane's main directory), use code like this:
\verb|infofile = os.open(SCRIPT_DIRECTORY .. "my_info.txt", "w")|
\subsubsection{AIRCRAFT\_PATH}
The full path to your aircraft file, ending with a directory separator.
\subsubsection{AIRCRAFT\_FILENAME}
The name of the ACF aircraft file, including the endian "\verb|.acf|".
\subsubsection{DO\_EVERY\_FRAME\_TIME\_SEC}
The duration time in seconds of the every frame loop.
\subsubsection{DO\_EVERY\_DRAW\_TIME\_SEC}
The duration time in seconds of the drawing loop.
\subsubsection{DO\_SOMETIMES\_TIME\_SEC}
The duration time in seconds of the loop to be executed sometimes.
\subsubsection{DO\_OFTEN\_TIME\_SEC}
The duration time in seconds of the often executed loop.
\subsubsection{SCRIPTS\_LOADING\_TIME\_SEC}
The time it takes to load all scripts.
\subsubsection{CLOCKS\_PER\_SEC}
The number of clock ticks in one second, a C value depending on your system.
$\frac{1}{CLOCKS\_PER\_SEC}$ is the ninimal time that can be maesured.
\subsubsection{LUA\_MEMORY\_USAGE\_KB}
The memory usage of the Lua environment in kB. This is not the complete memory consumption of your scripts, as some objects like wave files are not stored into Lua, but are allocated in C by the plugin FlyWithLua.
\newpage
\subsection{Lua functions}
The following functions are written in core C++ and are a part of the plugin. Most of them are multi-defined to handle different count of arguments.
\subsubsection{DataRef( "\emph{variable name}", "\emph{DataRef name}" )}
\begin{enumerate}
\item \emph{variable name} = Name of the Lua variable representing the DataRef.
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\end{enumerate}
Binds a Lua variable to a DataRef\footnote{You can spell it \emph{dataref()} instead of \emph{DataRef()}, if you don't like uppercase letters.}. The connection will be forced to readonly. Not possible to array DataRefs.
\subsubsection{DataRef( "\emph{variable name}", "\emph{DataRef name}", "\emph{readonly}" )}
\begin{enumerate}
\item \emph{variable name} = Name of the Lua variable representing the DataRef.
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{readonly} = Should the variable be pushed to X-Plane when it is changed? Say \verb|"readonly"| to have it readonly or \verb|"writable"| to make it writable.
\end{enumerate}
Binds a Lua variable to a DataRef. The connection will be writealbe if you say \verb|"writable"| as the third argument and if the DataRef is writable. Not possible to array DataRefs.
\subsubsection{DataRef( "\emph{variable name}", "\emph{DataRef name}", "\emph{readonly}", \emph{index} )}
\begin{enumerate}
\item \emph{variable name} = Name of the Lua variable representing the DataRef.
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{readonly} = Should the variable be pushed to X-Plane when it is changed? Say \verb|"readonly"| to have it readonly or \verb|"writable"| to make it writable.
\item \emph{index} = The index of an array DataRef.
\end{enumerate}
Binds a Lua variable to a DataRef. The connection will be writalbe if you say \verb|"writable"| as the third argument and if the DataRef is writable. For array DataRefs use a fourth argument, the index starting at 0 (Zero). It will bind the element at the given index. It will not bind an array as a Lua table. Maybe you can bind Lua tables to array DataRefs in later versions of this plugin.
\subsubsection{\emph{DataRef name}, \emph{Index}, \emph{readonly}, \emph{DataRef type}, \emph{DataRef ID} = get\_DataRef\_binding( "\emph{variable name}" )}
\begin{enumerate}
\item \emph{variable name} = Name of the Lua variable representing the DataRef.
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{Index} = The Index of the DataRef. This is always 0 (zero) if the DataRef isn't an array.
\item \emph{readonly} = This results to \verb|true| is the DataRef is readonly and \verb|false| if it's writable.
\item \emph{DataRef type} = Type of the DataRef. 1 = integer, 2 = float, 4 = double, 8 = float array, 16~=~integer array and 32 = data (strings).
\item \emph{DataRef ID} = The ID of the DataRef. A pointer to the memory, the DataRef is stored.
\end{enumerate}
\subsubsection{button( \emph{button number} )}
\begin{enumerate}
\item \emph{button number} = Number of the button, starting at 0 (zero).
\end{enumerate}
Returns the value of the actual state of a joystick button. \verb|button(i)| will result in \verb|true| if the button is pressed, else it gives back \verb|false|. The argument \verb|i| must be an integer, ranging from 0 to 1599. Check out the number in X-Plane's advanced buttons menu.
\subsubsection{last\_button( \emph{button number} )}
\begin{enumerate}
\item \emph{button number} = Number of the button, starting at 0 (zero).
\end{enumerate}
Returns the value of the state of a joystick button, as it was during the last frame. \verb|last_button(i)| will result in \verb|true| if the button was pressed, else it gives back \verb|false|. The argument \verb|i| must be an integer, ranging from 0 to 1599. Check out the number in X-Plane's advanced buttons menu.
\textbf{Advice:}\\
Always use \verb|button()| and \verb|last_button()| to grab joystick values, instead of using\\ \verb|DataRef("MyButton", "sim/joystick/joystick_button_values", "readonly", 123)|, if you like super fast code execution. The functions \verb|button()| and \verb|last_button()| deliver values much efficient than user defined DataRefs.
\subsubsection{create\_switch( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{off value}, \emph{on value} )}
\begin{enumerate}
\item \emph{button number} = Number of the button, starting at 0 (zero).
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{index} = The index of an array DataRef, else 0.
\item \emph{off value} = Value to be set when button is not pressed (off).
\item \emph{on value} = Value to be set when button is pressed (on).
\end{enumerate}
This will turn a joystick buton into a switch controlling a DataRef. If the button is not pressed, the DataRef will be set to the off value, else to the on value. The index is 0 (zero) for non-array DataRefs.
The last three arguments are optional. If you leave them away, Lua will guess 0 for the index and the off value and 1 for the on value. So this will be fine to let button no.~15 control the battery as a real hardware switch:
\verb|>create_switch(15, "sim/cockpit/electrical/battery_on")|
\subsubsection{create\_positive\_edge\_flip( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{first value}, \emph{second value} )}
\begin{enumerate}
\item \emph{button number} = Number of the button, starting at 0 (zero).
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{index} = The index of an array DataRef, else 0.
\item \emph{first value} = Value to be set when button is just pressed (positive edge detecttion).
\item \emph{second value} = Value to be set when button is just pressed but the DataRef's value is equal to the first value.
\end{enumerate}
This is similar to the \verb|create_switch()| function, but it will flip between the two values, given as the last two arguments, every time a positive edge was detected (when the button is pressed just in that moment).
The last three arguments are optional. If you leave them away, Lua will guess 0 for the index and the first value and 1 for the second value. So this will be fine to let button no.~15 control the battery and flip it every time it is pressed:
\verb|>create_positive_edge_flip(15, "sim/cockpit/electrical/battery_on")|
Lua will automatically handle it like this:
\verb|>create_positive_edge_flip(15, "sim/cockpit/electrical/battery_on", 0, 0, 1)|
\subsubsection{create\_negative\_edge\_flip( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{first value}, \emph{second value} )}
\begin{enumerate}
\item \emph{button number} = Number of the button, starting at 0 (zero).
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{index} = The index of an array DataRef, else 0.
\item \emph{first value} = Value to be set when button is just released (positive edge detecttion).
\item \emph{second value} = Value to be set when button is just released but the DataRef's value is equal to the first value.
\end{enumerate}
Nearly the same as the function \verb|create_positive_edge_flip()|, but it will react when the button is released. For an engeneer, this is the negative edge of the button's signal.
\subsubsection{create\_positive\_edge\_trigger( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{value} )}
\begin{enumerate}
\item \emph{button number} = Number of the button, starting at 0 (zero).
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{index} = The index of an array DataRef, else 0.
\item \emph{value} = Value to be set in the moment when button is pressed down (positive signal edge).
\end{enumerate}
This will set the DataRef to the given value in the moment, when the button is pressed down, not during hold. In engineer's words it's a positive edge detection.
\subsubsection{create\_negative\_edge\_trigger( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{value} )}
\begin{enumerate}
\item \emph{button number} = Number of the button, starting at 0 (zero).
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{index} = The index of an array DataRef, else 0.
\item \emph{value} = Value to be set in the moment when button is released (negative signal edge).
\end{enumerate}
This will set the DataRef to the given value in the moment, when the button is released. In engineer's words it's a negative edge detection.
\subsubsection{create\_positive\_edge\_increment( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{stepping}, \emph{limit}, \emph{rounding} )}
\begin{enumerate}
\item \emph{button number} = Number of the button, starting at 0 (zero).
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{index} = The index of an array DataRef, else 0.
\item \emph{stepping} = Value to be added to the DataRef when the button is pressed down (positive signal edge).
\item \emph{limit} = Value that should not be trespass.
\item \emph{rounding} = Value must be a power of ten, the DataRef should be rounded to.
\end{enumerate}
This will increase the DataRef by the given step when the button is pressed down.
The parameter \emph{rounding} is optional. If you give this value to Lua, the DataRef will be rounded.
Here is an example:
\verb|>create_positive_edge_increment(13, "sim/flightmodel/engine/ENGN_cowl", 2, 0.1, 1.0, 0.1)|
This will increase the cowl flap of engine no.~3 (X-Plane starts numbering at 0) by 0.1 up to the limit of 1.0 -- and the result will be rounded to one decimal place. Rounding is only possible to float DataRefs.
\subsubsection{create\_negative\_edge\_increment( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{stepping}, \emph{limit}, \emph{rounding} )}
The same as before, but with negative edge detection (works when the button is released).
\subsubsection{create\_positive\_edge\_decrement( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{stepping}, \emph{limit}, \emph{rounding} )}
Same as before, but decreases the DataRef.
An other example (the radio frequency is an integer DataRef):
\verb|>create_positive_edge_increment(15, "sim/cockpit/radios/com1_freq_hz", 0, 100, 13797)|\\
\verb|>create_positive_edge_decrement(14, "sim/cockpit/radios/com1_freq_hz", 0, 100, 11800)|
\subsubsection{create\_negative\_edge\_decrement( \emph{button number}, \emph{DataRef name}, \emph{index}, \emph{stepping}, \emph{limit}, \emph{rounding} )}
What the hell could this does? ;)
\subsubsection{create\_axis\_median( \emph{axis number}, \emph{variable name} )}
\begin{enumerate}
\item \emph{axis number} = Number of the axis, starting at 0 (zero).
\item \emph{variable name} = Name of the variable to be filled with the median value of the axis.
\end{enumerate}
Calculates a median value of the last five values from an axis and puts it into a Lua variable. This is an example how to store the median value of axis no. 3 (the fourth axis shown in X-Plane, as we start counting with zero) into the variable \emph{median\_throttle}:
\verb|>create_axis_median(3, "median_throttle")|
\subsubsection{get( "\emph{DataRef name}" )}
\begin{enumerate}
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\end{enumerate}
Pulling a DataRef to Lua. This function returns one value pulled from the DataRef. Slower than the automatic pull, but does not need a variable. Good for initial scripts or macros. Highly not recommended in callbacks. This is the version used for non array DataRefs. If you try to pull an array DataRef with this function, you will get the first element of the array.
An easy way of reading out a DataRef with the XSquawkBox's input line. Check DataRefs like this:
\verb|>print(get("sim/aircraft/weight/acf_m_fuel_tot"))|
\subsubsection{get( "\emph{DataRef name}", \emph{index} )}
\begin{enumerate}
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{index} = The index of an array DataRef.
\end{enumerate}
Pulling a DataRef to Lua. This function returns one value pulled from the DataRef. Slower than the automatic pull, but does not need a variable. Good for initial scripts or macros. Highly not recommended in callbacks. This is the version used for array DataRefs.
\newpage
\subsubsection{set( "\emph{DataRef name}", \emph{value} )}
\begin{enumerate}
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{value} = The value you want to push to the DataRef.
\end{enumerate}
Pushing a given value to a DataRef. Not possible for array or string DataRefs. The set function is slower than the automatic pushing of variables to DataRefs. But on the other hand it will not create a global variable. This can provide getting in confict between multiple scripts using the same variable for different DataRefs, a situation normally crashing the system.
Use the set function to fill DataRefs during startup (typically config files) or in macros, when you only need to push the values (and do not need to pull them into Lua variables).
\subsubsection{set\_array( "\emph{DataRef name}", \emph{index}, \emph{value} )}
\begin{enumerate}
\item \emph{DataRef name} = Name of the DataRef. Look at the \href{http://www.xsquawkbox.net/xpsdk/docs/DataRefs.html}{listing of all DataRefs}.
\item \emph{index} = The index of an array DataRef.
\item \emph{value} = The value you want to push to the DataRef.
\end{enumerate}
Does the same as the \verb|set()| function, but to be used for array DataRefs.
\subsubsection{set\_button\_assignment( \emph{button number}, "\emph{simulator function}")}
\begin{enumerate}
\item \emph{button number} = Number of the button (starting with 0).
\item \emph{simulator function} = Name of the function you want to assign. You can copy\&paste the name from X-Plane's advanced button setting menu. Must be a string, don't forget the brackets.
\end{enumerate}
Assigning a function given by X-Plane to a joystick button. The same as clicking it inside the advanced button settings menu. Usefull to make different configs for different planes or situations.
\newpage
\subsubsection{set\_axis\_assignment( \emph{axis number}, "\emph{axis function}", "\emph{reverse}")}
\begin{enumerate}
\item \emph{axis number} = Number of the axis (starting with 0). Since X-Plane 10.10 Austin forces you to guess the numbers or to view inside the config files. Counting them inside the menu is no longer possible. Please ask him why he did it, not me.
\item \emph{axis function} = Name of the function you want to assign. You can copy\&paste the name from X-Plane's advanced button setting menu. Must be a string, don't forget the brackets.
\item \emph{reverse} = a string telling X-Plane to reverse the axis if the value is \verb|"reverse"| or to set a normal axis if the value is \verb|"normal"|.
\end{enumerate}
Assigning axis functions. Possible values for the function names are: \verb|"none"|, \verb|"pitch"|, \verb|"roll"|, \verb|"yaw"|, \verb|"throttle"|, \verb|"collective"|, \verb|"left toe brake"|, , \verb|"right toe brake"|, \verb|"prop"|, \verb|"mixture"|, \verb|"carb heat"|, \verb|"flaps"|, \verb|"thrust vector"|, \verb|"wing sweep"|, \verb|"speedbrakes"|, \verb|"displacement"|, \verb|"reverse"|, \verb|"elev trim"|, \verb|"ailn trim"|, \verb|"rudd trim"|, \verb|"throttle 1"|, \verb|"throttle 2"|, \verb|"throttle 3"|, \verb|"throttle 4"|, \verb|"prop 1"|, \verb|"prop 2"|, \verb|"prop 3"|, \verb|"prop 4"|, \verb|"mixture 1"|, \verb|"mixture 2"|, \verb|"mixture 3"|, \verb|"mixture 4"|, \verb|"reverse 1"|, \verb|"reverse 2"|, \verb|"reverse 3"|, \verb|"reverse 4"|, \verb|"landing gear"|, \verb|"nosewheel tiller"|, \verb|"backup throttle"|, \verb|"auto roll"|, \verb|"auto pitch"|, \verb|"view left/right"|, \verb|"view up/down"|, \verb|"view zoom"|, \verb|"camera left/right"|, \verb|"camera up/down"|, \verb|"camera zoom"|,
\verb|"gun/bomb left/right"| and \verb|"gun/bomb up/down"|.
\subsubsection{clear\_all\_axis\_assignments()}
Sets all assignments to \verb|"none"|.
\subsubsection{clear\_all\_button\_assignments()}
Sets all assignments to \verb|"sim/none/none"|.
\subsubsection{set\_pilots\_head( \emph{x}, \emph{y}, \emph{z}, \emph{heading}, \emph{pitch} )}
\begin{enumerate}
\item \emph{x}, \emph{y}, \emph{z} = Position of pilot's head relative to the plane.
\item \emph{heading} = The heading of pilot's head.
\item \emph{pitch} = The pitch of pilot's head.
\end{enumerate}
This will set the pilot's head in position and angle. If we are not in 3D view, 3D view will be set.
\subsubsection{\emph{x}, \emph{y}, \emph{z}, \emph{heading}, \emph{pitch} = get\_pilots\_head( )}
\begin{enumerate}
\item \emph{x}, \emph{y}, \emph{z} = Position of pilot's head relative to the plane.
\item \emph{heading} = The heading of pilot's head.
\item \emph{pitch} = The pitch of pilot's head.
\end{enumerate}
This will get the pilot's head position and angle.
\subsubsection{command\_once( "\emph{simulator function}" )}
\begin{enumerate}
\item \emph{simulator function} = Name of the function you want to assign. You can copy\&paste the name from X-Plane's advanced button setting menu.
\end{enumerate}
Execute a simulator given command only one time.
\subsubsection{logMsg( "\emph{string}" )}
\begin{enumerate}
\item \emph{string} = What you want to say.
\end{enumerate}
Write a string into the \verb|Log.txt| file in X-Plane's main directory. You can take a look into the log file by assigning a button to the simulator function \verb|"sim/operation/dev_console"|. Or you choose the viewing toggle from the specials menu.
\subsubsection{XSBSpeakString( "\emph{string}" )}
\begin{enumerate}
\item \emph{string} = What you want to say.
\end{enumerate}
Write a string into the XSquawkBox. The string will not be send to other pilots or controllers when connected to VATSIM. Only to give you an easy way to print notes on the screen.
\subsubsection{XPLMSpeakString( "\emph{string}" )}
\begin{enumerate}
\item \emph{string} = What you want to say.
\end{enumerate}
Write a string onto the screen for a few seconds and speaks the string if text-to-speak is enabled. This function will return immediately, the string will be spoken asynchronously. If you fire up multiple strings at once, you will get a confusing mix. So take care of timing.
\newpage
\subsubsection{print( "\emph{string}" )}
\begin{enumerate}
\item \emph{string} = What you want to say.
\end{enumerate}
Similar to \verb|XSBSpeakString()|, but uses it's own box to display. All text will be displayed for 5 seconds, then the box fades away. To display the box again, you can move the mouse pointer to the top of the screen. To scroll through the lines, just move the mouse pointer left or right.
\subsubsection{do\_sometimes( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be calculated every 10 sec.
\end{enumerate}
Calculates a string of Lua code from time to time.
\subsubsection{do\_often( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be calculated every sec.
\end{enumerate}
Calculates a string of Lua code very often.
\subsubsection{do\_every\_frame( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be calculated every single frame.
\end{enumerate}
Calculates a string of Lua code every single frame. Can slow down the simulator at a glance. Use this function carefully!
\subsubsection{do\_every\_draw( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be calculated every single draw.
\end{enumerate}
Calculates a string of Lua code every single draw. Seems to be the same as \verb|do_every_frame()|, but it is different. Only in this drawing callback you are able to draw things like colored text. To save CPU time, the automatic DataRefs to variables transfer is disabled during a draw callback. So do not read or write DataRefs, use it only to draw your messages.
Can slow down the simulator at a glance. Use this function carefully!
\subsubsection{do\_on\_keystroke( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be calculated every time when the user presses or releases a key.
\end{enumerate}
When the user (pilot) presses or releases a key, a keystroke event starts your Lua code given by this function. Lua provides these special variables, the last one is writable:
\begin{enumerate}
\item \emph{VKEY} = An integer value representing the key you pressed. Play around with this value a little bit, it is not the ASCII value.
\item \emph{CKEY} = The key as a char (string with a single letter).
\item \emph{SHIFT\_KEY} = A boolean value, representing the state of the shift key. If a shift key is pressed, the value is \verb|true|, else \verb|false|.
\item \emph{OPTION\_KEY} = A boolean value, representing the state of the option or alt key. If an option or alt key is pressed, the value is \verb|true|, else \verb|false|.
\item \emph{CONTROL\_KEY} = A boolean value, representing the state of the control key. If a control key is pressed, the value is \verb|true|, else \verb|false|.
\item \emph{KEY\_ACTION} = A string either resulting in \verb|"pressed"| or \verb|"released"|, depending on the user action.
\item \emph{RESUME\_KEY} = A boolean value. If it is set to \verb|true| your script will resume the keystroke and X-Plane will not recognize it. Default value is \verb|false|, to not disturb X-Plane or other plugins.
\end{enumerate}
\subsubsection{do\_on\_mouse\_wheel( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be calculated every time when the user presses, holds down or releases the primary mouse button.
\end{enumerate}
When the user (pilot) moves a mouse wheel, an event handler starts your Lua code given by this function. Lua provides these special variables, the last one is writable:
\begin{enumerate}
\item \emph{MOUSE\_WHEEL\_NUMBER} = An positive integer value starting with 0 (zero), indicating what wheel causes the event. Some operating systems allow more than one mouse wheel. If not, it will be always 0.
\item \emph{MOUSE\_WHEEL\_CLICKS} = An integer value indicating the number of steps the user moved the wheel. Can be positive or negative depending on the moving direction.
\item \emph{RESUME\_MOUSE\_WHEEL} = A boolean value. If it is set to \verb|true| your script will resume the mouse wheel movement and X-Plane will not recognize it. Default value is \verb|false|, to not disturb X-Plane or other plugins.
\end{enumerate}
\subsubsection{do\_on\_mouse\_click( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be calculated every time when the user presses, holds down or releases the primary mouse button.
\end{enumerate}
When the user (pilot) presses, holds or releases the primary mouse button, an event handler starts your Lua code given by this function. Lua provides these special variables, the last one is writable:
\begin{enumerate}
\item \emph{MOUSE\_STATUS} = A string either \verb|"down"|, \verb|"drag"| or \verb|"up"|. \verb|"down"| says, the user just starts pressing the button, \verb|"drag"| means, he holds down the mouse button and if he releases the button, you get \verb|"up"|.
\item \emph{RESUME\_MOUSE\_CLICK} = A boolean value. If it is set to \verb|true| your script will resume the mouse click and X-Plane will not recognize it. Default value is \verb|false|, to not disturb X-Plane or other plugins.
\end{enumerate}
\subsubsection{do\_on\_new\_metar( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be calculated every time when the plugin receives a new METAR from XSquawkBox.
\end{enumerate}
This is called by a XSquawkBox event. You can read out the predefined variable \verb|XSB_METAR|, or do whatever you like when XSquawkBox sends a new METAR (changes the weather).
\subsubsection{do\_on\_exit( "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{Lua code string} = A string containing Lua code you want to be executed when Lua stops. The will be executed only on normal stops, like changing the airport or aircraft or shutting down X-Plane. The code can/will not be execuded on errors.
\end{enumerate}
Use this function to collect code that is executed when Lua stops working because of a script reload. This is not for error handling, but can be usefull if you want to store values to disk for the next time you start Lua.
\subsubsection{draw\_string( \emph{x}, \emph{y}, "\emph{string}" )}
\begin{enumerate}
\item \emph{x} = Horizontally position where you want to draw. Starts on the left side from 0 (Zero).
\item \emph{y} = Vertically position where you want to draw. Starts from the bottom with value 0 (Zero).
\item \emph{string} = The string you want to see on top of the screen.
\end{enumerate}
Prints a string onto the screen. Will only work during draw callbacks. The color is set to white.
The drawing system is for advanced users only!
\subsubsection{draw\_string( \emph{x}, \emph{y}, "\emph{string}", "\emph{color}" )}
\begin{enumerate}
\item \emph{x} = Horizontally position where you want to draw. Starts on the left side from 0 (Zero).
\item \emph{y} = Vertically position where you want to draw. Starts from the bottom with value 0 (Zero).
\item \emph{string} = The string you want to see on top of the screen.
\item \emph{color} = A string describing the color you want to choose.
\end{enumerate}
Prints a string onto the screen. Will only work during draw callbacks. The color can be \verb|"white"|, \verb|"black"|, \verb|"grey"|, \verb|"red"|, \verb|"green"|, \verb|"blue"|, \verb|"yellow"|, \verb|"magenta"| or \verb|"cyan"|.
The drawing system is for advanced users only!
\subsubsection{draw\_string( \emph{x}, \emph{y}, "\emph{string}", \emph{red}, \emph{green}, \emph{blue} )}
\begin{enumerate}
\item \emph{x} = Horizontally position where you want to draw. Starts on the left side from 0 (Zero).
\item \emph{y} = Vertically position where you want to draw. Starts from the bottom with value 0 (Zero).
\item \emph{string} = The string you want to see on top of the screen.
\item \emph{red} = A float value from 0.0 to 1.0 choosing the red part of a RGB color.
\item \emph{green} = A float value from 0.0 to 1.0 choosing the green part of a RGB color.
\item \emph{blue} = A float value from 0.0 to 1.0 choosing the blue part of a RGB color.
\end{enumerate}
If the predefined color don't fit your needs, choose a custom RGB value.
The drawing system is for advanced users only!
\subsubsection{draw\_string\_Helvetica\_10( \emph{x}, \emph{y}, "\emph{string}" )}
\begin{enumerate}
\item \emph{x} = Horizontally position where you want to draw. Starts on the left side from 0 (Zero).
\item \emph{y} = Vertically position where you want to draw. Starts from the bottom with value 0 (Zero).
\item \emph{string} = The string you want to see on top of the screen.
\end{enumerate}
Prints a string onto the screen. Will only work during draw callbacks.
This will print the text to screen using the GLUT library instead of the X-Plane SDK. So you will have to set the color first by \verb|glColor4f(red, green, blue, alpha)|. It will print the text using the bitmap font \verb|GLUT_BITMAP_HELVETICA_10|.
\subsubsection{draw\_string\_Helvetica\_12( \emph{x}, \emph{y}, "\emph{string}" )}
The same as above, but using the bitmap font \verb|GLUT_BITMAP_HELVETICA_12|.
\subsubsection{draw\_string\_Helvetica\_18( \emph{x}, \emph{y}, "\emph{string}" )}
The same as above, but using the bitmap font \verb|GLUT_BITMAP_HELVETICA_18|.
\subsubsection{draw\_string\_Times\_Roman\_10( \emph{x}, \emph{y}, "\emph{string}" )}
The same as above, but using the bitmap font \verb|GLUT_BITMAP_TIMES_ROMAN_10|.
\subsubsection{draw\_string\_Times\_Roman\_24( \emph{x}, \emph{y}, "\emph{string}" )}
The same as above, but using the bitmap font \verb|GLUT_BITMAP_TIMES_ROMAN_24|.
\subsubsection{measure\_string( "\emph{string}" )}
\begin{enumerate}
\item \emph{string} = The string you want to measure.
\end{enumerate}
Returns the length of a given string in screen pixel as a float number. Calculation is based on the standard proportional font used by \verb|draw_string()|.
\subsubsection{measure\_string( "\emph{string}", "\emph{font name}" )}
\begin{enumerate}
\item \emph{string} = The string you want to measure.
\item \emph{font name} = The name of the font for use with GLUT.
\end{enumerate}
Returns the length of a given string in screen pixel as an integer number. Calculation is based on the font given by the second argument. It can be \verb|Helvetica_10|, \verb|Helvetica_12|, \verb|Helvetica_18|, \verb|Times_Roman_10| or \verb|Times_Roman_24|.
\subsubsection{\emph{hight}, \emph{width} = bubble( \emph{x}, \emph{y}, "\emph{title}", $\dots$ )}
\begin{enumerate}
\item \emph{x} = Horizontally position where you want to draw the bubble. Starts on the left side from 0 (Zero).
\item \emph{y} = Vertically position where you want to draw the bubble. Starts from the bottom with value 0 (Zero).
\item \emph{title} = The string you want to see on top of the bubble in a slightly bigger font size.
\item .~.~. = An optional set of strings for the text lines. Each line must be a single string argument without an CR/LF in it.
\end{enumerate}
The function \verb|bubble()| is only allowed inside the drawing loop callback. So only use it with \verb|do_every_draw()| -- or you will see no result. The two returned arguments will give you the maximum x and y screen coordinate the bubble will use.
The scripts \verb|QNH_helper.lua| and \verb|bubble copilot.lua| will show you some examples how to use bubbles.
\subsubsection{\emph{hight}, \emph{width} = big\_bubble( \emph{x}, \emph{y}, "\emph{title}", $\dots$ )}
The same as \verb|bubble()|, but with a bigger font size.
\subsubsection{\emph{hight}, \emph{width} = huge\_bubble( \emph{x}, \emph{y}, "\emph{title}", $\dots$ )}
The same as \verb|bubble()|, but with a much bigger font size.
\subsubsection{add\_macro( "\emph{macro name}", "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{macro name} = Name of the macro. This string is used for the menu entry.
\item \emph{Lua code string} = A string containing Lua code you want to be calculated when the user clicks on the menu entry.
\end{enumerate}
Make a menu entry to calculate a little piece of Lua code on demand.
\subsubsection{add\_ATC\_macro( "\emph{macro name}", "\emph{Lua code string}" )}
\begin{enumerate}
\item \emph{macro name} = Name of the macro. This string is used for the menu entry.
\item \emph{Lua code string} = A string containing Lua code you want to be calculated when the user clicks on the menu entry.
\end{enumerate}
Make a menu entry to calculate a little piece of Lua code on demand. Menu entry will be created inside the ATC menu, instead of the macro menu. Nice to collect some radio settings for recurrent situations like flying home to your base airport. Can save a lot of clicks.
\subsubsection{add\_macro( "\emph{macro name}", "\emph{activation code string}", "\emph{deactivation code string}", "\emph{default state}" )}
\begin{enumerate}
\item \emph{macro name} = Name of the macro. This string is used for the menu entry.
\item \emph{activation code string} = A string containing Lua code you want to be calculated when the user turns on the menu item.
\item \emph{deactivation code string} = A string containing Lua code you want to be calculated when the user turns off the menu item.
\item \emph{default state} = A string either \verb|"activate"| or \verb|"deactivate"| to define the default state of the menu entry.
\end{enumerate}
Creating a menu entry with a switch. Only possible for macro menu, not for the ATC menu. See the tutorial above for an example (auto setting the transponder).
\subsubsection{create\_command( "\emph{command name}", "\emph{command description}", "\emph{begin code string}", "\emph{continue code string}", "\emph{end code string}" )}
\begin{enumerate}
\item \emph{command name} = Name of the command, as X-Plane wants it to be (slash separated).
\item \emph{command description} = A string describing your command. Can be found in X-Plane's keyboard and joystick menu.
\item \emph{begin code string} = A string containing Lua code you want to be calculated when the command begins.
\item \emph{continue code string} = A string containing Lua code you want to be calculated when the command continues (one per frame).
\item \emph{end code string} = A string containing Lua code you want to be calculated when the command ends.
\end{enumerate}
Creates a classic custom command. As you can check button states and call Lua functions direct in every frame loops, custom commands are pretty useless.
If you want to script a classic command to provide a nice new feature to the X-Plane universe, keep in mind that all of your little script have to contain classic code. Do not use modern code (variables connected to DataRefs). You will never know if the user, who downloaded your custom command script file, will use the same writable DataRef with a different variable name. If so, FlyWithLua will stop working and presents an error message.
\textbf{Attention:} Never use a custom command name like "sim/...", or Austin will kill you.
There is a demo script >>\verb|test command.lua|<<, showing how to use this powerful feature. And the QNH tool >>\verb|automatic set qnh.lua|<< will also provide a custom command.
\subsubsection{\emph{table} = directory\_to\_table( "\emph{path}" )}
\begin{enumerate}
\item \emph{table} = A variable you want to be filled with a Lua table containing all filenames inside the given directory.
\item \emph{path} = A string with the path of the directory. The path can be written in Unix stile, independent from the OS FlyWithLua is running on.
\end{enumerate}
Will return a simple table containing all filenames in alphabetical order. Only the filenames are returned, without the path.
\subsubsection{place\_aircraft\_at( "\emph{ICAO}" )}
\begin{enumerate}