From ESOUI Wiki

Jump to: navigation, search

In our second lesson we will react to user input and try to show something on the screen the same way we learned previously. There are multiple different ways how input can be received in ESO and the easiest way is same like last time via the chat UI. Specifically we will add a new slash command that can be called by typing /<myCommandName> in the chat input box.

Slash commands are simply functions stored in a global Lua table called SLASH_COMMANDS. We will now modify our "Hello World" message to be printed whenever the user wants to see it by adding one such entry to this table.

SLASH_COMMANDS["/hello"] = function() d("Hello Tamriel!") end

Now after we reload the UI the message will be printed to chat whenever we type /hello in chat and press enter.

That's it for this section.

What's that? You want more? Okay, I guess we can do something more interesting. Let's change our command so it prints random jokes. To do this, we need a table that holds multiple jokes and a way to randomly select one of them.

First we create a table with some jokes:

local jokes = {
    "What's the best way to convince even the most pompous Altmer that you have a good point? Stab them in the chest with it.",
    "What do you get when you cross a Nord, a Dunmer, and an Argonian? Violently Murdered! Blood for the Pact!",
    "What is the thinnest book in the world? Redguard Heroes of the War of Betony.",

It is always a good idea to define variables locally at first in order to avoid polluting the global namespace. That way other add-ons cannot accidentally overwrite parts of our add-on and we also won't do the same to them. If we want to make things accessible to others, the established way to do so is to create one global table that has the same name as the add-on and put things in there, but more about that in another part.

Now that we have our jokes in place, we want to select one of them. For starters we change the name of the command and just print our table of jokes to see if it works:

SLASH_COMMANDS["/joke"] = function() d(jokes) end

There are two things to notice here. First, the d() command is capable of printing our tables. It is really flexible and can even handle recursive tables and other data types. We can even pass more than one argument and it will just print everything. Secondly Lua starts numerically indexed tables (called arrays in some other languages) at 1 and not at 0, but we already knew that, right?

Now how about we try to get some random number? The built-in Lua method math.random() will do that for us, but let's pretend we don't know exactly what output to expect. To see what values we will get, we will print its output via d(), but this time instead of reloading the UI we just try it directly in-game. The /script slash command allows us to run code directly from chat and /script d(math.random()) will show us what we want to know. The number is a floating point type and the value is between 0 and 1 (exclusive), so we need to first multiply it by the number of elements in our array and then convert it to an integer. Like we said earlier we also need to increment it by 1 to accommodate for the start index of Lua tables.

/script d(1 + math.floor(math.random() * 3))

This shows the numbers 1, 2 and 3 randomly when we run it a couple of times, but what if we add more jokes later? We can use the # operator to get the amount of elements in a numerically indexed table. Just keep in mind that it won't work on sparse tables and won't count past an entry that is nil.

Let's put everything together:

SLASH_COMMANDS["/joke"] = function() d(jokes[1 + math.floor(math.random() * #jokes)]) end

This works, but looks a bit confusing. Let's spread the code out a bit so it is easier readable:

local function GetRandomElement(array)
    local random = math.random() * #array
    local index = 1 + math.floor(random)
    return array[index]
SLASH_COMMANDS["/joke"] = function() 

This looks nice and tells us some jokes, but what about other people? Why not print it to the "say" chat? The API does not allow us to print things to chat directly except for the local debug output, but we can at least prepare the chat message so we only have to hit enter.

To place something in the chat input field, we can use the StartChatInput() method. It accepts a message, an optional channel constant and a target name in case we want to whisper someone.

In our case we want to talk to the say channel, so we need to pass CHAT_CHANNEL_SAY.

SLASH_COMMANDS["/joke"] = function() 
    StartChatInput(GetRandomElement(jokes), CHAT_CHANNEL_SAY)

Now we just need to type /joke and hit enter twice to get our joke out into the world.

That's it for real. Now you know that the d() function is capable more than just printing text, we learned how to create simple user interactions with slash commands, how to generate random integer values and how to put text into the chat input field. In the next part we will look into how we can react to other things than just the user input.

Personal tools