Author: Mu Feng
In this article, I would like to introduce you to Lua program design. I suppose everyone has learned at least one programming language, such as basic or C, especially C. Because Lua is used as a script in the Host Program for the maximum purpose.
Lua's syntax is relatively simple and easier to learn, but its functions are not weak.
In Lua, everything is a variable except a keyword. Remember this sentence.
I. annotation first
Writing a program is always without comments.
In Lua, you can use single-line and multi-line annotations.
In a single line comment, two consecutive minus signs "--" indicate the start of the comment until the end of the line. It is equivalent to "//" in C ++ "//".
In multi-line comments, the Comment starts from "-- [" and continues. This annotation is equivalent "/*... */". In comments, "[[" and "]" can be nested.
Ii. Lua Programming
A classic "Hello World" program is always used to introduce a language. In Lua, writing such a program is simple:
Print ("Hello World ")
In Lua, statements can be separated by semicolons (;) or blank spaces. Generally, if multiple statements are written in the same row, we recommend that you use semicolons to separate them.
Lua has several program control statements, such:
Conditional Control: If condition then... Elseif condition then... Else... End
While loop: While condition do... End
Repeat loop: Repeat... Until Condition
For Loop: for variable = initial value, end value, step do... End
For Loop: for variable 1, variable 2 ,... , Variable N in table or enumeration function do... End
Note that the for Loop Variable always acts only on the partial variable of the for, you can also omit the step value, at this time, the for Loop will use 1 as the step value.
You can use break to stop a loop.
If you have the foundation of programming, such as Basic and C, you will feel that Lua is not difficult. However, Lua has several differences from these programming languages, so pay special attention to them.
. Statement Block
The statement block is enclosed by "{" and "}" in C ++. In Lua, It is enclosed by do and end. For example:
Do print ("Hello") end
You can set local variables in functions and statement blocks.
. Assignment Statement
The value assignment statement is enhanced in Lua. It can assign values to multiple variables at the same time.
For example:
A, B, c, d = 1, 2, 3, 4
Even:
A, B = B, a -- how convenient the variable exchange function is.
By default, variables are always considered global. If you want to define a local variable, you must use local to describe it during the first assignment. For example:
Local a, B, c = 1, 2, 3 -- a, B, c are local variables
. Numeric operation
Like the C language, it supports + ,-,*,/. But Lua has another "^ ". This indicates exponential multiplication. For example, the result of 2 ^ 3 is 8, and the result of 2 ^ 4 is 16.
Connect two strings. You can use the ".." operator. For example:
"This a"... "string." -- equal to "this a string"
. Comparison operation
<> <= >== ~ =
They indicate less than, greater than, not greater than, not less than, equal, not equal
All these operators always return true or false.
For Table, Function, and Userdata data, only = and ~ = Available. The two variables reference the same data. For example:
A = {1, 2}
B =
Print (a = B, ~ = B) -- true, false
A = {1, 2}
B = {1, 2}
Print (a = B, ~ = B) -- false, true
. Logical operation
And, or, not
And or differ significantly from C.
Here, remember that in Lua, only false and nil are calculated as false, and any other data is calculated as true, and 0 is also true!
The operation result of and or is not true or false, but related to its two operands.
A and B: If a is false, a is returned; otherwise, B is returned.
A or B: if a is true, a is returned; otherwise, B is returned.
For example:
Print (4 and 5) --> 5
Print (nil and 13) --> nil
Print (false and 13) --> false
Print (4 or 5) --> 4
Print (false or 5) --> 5
This is a very useful feature in Lua, and it is also a hybrid feature.
We can simulate the C language statement: x =? B: C. In Lua, it can be written as: x = A and B or C.
The most useful statement is: x = X or V, which is equivalent to: If not X then x = V end.
. Operator priority. The order from high to low is as follows:
^
Not-(mona1 Operation)
*/
+-
.. (String connection)
<> <=> = ~ ===
And
Or
Iii. Keywords
Keywords cannot be used as variables. There are not many Lua keywords, just the following:
And break do else elseif
End false for function if
In local nil not or
Repeat return then true until while
Iv. Variable type
How can we determine the type of a variable? You can use the type () function to check. Lua supports the following types:
Nil null. All unused variables are nil. Nil is both a value and a type.
Boolean Value
Number value. In Lua, the value is equivalent to double in C.
String. If you want to, the String can contain ''characters.
Table relational Table type, which has powerful functions. Let's talk about it later.
Function type. Do not doubt that a Function is also a type. That is to say, all functions are a variable.
Userdata: Well, this type is used to deal with Lua's host. Generally, the host is written in C and C ++. In this case, Userdata can be any data type of the host, usually including Struct and pointer.
Thread type. There is no real Thread in Lua. In Lua, a function can be divided into several parts for running. If you are interested, you can go to Lua's documents.
V. variable definition
Variables are used in all languages. In Lua, no matter where you use variables, you do not need to declare them, and all these variables are always global variables unless you add "local" in front ".
Pay special attention to this, because you may want to use local variables in the function, but forget to use local to describe.
Variable names are case-sensitive. That is to say, A and a are two different variables.
To define a variable, assign a value. "=" Operations are used to assign values.
Let's define several common types of variables.
A. Nil
As mentioned above, the values of unused variables are all Nil. Sometimes we also need to clear a variable. At this time, we can directly assign the variable a nil value. For example:
Var1 = nil -- note that nil must be in lowercase.
B. Boolean
Boolean values are usually used for condition determination. There are two types of Boolean values: true and false. In Lua, only false and nil are calculated as false, and all other types of values are true. For example, 0 and null strings are all true. Do not be misled by the C language habits. 0 is true in Lua. You can also assign a Boolean value to a variable, for example:
Varboolean = true
C. Number
In Lua, there is no integer type and it is not required. Generally, as long as the value is not very large (for example, it cannot exceed 100,000,000,000,000), there will be no rounding error. In many CPUs, real number operations are not slower than integers.
The representation of real numbers, similar to the C language, for example:
4 0.4 4.57e-3 0.3e12 5e + 20
D. String
String is always a very common advanced type. In Lua, you can easily define long and long strings.
There are several methods to represent a string in Lua. The most common method is to enclose a string with double quotation marks or single quotation marks, for example:
"This is a string ."
Similar to the C language, it supports some escape characters. The list is as follows:
A bell
B back space
F form feed
N newline
R carriage return
T horizontal tab
V vertical tab
\ Backslash
"Double quote
'Single quote
[Left square bracket
] Right square bracket
Because such a string can only be written in one row, it is inevitable to use escape characters. It seems that the strings with escape characters are not flattering, for example:
"One linennext linen" in quotes ", 'in quotes '"
A lot of "" symbols make people look quite appetizing. If you share the same feelings with me, we can use another Representation Method in Lua: Enclose strings of multiple rows with "[[" and, for example:
Page = [[
<HTML>
<HEAD>
<TITLE> An HTML Page </TITLE>
</HEAD>
<BODY>
<A href = "http://www.lua.org"> Lua </A>
[[A text between double brackets]
</BODY>
</HTML>
]
It is worth noting that if this string contains a separate "[[" or "]", "[" or "]" is still used to avoid ambiguity. Of course, this situation rarely happens.
E. Table
Relational table type, which is a very powerful type. We can regard this type as an array. Only arrays in C language can be indexed using positive integers. In Lua, You Can index arrays of any type, except nil. Similarly, in C language, the array content can only be one type. In Lua, you can also use any type of value as the array content, except nil.
The definition of Table is very simple. Its main feature is to use "{" and "}" to enclose a series of data elements. For example:
T1 ={} -- Define an empty table
T1 [1] = 10 -- then we can use it like the C language.
T1 ["John"] = {Age = 27, Gender = "Male "}
This sentence is equivalent:
T1 ["John"] ={} -- must be defined as a table first. Do you still remember that the undefined variable is of the nil type?
T1 ["John"] ["Age"] = 27
T1 ["John"] ["Gender"] = "Male"
When the index of a table is a string, it can be abbreviated:
T1.John = {}
T1.John. Age = 27
T1.John. Gender = "Male"
Or
T1.John {Age = 27, Gender = "Male "}
This is a strong feature.
When defining a table, we can write all the data content between "{" and "}". This is very convenient and nice-looking. For example, the previous T1 definition can be written as follows:
T1 =
{
10, -- equivalent to [1] = 10
[100] = 40,
John = -- If you intend, you can also write it as: ["John"] =
{
Age = 27, -- If you intend, you can also write it as: ["Age"] = 27
Gender = Male -- if you are interested, you can also write it as: ["Gender"] = Male
},
20 -- equivalent to [2] = 20
}
It looks pretty, isn't it? Note the following three points when writing:
First, all elements are separated by commas;
Second, all index values must be enclosed by "[" and "]". If it is a string, you can also remove the quotation marks and brackets;
Third, if no index is written, the index will be regarded as a number and will be automatically edited from 1 in order;
The construction of table types is so convenient that they are often used instead of configuration files. Yes, you don't have to worry about it. It is more beautiful and powerful than the INI file.
F. Function
Function. In Lua, the function definition is also very simple. A typical definition is as follows:
Function add (a, B) -- add is the function name, And a and B are the parameter names.
Return a + B -- return is used to return the function running result.
End
Note that the return language must be written before the end. If you have to put a return statement in the middle, write it as do return end.
Do you remember that the function is also a variable type? The above function definition is actually equivalent:
Add = function (a, B) return a + B End
When you assign a value to add again, it no longer indicates this function. You can even assign add arbitrary data, including nil (in this way, you can clear the Add variable ). Is a function like a function pointer in C?
Like the C language, Lua functions can accept the number of variable parameters. It also uses "... "To define, such:
Function sum (a, B ,...)
If you want to obtain... The parameter can be obtained by accessing the ARG local variable (Table type) in the function.
Such as sum (1, 2, 3, 4)
Then, in the function, a = 1, B = 2, Arg = {3, 4}
More importantly, it can return multiple results at the same time, for example:
Function S ()
Return 1, 2, 3, 4
End
A, B, c, d = S () -- at this time, a = 1, B = 2, c = 3, D = 4
As mentioned above, the table type can have any type of values, including functions! Therefore, a very powerful feature is that tables with functions, oh, I think it should be more appropriate to say that it is an object. Lua can use object-oriented programming. Believe it? Here is an example:
T =
{
Age = 27
Add = function (self, n) self. Age = self. Age + N end
}
Print (T. Age) -- 27
T. Add (T, 10)
Print (t. Age) -- 37
However, the sentence t. add (t, 10) is a bit earthy, right? It doesn't matter. In Lua, You Can abbreviated it:
T: add (10) -- equivalent to t. add (t, 10)
G. Userdata and Thread
These two types of topics are beyond the content of this article and will not be discussed in detail.
VI. Concluding remarks
Is that the end? Of course not. Next, you need to use the Lua interpreter to help you understand and practice it. This article only helps you understand the Lua syntax. If you have a programming Foundation, I believe you will soon get started with Lua.
Like the C language, Lua provides a considerable number of standard functions to enhance language functions. With these standard functions, you can easily operate various data types and process input and output. For this information, you can refer to the book Programming in Lua, you can directly watch the electronic version on the network, web site: http://www.lua.org/pil/index.html
Of course, Lua's most powerful feature is its ability to work closely with the Host Program. Therefore, in the next article, I will tell you how to use Lua as a script in your program, make your program interact with the Lua script.
Bytes ---------------------------------------------------------------------------------------------------------
Procedure
1. Use of functions
The following program demonstrates how to use functions and local variables in Lua.
Example e02.lua
-- Functions
Function pythagorean (a, B)
Local C2 = a ^ 2 + B ^ 2
Return SQRT (C2)
End
Print (Pythagorean (3, 4 ))
Running result
5
Program description
In Lua, The Function Definition Format is:
Function Name (parameter)
...
End
Unlike Pascal, end does not need to be paired with begin. You only need to end the function.
In this example, the function is used to obtain the diagonal side of a right triangle and obtain the length of the oblique side. parameters a and B indicate the length of the right side, respectively,
The local variable is defined in the function to store the square of the oblique edge. It is the same as the C language and defined in the function.
The code will not be executed directly, and will be executed only when the main program is called.
Local indicates defining a local variable. If the local variable is not added, C2 is a global variable, and the local scope
Is between the end of the innermost layer and the matched keywords, such as if... end, while... end. Global variable
The scope is the whole program.
2. Loop statements
Example e03.lua
-- Loops
For I = 1, 5 do
Print ("I is now" .. I)
End
Running result
I is now 1
I is now 2
I is now 3
I is now 4
I is now 5
Program description
Here we use the for statement.
For variable = parameter 1, parameter 2, parameter 3 do
Loop body
End
The variable takes parameter 3 as the step, and changes from parameter 1 to parameter 2.
For example:
For I = 1, F (x) Do print (I) End
For I = 10, 1,-1 do print (I) End
In Print ("I is now" .. I), we use..., which is used to connect two strings,
Even if I try to see what I mentioned in (1), I don't know if you have answered correctly.
Although I is an integer here, Lua will automatically convert it into a string type during processing, without worrying about it.
3. Condition branch statement
Example e04.lua
-- Loops and conditionals
For I = 1, 5 do
Print ("I is now" .. I)
If I <2 then
Print ("small ")
Elseif I <4 then
Print ("medium ")
Else
Print ("big ")
End
End
Running result
I is now 1
Small
I is now 2
Medium
I is now 3
Medium
I is now 4
Big
I is now 5
Big
Program description
If else is easy to use, similar to the C language, but note that the entire if only needs an end,
Even if multiple elseif are used, it is also an end.
For example
If op = "+" then
R = a + B
Elseif op = "-" then
R = a-B
Elseif op = "*" then
R = a * B
Elseif op = "/" then
R = a/B
Else
Error ("invalid operation ")
End
4. Try again
In addition to the for loop, Lua also supports multiple loops. Use the while... do and repeat... until to rewrite the for program in this article.
Bytes ----------------------------------------------------------------------------------------------------------
Use of Arrays
1. Introduction
Lua has only one basic data structure, that is, table. All other data structures, such as arrays,
Can be implemented by table.
2. table subscript
Example e05.lua
-- Arrays
MyData = {}
MyData [0] = "foo"
MyData [1] = 42
-- Hash tables
MyData ["bar"] = "baz"
-- Iterate through
-- Structure
For key, value in myData do
Print (key .. "=" .. value)
End
Output result
0 = foo
1 = 42
Bar = baz
Program description
First define a table myData = {}, and then use a number as the subscript to assign two values to it.
The definition method is similar to the array in C, but unlike the array, each array element does not need to be of the same type,
In this example, one is an integer and the other is a string.
The second part of the program uses the string as the subscript and adds an element to the table.
The map. table subscript in STL can be any basic type supported by Lua, except for the nil value.
Lua automatically processes Table memory usage, as shown in the following code:
A = {}
A ["x"] = 10
B = a -- 'B' refers to the same table as 'A'
Print (B ["x"]) --> 10
B ["x"] = 20
Print (a ["x"]) --> 20
A = nil -- now only 'B' still refers to the table
B = nil -- now there are no references left to the table
Both B and a point to the same table and only occupy one piece of memory. When a = nil is executed, B still points to table,
When B = nil is executed, Lua Automatically releases the memory occupied by the table because it does not point to the table variable.
3. Table nesting
Table can also be nested, as shown in the following example.
Example e06.lua
-- Table 'constructor'
MyPolygon = {
Color = "blue ",
Thickness = 2,
Npoints = 4;
{X = 0, y = 0 },
{X =-10, y = 0 },
{X =-5, y = 4 },
{X = 0, y = 4}
}
-- Print the color
Print (myPolygon ["color"])
-- Print it again using dot
-- Notation
Print (myPolygon. color)
-- The points are accessible
-- In myPolygon [1] to myPolygon [4]
-- Print the second point's x
-- Coordinate
Print (myPolygon [2]. x)
Program description
First, create a table. Different from the previous example, In the constructor of the table, there are {x = 0, y = 0 },
What does this mean? This is actually a small table, defined in the big table, the small table
The table name is omitted.
The last line of myPolygon [2]. x is the access method for small tables in large tables.
Bytes -----------------------------------------------------------------------------------------------------------
How to simplify your macros.
Although the above introduction allows us to understand that daohong can provide very powerful functions, blizzard is so stingy that it only gives us 255 characters to write the macro content, if your macro functions are too technical, it will be very troublesome. So I will introduce some tips to simplify macros:
1. Define global variables
All the variables in Lua are global variables. That is to say, if you define any variable after you start the game, by the end of the game, as long as you do not redefine it, it will be effective. However, in order not to confuse global variables with local variables, we can use case-sensitive methods, that is, all uppercase variables are used as global variables, and all lowercase variables use local variables.
In this way, we can define our commonly used magic/skills as variables in a macro to represent them. For example, if I am a, we can do this:
F = "corrosion technique (grade 3)" X = "Sacrifice (grade 3 )".......
Then, when we want to use such magic, we only need to use F or X to replace it. Even "" can be saved, isn't it very convenient ~
You can also define some common API function variables:
T = "target" P = "player ".....
It is used in the same way as above.
2. User-Defined Functions
To be honest, some functions of warcraft are too long, and many times the precious bytes are occupied by functions. So when necessary, we need to use a user-defined function to simplify these functions.
The User-Defined Function statement is:
Function Name (function variable 1, function variable 2...) return function return value end
For example, if the function of the spell is CastByName (), we can write it like this in the macro:
/Scirpt function C (a) CastByName (a) end
After running, we only need to use C () directly for other macros to use spells. Is it very convenient?
Or the talking function:
/Script function S (a) SendChatMessage (a, "SAY") end
Then you need to control the characters and use S () to speak.
If there is a function with a returned value:
/Script
Function N ()
Return UNitName (a) -- return indicates the return value of the function, but return must be prior to end.
End
If you want to call the target name in the future, use x = N ("target") directly. If the global variable is defined according to the first point, simpler x = N (T ).
In this way, we can use the important bytes in the macro judgment content, rather than the sinking function. If you have any better ways to simplify it, follow the instructions.
Bytes -------------------------------------------------------------------------------------------------------
How to Create a macro for sorting backpack items
Because the function provided by the game cannot be called directly by the item name, it is usually troublesome to simply use the item macro. You must place the item in the specific position of the backpack.
Or most locks need problems and can monitor their soul fragments at any time (of course, a plug-in can do this ).
Below I will write about how to make such macros:
First, we need to find what we need in our backpack and traverse these packages in a loop. Because there are two parameters in the position, one is the package number and the other is the number of the slot in the package,
So we need a nested loop to search:
Assume that we have a 16-grid package:
For bag =, 1 do -- the package number is from right to left, 4
For cw =, 1 do -- the slot number is top to bottom, left to right, 5 ...... 16
.......... -- Here we can write a statement to determine whether an item is what we need.
End -- indicates that the inner loop ends.
End -- end of External Loop
Or use other methods to do this loop:
While loop: while condition do... End
Repeat loop: repeat... Until Condition
Then, you need to handle the judgment of the item:
Two functions can be used.
GetContainerItemLink () and GetContainerItemInfo ()
The two functions use two variables, one is the package number and the other is the slot number, but their return values are different.
GetContainerItemLink () returns a connection with an item name. If you use the chat function to output the returned value, you can see that not only the item name, but also
A connection that can be connected to the Details window of an item.
For example, if a piece of bear meat is placed at the position of in your bag, you can see it after using/script sendchatmessage (getcontaineritemlink (), "say ").
Meat] ", and click the content, you can also pop up a window to describe this piece of meat.
However, you must note that using a string such as "[bear meat]" cannot determine this item. For example:
If getcontaineritemlink () = "[bear meat]" then ...... end
This judgment is invalid.
The correct method is to assign a variable to the item to be judged, and then use the variable to make a judgment:
Rou = getcontaineritemlink () -- assign the item connection value to ROU
If getcontaineritemlink () = Rou then... end -- now you can determine the item normally.
The last thing to note is that this function cannot make a correct judgment on the warehouse's soul fragments, which means that although the soul fragments are displayed the same with this function, this function recognizes
It is a different thing for all soul fragments, that is, after you assign the connection of this soul fragment to a variable, this variable can only judge this soul fragment, and other soul fragments cannot
It's strange to make a judgment. Therefore, to judge the soul fragments, you must use the second function getcontaineriteminfo ()
Getcontaineriteminfo () returns a large number of values, and almost all item information can be returned. However, we can judge that only the first value is returned.
We can first use the chat function to see what the first return value looks like:
/Script
A = getcontaineriteminfo (4, 1)
Sendchatmessage (a, "say ")
We can see that the return value is long in English, but the keyword of the item is behind.
In this way, we have two ways to use this function to determine an item.
1. Like the method of the previous function, store the value with a variable before making a judgment, provided that the item to be judged should be placed in a specific position and assigned a value.
2. Only use a specific item, write the keyword of the item's judgment in the function, and then use string. find () to judge the item.
Example: The keyword of an item is bd.
If string. find (GetContainerItemInfo (), bd) then ...... end -- determines whether the keyword of the position of package is bd.
Next we need to deal with the use and exchange of items.
Function for using an item in a specific backpack location: UseContainerItem (index, slot)
This is easy to understand.
Function for picking and dropping objects: PickupContainerItem (index, slot)
This function is interesting. When you move your mouse over an item, it is used to pick up the item at a specific position. If you have the item, it is used to put down the item at a specific position and exchange the item at that position.
Therefore, to complete the exchange of two items in the package, use this function three times:
PickupContainerItem () -- pick up the item at location 4 and 1
PickupContainerItem () -- put it at and pick up the item
PickupContainerItem () -- place the item at location 1 and 4 at location 1.
Haola, after combining the above several points, the macro is basically completed:
The following example shows how to organize the soul fragments and put all the soul fragments in the first four packages in the last package:
/Script
Bag = 0 cw = 1 SC = 1 -- defines the variable. bag is the number of the package. cw indicates the slot of the package. SC points to the slot in the last package.
For bag =, 1 do -- starts from package 0, ends with package 3, and does not search for the last package.
For cw =, 1 do -- assume that all packages have 16 slots. If there are not so many slots, the packages can also be used.
If GetContainerItemLink (bag, cw )~ = Nil -- determines whether the slot is null. If it is null, it will jump directly to the next slot.
Then
If string. find (GetContainerItemInfo (bag, cw), "Gem") -- determines whether the slot is a soul fragment. Gem is the keyword of the soul fragment.
Then
While string. find (GetContainerItemInfo (4, SC), "Gem") do SC = SC + 1 end
-- This is a small loop used to determine whether there are soul fragments in the last package. If so, it points to the next slot of the package.
PickupContainerItem (bag, cw)
PickupContainerItem (4, SC)
PickupContainerItem (bag, cw) -- these three statements control the exchange of soul fragments and objects in the last package
SC = SC + 1 -- important. You cannot forget this. After each shard is placed
The slot Pointer Points to the next slot, and the small loop above cannot judge the fragments that have just been placed.
End
End
End
End-end of Loop
No, of course not... The macro is limited to 255 characters. So we need to simplify our macros.
The longest content estimation is the function, starting with simplifying the function:
Create the following macros:
/Script function p (c, d) pickupcontaineritem (c, d) End
/Script Function I (e, f) If getcontaineriteminfo (e, f) then return string. Find (getcontaineriteminfo (E, F), "Gem") else return nil end
The original macro is changed:
/Script
Bag = 0 CW = 1 SC = 1
For bag = 0, 3, 1 do
For CW = 1, 16, 1 do
If G (bag, Cw )~ = Nil
Then
If I (bag, Cw)
Then
While I (4, SC) Do SC = SC + 1 end
P (bag, Cw)
P (4, SC)
P (bag, cw)
SC = SC + 1
End
End
End
End
The definition of unnecessary variables and variables that are too long can be changed:
/Script
S = 1
For g = 0, 3 do
For w = 1, 16 do
If G (g, w)
Then
If I (g, w)
Then
While I (4, s) do s = s + 1 end
P (g, w)
P (4, s)
P (g, w)
S = s + 1
End
End
End
End
Now, let's write it down. I have already written the macros for using items, but I have not tested them. I will release them after the test is complete. If you are interested, you can write it yourself.
Note that you can jump out of the loop as long as you find the item using the item macro, so it is more appropriate to use the Repeat loop.