• This is a read only backup of the old Emudevs forum. If you want to have anything removed, please message me on Discord: KittyKaev

Written TrinityCore Gossip Tutorial (Explained in code)

Greetings. I'm not so good at intros, so let's go on and do this.
For this Gossip script, we're going to have the NPC do a few basic things. We'll have him:
Cast a buff on a player
Teleport players to their faction hub (Orgrimmar/Stormwind)
Talk
Send a gossip menu
Take a currency from the player to do all of this (optional)


So, first we need the base skeleton.
Code:
#include "ScriptPCH.h"
class example_gossip : public CreatureScript //This is the class name, which will be used as the script name for the creature. This is also a creaturescript, rather than a playerscript or something like that.
{
public:
	example_gossip() : CreatureScript("example_gossip"){ } //"example_gossip" = the name we use in the DB for the creature.

};
This is the basic skeleton we need to have in order to start. This is pretty much the skeleton of every creature script, so you'll be able to use this sort of thing in most scripts for an NPC name. You can change "example_gossip" to whatever you want, as long as everything that involves the name is set up correctly.

Now, we'll go over how to add the gossip items by default. We'll add the gossip items + A faction check for the teleport.
Remember to read the comments besides the code. ;)
Code:
#include "ScriptPCH.h"
class example_gossip : public CreatureScript //This is the class name, which will be used as the script name for the creature. This is also a creaturescript, rather than a playerscript or something like that.
{
public:
	example_gossip() : CreatureScript("example_gossip"){ }

	bool OnGossipHello(Player* _player, Creature* _creature){ //You can change the things that follow Player* or Creature*, those just serve as names that we use for the code. if you feel more comfortable with player instead of _player, change  Player* _player to Player* player
		
		_player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Tell me a joke!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); //The first thing is the icon. Intellisense will tell you the icons. The second thing is the text, it MUST be in quotes. The third thing is the sender, almost always needs to be GOSSIP_SENDER_MAIN. The fourth part can be any text you want, that's what we'll use to select part in the case later down the line.
		_player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Buff me, my good man!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
		if (_player->GetTeam() == TEAM_HORDE){ 
			//Only show this menu if if player is Horde.
			_player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "I want to teleport to Orgrimmar! For the Horde!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); 
		}
		else if (_player->GetTeam() == TEAM_ALLIANCE){
			//Only show this menu if if player is Alliance.
			_player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "I want to teleport to Stormwind! For the Alliance!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
		}
		_player->PlayerTalkClass->SendGossipMenu(30000, _creature->GetGUID()); // This is the gossip menu, as you will define in npc_text, _creature->GetGUID() is the creature grabbing it's own GUID. Also, always have the gossip_menu AFTER the defined gossip items. Otherwise it won't work.
		return true;
	}

};
Everything in there is explained in a comment, rather than me typing it all out here messily. =P
So, those are the gossip items added by our code.

Now we want to add stuff to the code, in order to make things work! The function for this is "OnGossipHello"
Code:
#include "ScriptPCH.h"
#define GossipMenu = 30000 
class example_gossip : public CreatureScript //This is the class name, which will be used as the script name for the creature. This is also a creaturescript, rather than a playerscript or something like that.
{
public:
	example_gossip() : CreatureScript("example_gossip"){ }

	bool OnGossipHello(Player* _player, Creature* _creature){ //You can change the things that follow Player* or Creature*, those just serve as names that we use for the code. if you feel more comfortable with player instead of _player, change  Player* _player to Player* player
		
		_player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Tell me a joke!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); //The first thing is the icon. Intellisense will tell you the icons. The second thing is the text, it MUST be in quotes. The third thing is the sender, almost always needs to be GOSSIP_SENDER_MAIN. The fourth part can be any text you want, that's what we'll use to select part in the case later down the line.
		_player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Buff me, my good man!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 2);
		if (_player->GetTeam() == TEAM_HORDE){ 
			//Only show this menu if if player is Horde.
			_player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "I want to teleport to Orgrimmar! For the Horde!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 3); 
		}
		else if (_player->GetTeam() == TEAM_ALLIANCE){
			//Only show this menu if if player is Alliance.
			_player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "I want to teleport to Stormwind! For the Alliance!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 4);
		}
		_player->PlayerTalkClass->SendGossipMenu(30000, _creature->GetGUID()); // This is the gossip menu, as you will define in npc_text, _creature->GetGUID() is the creature grabbing it's own GUID.
		return true;
	}
	bool OnGossipSelect(Player* _player, Creature* _creature, uint32 sender, uint32 action){
		_player->PlayerTalkClass->ClearMenus();
		if (sender != GOSSIP_SENDER_MAIN)
			return false; //If the sender is not a player, the code will not even bother executing.
		switch (action){
			//This is where we start adding the selections. 
		case GOSSIP_ACTION_INFO_DEF + 1: //The first case. Again, GOSSIP_ACTION_INFO_DEF + 1 can be defined as anything, as long as you select the case correctly.
			_creature->MonsterWhisper("A dwarf hunter walks into a bar. He takes everyones drinks. They get angry, as the dwarf yells 'MULTISHOT!'", _player, false); // Syntax: Text, target, bosswhisper
			_player->PlayerTalkClass->SendCloseGossip(); // We use this in order to close the gossip menu after an option is chosen.
			break; //ALWAYS break at the end of a case.
		case GOSSIP_ACTION_INFO_DEF + 2:
			_player->PlayerTalkClass->SendCloseGossip(); // We use this in order to close the gossip menu after an option is chosen.
			_player->AddAura(1337, _player); //Could be cleaner done via a cast, but this works too. You could also use an array to make this easier.
			_creature->MonsterWhisper("You'z welcome.", _player, false);
			break;
		case GOSSIP_ACTION_INFO_DEF + 3:
			_player->PlayerTalkClass->SendCloseGossip(); // We use this in order to close the gossip menu after an option is chosen.
			_player->TeleportTo(MapID, X, Y, Z, O); //Replace map Id with map ID and XYZO with the XYZ coordinates + Orientation.
			break;
		case GOSSIP_ACTION_INFO_DEF + 4:
			_player->PlayerTalkClass->SendCloseGossip(); // We use this in order to close the gossip menu after an option is chosen.
			_player->TeleportTo(Same, as, Orgrimmar, silly, bily);
			break;
		}
	}

};

//This is the end of the Script!
void AddSC_example_gossip()
{
	new example_gossip();
}
and there you go! You have a Gossip Script! I'll add more to this thread later, so stay tuned.

Resources:
http://www.trinitycore.net/index.html - This has amazing documentation on TrinityCore.
 
Last edited:

Tommy

Founder
Explanation in the code tags is kinda redundant to try and read because you have to scroll over to read everything. It would be better to take the code you want to explain and write the explanation under the code tags, for example:

Code:
class example_gossip : public CreatureScript
{
public:
	example_gossip() : CreatureScript("example_gossip") { }

};

"example_gossip": Is the class name. The class name can be any word, as long as it doesn't conflict with another class name with the same name.
"CreatureScript("example_gossip")": Here we set our CreatureScript as the base of our class, next to the constructor "example_gossip()." The string value set in "CreatureScript("NAME")" will be used as the script name for a creature.


Pretty much like the above is how I would do it since it would be much more clear to read, especially without the scrolling nonsense. One more thing, you don't need to include ScriptPCH.h since CMake handles including the needed files - they changed that a very long time ago.

Regardless, thanks for the tutorial.
 
Explanation in the code tags is kinda redundant to try and read because you have to scroll over to read everything. It would be better to take the code you want to explain and write the explanation under the code tags, for example:

Code:
class example_gossip : public CreatureScript
{
public:
	example_gossip() : CreatureScript("example_gossip") { }

};

"example_gossip": Is the class name. The class name can be any word, as long as it doesn't conflict with another class name with the same name.
"CreatureScript("example_gossip")": Here we set our CreatureScript as the base of our class, next to the constructor "example_gossip()." The string value set in "CreatureScript("NAME")" will be used as the script name for a creature.


Pretty much like the above is how I would do it since it would be much more clear to read, especially without the scrolling nonsense. One more thing, you don't need to include ScriptPCH.h since CMake handles including the needed files - they changed that a very long time ago.

Regardless, thanks for the tutorial.

I will probably rewrite tutorial in a little while. :)
 

Seraphim

Noble Member
I think that
Code:
if (sender != GOSSIP_SENDER_MAIN)
isn't really needed. I've never had to use it in a script to my knowledge, but...
 

Tommy

Founder
I think that
Code:
if (sender != GOSSIP_SENDER_MAIN)
isn't really needed. I've never had to use it in a script to my knowledge, but...

sender is rarely used, even for Blizzlike scripts. You're correct, the if statement isn't needed, nor is sender (comment sender out, like so: uint32 /* sender */).
 
Top