Variables.

A variable is a byte of data, represented by a name, that stores a defined piece of data. Unlike C++, there are no variable types in Lua. Also, there is no need to worry about unsigned/signed variables.

A variable is created by typing a string into the script. This string can be almost anything; however, it cannot be keywords or function names (You'll know if it is a keyword if you're using Notepad++, as it'll be highlighted a bold blue).

Furthermore, variables can only be alphanumeric and have underscores and/or hyphens in them. You can use these characters:

Code:
a b c d e f g h i j k l m n o p q r s t u v w x y z 
	A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
	1 2 3 4 5 6 7 8 9 0
	_
Note that variables are case sensitive. MY_VAR is not the same as my_var or My_VaR.

Variables can be declared with no identifier (Global) or with local infront of them. A global variable can pass from script to script, so it can cause problems. It's best to use local variables, which stay inside the current script, to reduce interference.



Good Variable Names:


Code:
My_Var = 1
	myVar = 2
Invalid Variable Names:

Code:
%MyVar = 1 -- PHP Users may be used to this.
	My.Var = 2
	My&Var = 3
It's always a good idea to name your variables after what they are being used for.

Code:
local Var983
Is not as easy to know what it does as this is:

Code:
 
local Npc_Id
Anyhow, back to your first Gossip NPC!

Back to your First Gossip NPC.


Code:
--[[
	My First Gossip Script!
	Tutorial by Neglected
]]

-- Variables
local NPC_ID = 133713

-- On Triggers

-- RegisterUnitEvents
So, this is the code we have so far. We know what the local NPC_ID line does now, so we can start coding.
First off, let's create a new function called 'exampleGossipOnTalk(Unit, Event, player)'. These arguments are the standard ones for the OnTalk gossip event. The OnTalk gossip event is the first menu/dialog you see when you talk to the NPC.


Code:
--[[
My First Gossip Script!
Tutorial by Neglected
]]

-- Variables
local NPC_ID = YourEntryID

-- On Triggers
function exampleGossipOnTalk(Unit, Event, player)
end

-- RegisterUnitEvents

Note that I added an end below the function. We need to end every function that is created, or the Lua Engine will chuck up errors. Now that we have created our function, let's add a RegisterUnitEvent. Usually, if you are created a boss, you will use RegisterUnitEvent(), but since we are making a Gossip NPC, we use RegisterUnitGossipEvent. Note that this is case-sensitive. Add this underneath the appropriate section;

Code:
RegisterUnitGossipEvent(NPC_ID, 1, "exampleGossipOnTalk")
RegisterUnitGossipEvent() has four arguments; ID, Event ID, and Function Name. The Function Name section is in quotation marks; Don't forget that. You can use Variables for the ID and Event ID, which is why I added the NPC_ID variable in place of the ID field.

Code:
RegisterUnitGossipEvent(ID, EVENT_ID, FUNCTION_NAME)
Right now, this script will register an empty function whenever you talk to the NPC. It's something, but it's useless. It's just a placeholder, in many respects. So let's start fleshing it out.


Code:
function exampleGossipOnTalk(Unit, Event, player)
end
As we saw earlier, the statements go between the function header and terminator (Posh words for function and end), like so.

Code:
function exampleGossipOnTalk(Unit, Event, player)
	-- Statements go here
end
To start creating a Gossip Menu, Lua needs to know we are creating the menu; we create a shell using the :GossipCreateMenu() statement.

Code:
 
:GossipCreateMenu(TEXT_ID, player, INTID)
Note that the :GossipCreateMenu() statement has a colon before it; this means it requires a Unit. By Default, the Unit is 'Unit'. This doesn't need to change unless we are dealing with multiple NPCs in one script; We'll come onto that later. Let's add our statement to the function.

Code:
function exampleGossipOnTalk(Unit, Event, player)
	Unit:GossipCreateMenu(100, player, 0)
end
You'll see that I used '100' for the text ID. This is the default, "Hi, <name>. How can I help you?". It can be changed by looking in the appropriate table inside your Database. I set the Intid at '0' because that is what all first menus are set at; 0. It makes logical sense, too.

So now we've created a menu that displays 'Hi, <name>. How can I help you?'. It's still pretty impractical and won't help anyone in any shape, or form (Unless they want a pick-me-up). To make this NPC useful, let's add a few options to our menu by using the :GossipMenuAddItem() statement.



Code:
:GossipMenuAddItem(ICON_ID, MENU_CONTENT, INTID[, CODE])
This statement may confuse you; INTID? CODE? ICON_ID? What the heck are these? Well, the ICON_IDs are the bit you see next to the text when you open the menu. There are a few different icons, the IDs are listed below;

Code:
0 = Chat bubble
	1 = Bag
	2 = Wings
	3 = Book
	4 = Cog/Gear
	5 = Cog/Gear
	6 = Bag with coin
	7 = Chat bubble with "..."
When you are writing in the MENU_CONTENT, you can actually colour it. You use it by putting |cf######, where the #s are your hexidecimal colour (Web Color Chart - Hexadecimal - by VisiBone for more info), at the start of your string, and adding |r at the end.

Code:
:GossipMenuAddItem(0, "|cfFFFFFF White! |r", 1, 0)

INTID? Well, when you use the OnSelect function later, the INTID is used to determine which menu was opened. Therefore, you have to use unique IntIDs for each Menu selection, or the script will not work. Also, the IntID is in numerical form and not string.

CODE is an optional... option.. that can be omitted. It is only used when you want to load up a codebox. This will not be explained in this tutorial, and you will have to experiment to get it completely correct. Needless to say, leave it at 0 (False) unless you want it to load up, then set it to 1 (True).

I'll add a few options to our Gossip Menu..



Code:
 
function exampleGossipOnTalk(Unit, Event, player)
Unit:GossipCreateMenu(100, player, 0)
Unit:GossipMenuAddItem(0, "Teleport me to the mall.", 1, 0)
Unit:GossipMenuAddItem(0, "Remove Resurrection Sickness.", 2, 0)
Unit:GossipMenuAddItem(0, "Never mind.", 3, 0)
end
This adds three options to our menu; a mall teleport option, a remove resurrection sickness option, and an option to close the menu. However, this won't work. We've created the menu, but as far as ArcEmu is concerned, we haven't sent it to the player yet. For this, we add the :GossipSendMenu() command. This one has one argument; the target. The Target is the person we are sending the menu to; this is the reason we have the 'player' argument in this function. We are sending the menu to the player, so we add this to our code:

Code:
Unit:GossipSendMenu(player)
Which makes our function this:

Code:
function exampleGossipOnTalk(Unit, Event, player)
	Unit:GossipCreateMenu(100, player, 0)
	Unit:GossipMenuAddItem(0, "Teleport me to the mall.", 1, 0)
	Unit:GossipMenuAddItem(0, "Remove Resurrection Sickness.", 2, 0)
	Unit:GossipMenuAddItem(0, "Never mind.", 3, 0)
	Unit:GossipSendMenu(player)
end
Let's add this to the rest of our code, leaving us with this:

Code:
--[[
	My First Gossip Script!
	Tutorial by Neglected
]]

-- Variables
local NPC_ID = 133713

-- On Triggers
function exampleGossipOnTalk(Unit, Event, player)
	Unit:GossipCreateMenu(100, player, 0)
	Unit:GossipMenuAddItem(0, "Teleport me to the mall.", 1, 0)
	Unit:GossipMenuAddItem(0, "Remove Resurrection Sickness.", 2, 0)
	Unit:GossipMenuAddItem(0, "Never mind.", 3, 0)
	Unit:GossipSendMenu(player)
end

-- RegisterUnitEvents
RegisterUnitGossipEvent(NPC_ID, 1, "exampleGossipOnTalk")
We're getting there! However, this just shows the menu. The options won't work, you'll be able to see them; but if you click them, nothing will happen. You see, ArcEmu (sadly) doesn't 'detect' your functions for you. You need to tell it what to do. And we do this with our second function; the OnSelect function.

Code:
exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc)
This means nothing to you at the moment, right? Fair enough. Let's create another function underneath our first one.

Code:
--[[
	My First Gossip Script!
	Tutorial by Neglected
]]

-- Variables
local NPC_ID = 133713

-- On Triggers
function exampleGossipOnTalk(Unit, Event, player)
	Unit:GossipCreateMenu(100, player, 0)
	Unit:GossipMenuAddItem(0, "Teleport me to the mall.", 1, 0)
	Unit:GossipMenuAddItem(0, "Remove Resurrection Sickness.", 2, 0)
	Unit:GossipMenuAddItem(0, "Never mind.", 3, 0)
	Unit:GossipSendMenu(player)
end

function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc)
end

-- RegisterUnitEvents
RegisterUnitGossipEvent(NPC_ID, 1, "exampleGossipOnTalk")
And add the RegisterUnitGossipEvent hook underneath the OnTalk one.

Code:
--[[
	My First Gossip Script!
	Tutorial by Neglected
]]

-- Variables
local NPC_ID = 133713

-- On Triggers
function exampleGossipOnTalk(Unit, Event, player)
	Unit:GossipCreateMenu(100, player, 0)
	Unit:GossipMenuAddItem(0, "Teleport me to the mall.", 1, 0)
	Unit:GossipMenuAddItem(0, "Remove Resurrection Sickness.", 2, 0)
	Unit:GossipMenuAddItem(0, "Never mind.", 3, 0)
	Unit:GossipSendMenu(player)
end

function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc)
end

-- RegisterUnitEvents
RegisterUnitGossipEvent(NPC_ID, 1, "exampleGossipOnTalk")
RegisterUnitGossipEvent(NPC_ID, 2, "exampleGossipOnSelect
OK, so our new function has some unknown arguments; id, code, and pMisc. Well, I'll tell you what each one does.
ID; Not a clue. :3
code; This is used if you enabled code in the Previous menu.
pMisc; this is the name of the person who started the Gossip (?).

None of these are much use to you, because you probably won't use them. At least, not in this tutorial. So, let's add the first option (of the 3) to our new function.



Code:
function exampleGossipOnSelect(Unit, Event, player, id, intid, code, pMisc)
	if (intid == 1) then
		player:Teleport(MapID, x, y, z)
		player:GossipComplete()
	end
end
Wait, what? player:Teleport()? player:GossipComplete()? This makes no sense right? And what's with this 'if' thing-a-majig?!

BRAIN FREEEZE!



Err.. OK then, panic moment over. Let's work through this.. deep breaths.. in.. out..