Contents
- Beginner -
- Basics.
- Understanding gossips.
- How to script a gossip npc.
- How to script a gossip item.
- Intermediate -
- Understanding the code tag.
- Understanding dropdown menus.
Basics.
A gossip always starts with a gossip function. [Kinda logic huh?]
- GOSSIP NPC -
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit is the npc itself.
player is the player opening the gossip menu.
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit:GossipCreateMenu(1, player, 0)
1 The gossip text menu. [See bottom for more information]
player Indicates that it's destinated for the player.
0 code tag, 1 = enabled 0 = unabled [Dont bother this]
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit:GossipCreateMenu(1, player, 0)
pUnit:GossipMenuAddItem([color="red"]1, "Name of the action", 1, 0)
1 This is the tag, the image that shows up in front of the action name. [See bottom for more information]
"Name of the action" Speaks for itself.
1 This is the intid, wich is an unique number that indicates the action's performance.
0 The code tag, unable here.
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit:GossipCreateMenu(1, player, 0)
pUnit:GossipMenuAddItem(1, "Say Hello World.", 1, 0)
pUnit:GossipMenuAddItem(1, "Nevermind.", 2, 0)
2 as you can see I've added a '2' on the place of the intid. As I've told you this number must be unique.
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit:GossipCreateMenu(1, player, 0)
pUnit:GossipMenuAddItem(1, "Say Hello World.", 1, 0)
pUnit:GossipMenuAddItem(1, "Nevermind.", 2, 0)
pUnit:GossipSendMenu(player)
pUnit:GossipSendMenu(player) this sends the complete gossip menu to the player, so the player can choose the actions.
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit:GossipCreateMenu(1, player, 0)
pUnit:GossipMenuAddItem(1, "Say Hello World.", 1, 0)
pUnit:GossipMenuAddItem(1, "Nevermind.", 2, 0)
pUnit:GossipSendMenu(player)
end
end every function needs to be ended with an end!
Now we go to the action selection part.
Code:
function Gossiper_OnGossipSelect(pUnit, event, player, intid, id, code, pMisc)
intid this is the most important indicator we'll be using in the selection part.
function Gossiper_OnGossipSelect(pUnit, event, player, intid, id, code, pMisc)
if(intid == 1) then[/code]
if(intid == 1) then There it is again, the intid. Remember from the gossip menu creation function?
Code:
pUnit:GossipMenuAddItem(1, "Say Hello World.", 1, 0)
1 - if(intid == 1) then Yeah it's matching eachother, now it'll continue the script.
Code:
function Gossiper_OnGossipSelect(pUnit, event, player, intid, id, code, pMisc)
if(intid == 1) then
pUnit:SendChatMessage(12, 0, "Hello World.")
pUnit:SendChatMessage(12, 0, "Hello World.") This'll make the npc say [12 = Say, 14 = Yell] in universal [0 = language] "Hello World."
Code:
function Gossiper_OnGossipSelect(pUnit, event, player, intid, id, code, pMisc)
if(intid == 1) then
pUnit:SendChatMessage(12, 0, "Hello World.")
player:GossipComplete()
end
player:GossipComplete() finishes the gossip action selection.
Code:
function Gossiper_OnGossipSelect(pUnit, event, player, intid, id, code, pMisc)
if(intid == 1) then
pUnit:SendChatMessage(12, 0, "Hello World.")
player:GossipComplete()
end
if(intid == 2) then
player:GossipComplete()
end
end
if(intid == 2) then Remember at the gossip menu creation again?
REMINDER:
Code:
pUnit:GossipMenuAddItem(1, "Nevermind.", 2, 0)
end you might be asking "Why 2 ends?" well, one for ending the selection function, and one for ending if(intid == 2) then
"Why aint there at the first intid 2 ends then?" this is because you are only ending
Code:
if(intid == 1) then
and not the function itself.
The finishing touch.
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit:GossipCreateMenu(1, player, 0)
pUnit:GossipMenuAddItem(1, "Say Hello World.", 1, 0)
pUnit:GossipMenuAddItem(1, "Nevermind.", 2, 0)
pUnit:GossipSendMenu(player)
end
function Gossiper_OnGossipSelect(pUnit, event, player)
if(intid == 1) then
pUnit:SendChatMessage(12, 0, "Hello World.")
player:GossipComplete()
end
if(intid == 2) then
player:GossipComplete()
end
end
RegisterGossipUnitEvent(1337, 1, "Gossiper_OnGossipTalk")
RegisterGossipUnitEvent(1337, 2, "Gossiper_OnGossipSelect")
The red is the function register id, this register's the function name wich is hightlighted in green.
The blue indicates the npc's in-game id.
The number you use to .npc spawn it.
END OF PART 1
Gossip Items.
Gossip item works the same as npc, you just need to add a dummy spell on the item, to make the gossip menu show up.
Code:
function Item_OnGossipTalk(pItem, event, player)
pItem:GossipCreateMenu(1, "Say Hello World.", 1, 0)
pItem:GossipMenuAddItem(1, "Nevermind.", 2, 0)
pItem:GossipSendMenu(player)
end
function Item_OnGossipSelect(pItem, event, player)
if(intid == 1) then
player:SendBroadcastMessage("Hello World")
player:GossipComplete()
end
if(intid == 2) then
player:GossipComplete()
end
end
RegisterItemGossipEvent(1337, 1, "Item_OnGossipMenu")
RegisterItemGossipEvent(1337, 2, "Item_OnGossipSelect")
The only change I made is the red hightlighted sentence.
Since items cant send chat messages, I used SendBroadcastMessage to send a message to the player.
Now, the trick lies in the item itself.
If you go to WoW-v.com and create your item using the junk tool, and use it in-game, nothing will show up.
You can fix this my adding a dummy spell example: Gossip NPC Periodic - Talk - Spell - World of Warcraft.
If you use your item in-game now it'll show up the menu.
END OF PART 2
Intermediate
- Understanding the code tag.
- Understanding dropdown menus.
- Adding cooldown to your Gossips.
WARNING: If you understand everything above, and made several gossip npc's on your own, proceed to Intermediate.
Understanding the code tag.
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit:GossipCreateMenu(1, player, 1)
As I've told you in the basics, we'll have to enable the code tag.
The highlighted red text does this.
Now we are free to use the code tag.
I'll be scripting it so you can insert an item id wich he will add you.
Code:
function Gossiper_OnGossipTalk(pUnit, event, player)
pUnit:GossipCreateMenu(1, player, 1)
pUnit:GossipMenuAddItem(1, "Insert Item ID.", 1, 1)
pUnit:GossipMenuAddItem(1, "Nevermind.", 2, 0)
pUnit:GossipSendMenu(player)
end
function Gossiper_OnGossipSelect(pUnit, event, player, intid, id, code, pMisc)
if(intid == 1) then
local Query = PerformWorldDBQuery("SELECT * FROM `items` WHERE `id` = `"..code.."`")
if(Query == false) then
player:SendBroadcastMessage("That item does not exist, or you entered an invalid ID")
else
player:AddItem(Query, 1)
end
end
if(intid == 2) then
player:GossipComplete()
end
end
RegisterGossipUnitEvent(1, 1337, "Gossiper_OnGossipTalk")
RegisterGossipUnitEvent(2, 1337, "Gossiper_OnGossipSelect")
Performs a world DB query wich selects the inserted item id.
If query doesnt exist or is not a valid ID then.
Send's a error message with the function SendBroadcastMessage.
If query is succesful, then the npc adds the item to the player.
This is basicly all you need to know for code, but you can make it way more difficult.
Examples of advanced code tag using:
http://www.***********/forums/showthread.php?t=77763
http://www.***********/forums/showthread.php?t=75367
END OF PART 3
Understanding dropdown menu's
I'll first script the complete code, and explain it under it.
Code:
function Gossiper_OnGossipTalk(pUnit, event, player, pMisc, intid)
pUnit:GossipCreateMenu(1, player, 0)
pUnit:GossipMenuAddItem(1, "Get Information", 1, 0)
pUnit:GossipMenuAddItem(1, "Nevermin", 2, 0)
pUnit:GossipSendMenu(player)
if(intid == 1) then
pUnit:GossipMenuAddItem(1, "Hello You!", 0)
pUnit:GossipMenuAddItem(1, "How are you?", 0)
pUnit:GossipSendMenu(player)
end
function Gossiper_OnGossipSelect(pUnit, event, player, intid, id, code, pMisc)
if(intid == 1) then
Gossiper_OnGossipTalk(pUnit, event, player, intid)
end
if(intid == 2) then
player:GossipComplete()
end
end
RegisterUnitGossipEvent(1337, 1, "Gossiper_OnGossipTalk")
RegisterUnitGossipEvent(1337, 2, "Gossiper_OnGossipTalk")
Wait, what? Intid in GossipTalk?! Yes that's right intid, in the GossipTalk function.
As you can see here is also an intid 3, wich loops the GossipTalk function, and adding additional information to it.
This is the information that will get added if you click on the three, because it loops.
This is the additional information that'll be added, it's not really an option because there is no intid to define the action, so it's function is just giving information under action 1.
Same goes for this, this will also go under action 1 as additional information.
CREDITS TO DYNASHOCK FOR TEACHING.
[See bottom]
- Gossip Text Menu additional information.
You can make your own gossip text menu in your Database by going to world, and then opening the table "NPC_TEXT" and "NPC_TEXT LOCALIZED".
- SendChatMessage additional information.
There are various types and languages wich you can make your npc talk in.
List:
Code:
-- ChatMsg
CHAT_MSG_ADDON = -1
CHAT_MSG_SYSTEM = 0 -- 28 CHAT_MSG_SYSTEM = 0x00 0
CHAT_MSG_SAY = 1
CHAT_MSG_PARTY = 2
CHAT_MSG_RAID = 3
CHAT_MSG_GUILD = 4
CHAT_MSG_OFFICER = 5
CHAT_MSG_YELL = 6
CHAT_MSG_WHISPER = 7
CHAT_MSG_WHISPER_MOB = 8-- CHAT_MSG_WHISPER_INFORM
CHAT_MSG_WHISPER_INFORM = 9-- CHAT_MSG_REPLY
CHAT_MSG_EMOTE = 10
CHAT_MSG_TEXT_EMOTE = 11
CHAT_MSG_MONSTER_SAY = 12
CHAT_MSG_MONSTER_PARTY = 13
CHAT_MSG_MONSTER_YELL = 14
CHAT_MSG_MONSTER_WHISPER = 15
CHAT_MSG_MONSTER_EMOTE = 16
CHAT_MSG_CHANNEL = 17
CHAT_MSG_CHANNEL_JOIN = 18
CHAT_MSG_CHANNEL_LEAVE = 19
CHAT_MSG_CHANNEL_LIST = 20
CHAT_MSG_CHANNEL_NOTICE = 21
CHAT_MSG_CHANNEL_NOTICE_USER = 22
CHAT_MSG_AFK = 23
CHAT_MSG_DND = 24
CHAT_MSG_IGNORED = 25
CHAT_MSG_SKILL = 26
CHAT_MSG_LOOT = 27
CHAT_MSG_MONEY = 28
CHAT_MSG_OPENING = 29
CHAT_MSG_TRADESKILLS = 30
CHAT_MSG_PET_INFO = 31
CHAT_MSG_COMBAT_MISC_INFO = 32
CHAT_MSG_COMBAT_XP_GAIN = 33
CHAT_MSG_COMBAT_HONOR_GAIN = 34
CHAT_MSG_COMBAT_FACTION_CHANGE = 35
CHAT_MSG_BG_EVENT_NEUTRAL = 36
CHAT_MSG_BG_EVENT_ALLIANCE = 37
CHAT_MSG_BG_EVENT_HORDE = 38
CHAT_MSG_RAID_LEADER = 39
CHAT_MSG_RAID_WARNING = 40
CHAT_MSG_RAID_WARNING_WIDESCREEN = 41
CHAT_MSG_RAID_BOSS_EMOTE = 42
CHAT_MSG_FILTERED = 43
CHAT_MSG_BATTLEGROUND = 44
CHAT_MSG_BATTLEGROUND_LEADER = 45
CHAT_MSG_RESTRICTED = 46
CHAT_MSG_ACHIEVEMENT = 48
CHAT_MSG_GUILD_ACHIEVEMENT = 49
-- Languages
LANG_UNIVERSAL = 0x00
LANG_ORCISH = 0x01
LANG_DARNASSIAN = 0x02
LANG_TAURAHE = 0x03
LANG_DWARVISH = 0x06
LANG_COMMON = 0x07
LANG_DEMONIC = 0x08
LANG_TITAN = 0x09
LANG_THELASSIAN = 0x0A
LANG_DRACONIC = 0x0B
LANG_KALIMAG = 0x0C
LANG_GNOMISH = 0x0D
LANG_TROLL = 0x0E
LANG_GUTTERSPEAK = 0x21
LANG_DRAENEI = 0x23
NUM_LANGUAGES = 0x24
SOURCE = DefinedVariables.lua
- Need some data wich you can use as scripter?
[Almost] Every data you need is in here!
Scripting.rar
Source = Nuval, old scripting group I was part of.
Adding Cooldowns to your gossip scripts.
For fully understanding of this guide you must understand what tables are and how they work, and how a gossip script works.
Ever wanted to prevent someone from clicking a dozen times on an item, object, or NPC gossip script? Ever wanted to add a cooldown? More importantly, ever wanted to add a player specific cooldown and not a general cooldown for the script? Well, it's possible and I'll be teaching you how to in this guide.
New function(s):
- os.clock(), retrieves the time in seconds since the Lua Engine has started.
For this guide I'll be using this item gossip. I will not be explaining how everything of a gossip works because that's not what this guide is meant for.
Code:
CooldownTime = {}
function S_Script(item, event, player)
Script(item, player)
end
function Script(item, player)
if CooldownTime[player:GetName()] ~= nil and ((os.clock()-CooldownTime[player:GetName()])) <= 5 then
player:SendAreaTriggerMessage("|cFFFF0000You cannot use this item yet!")
else
CooldownTime[player:GetName()] = os.clock()
REST OF SCRIPT
end
RegisterItemGossipEvent(57045, 1, "S_Script")
I'll be explaining it with code snippets.
Define CooldownTime as a table. If we would not the Lua engine would think it was a variable. By making them empty we make sure that everyone/everything starts clean off when the script is loaded.
Code:
else
CooldownTime[player:GetName()] = os.clock()
REST OF SCRIPT
The reason why I explain this part before the if part is because you need to know what happens here before you can understand the if statement. Once the gossip's run, it will add the current Lua engine time to the table CooldownTime with as index the player's name. Say the engine has been running for 30 seconds the table would look like "Dynashock 30".
Code:
if CooldownTime[player:GetName()] ~= nil and ((os.clock()-CooldownTime[player:GetName()])) <= 5 then
player:SendAreaTriggerMessage("|cFFFF0000You cannot use this item yet!")
else
First we check if there's a value for the index player:GetName(). This check is needed to prevent an error from happening as otherwise it would try to substract NIL ('emptyness') from a number, which is not possible of course. If it indeed is empty it will break off the if statement there already and do everything beneath else. If the value for the index player:GetName() isn't empty it will do the os.clock() time minus the value contained in CooldownTime[player:GetName()] (= the time of when the player clicked). If this this time is smaller or equal to 5 seconds it will send the message. Thus this means 5 seconds is our cooldown time, if we want to either higher or lower the cooldown we will have to adjust this number.
Why not just do it with RegisterEvent and reset a value after x seconds?
Objects and items cannot register events and this looks cleaner to me.
I hope this guide has been any helpful for you. Feel free to ask any questions should you have them.
FULL CREDITS GO TO DYNASHOCK.