Skip to content

Instantly share code, notes, and snippets.

@Rochet2
Last active October 14, 2018 17:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Rochet2/9350420 to your computer and use it in GitHub Desktop.
Save Rochet2/9350420 to your computer and use it in GitHub Desktop.
Player & Item Gossip | Enables Item and Player gossip for TrinityCore | http://rochet2.github.io/Player-and-Item-Gossip.html
class example_ItemGossip : public ItemScript
{
public:
example_ItemGossip() : ItemScript("example_ItemGossip") {}
bool OnUse(Player* player, Item* item, SpellCastTargets const& targets) // Any hook here
{
player->PlayerTalkClass->ClearMenus(); // Clears old options
player->ADD_GOSSIP_ITEM(0, "Morph", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->ADD_GOSSIP_ITEM(0, "Demorph", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, item->GetGUID());
return false;
}
void OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action)
{
player->PlayerTalkClass->ClearMenus();
switch(action)
{
case GOSSIP_ACTION_INFO_DEF+1:
player->SetDisplayId(999);
break;
case GOSSIP_ACTION_INFO_DEF+2:
player->DeMorph();
break;
}
player->CLOSE_GOSSIP_MENU();
}
};
void AddSC_example_ItemGossip() // Add to scriptloader normally
{
new example_ItemGossip();
}
#include "ScriptPCH.h"
#define MENU_ID 123 // Our menuID used to match the sent menu to select hook (playerscript)
class example_PlayerGossip : public PlayerScript
{
public:
example_PlayerGossip() : PlayerScript("example_PlayerGossip") {}
void OnPlayerLeaveCombat(Player* player) // Any hook here
{
player->PlayerTalkClass->ClearMenus(); // Clears old options
player->ADD_GOSSIP_ITEM(0, "Morph", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
player->ADD_GOSSIP_ITEM(0, "Demorph", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
// SetMenuId must be after clear menu and before send menu!!
player->PlayerTalkClass->GetGossipMenu().SetMenuId(MENU_ID); // Sets menu ID so we can identify our menu in Select hook. Needs unique number for the menu
player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, player->GetGUID());
}
void OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action)
{
if (menu_id != MENU_ID) // Not the menu coded here? stop.
return;
player->PlayerTalkClass->ClearMenus();
switch(action)
{
case GOSSIP_ACTION_INFO_DEF+1:
player->SetDisplayId(999);
break;
case GOSSIP_ACTION_INFO_DEF+2:
player->DeMorph();
break;
}
player->CLOSE_GOSSIP_MENU();
}
};
void AddSC_example_PlayerGossip() // Add to scriptloader normally
{
new example_PlayerGossip();
}
diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp
index c4ff258..5dee602 100644
--- a/src/server/game/Handlers/MiscHandler.cpp
+++ b/src/server/game/Handlers/MiscHandler.cpp
@@ -110,6 +110,7 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
if (_player->PlayerTalkClass->GetGossipMenu().GetSenderGUID() != guid)
return;
+ Item* item = NULL;
Creature* unit = NULL;
GameObject* go = NULL;
if (IS_CRE_OR_VEH_GUID(guid))
@@ -130,6 +131,23 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
return;
}
}
+ else if (IS_ITEM_GUID(guid))
+ {
+ item = _player->GetItemByGuid(guid);
+ if (!item || _player->IsBankPos(item->GetPos()))
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Item (GUID: %u) not found.", uint32(GUID_LOPART(guid)));
+ return;
+ }
+ }
+ else if (IS_PLAYER_GUID(guid))
+ {
+ if (guid != _player->GetGUID() || menuId != _player->PlayerTalkClass->GetGossipMenu().GetMenuId())
+ {
+ TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - Player (GUID: %u) invalid.", uint32(GUID_LOPART(guid)));
+ return;
+ }
+ }
else
{
TC_LOG_DEBUG("network", "WORLD: HandleGossipSelectOptionOpcode - unsupported GUID type for highguid %u. lowpart %u.", uint32(GUID_HIPART(guid)), uint32(GUID_LOPART(guid)));
@@ -158,12 +176,20 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
if (!sScriptMgr->OnGossipSelectCode(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str()))
_player->OnGossipSelect(unit, gossipListId, menuId);
}
- else
+ else if (go)
{
go->AI()->GossipSelectCode(_player, menuId, gossipListId, code.c_str());
if (!sScriptMgr->OnGossipSelectCode(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str()))
_player->OnGossipSelect(go, gossipListId, menuId);
}
+ else if (item)
+ {
+ sScriptMgr->OnGossipSelectCode(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
+ }
+ else
+ {
+ sScriptMgr->OnGossipSelectCode(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId), code.c_str());
+ }
}
else
{
@@ -173,12 +199,20 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData)
if (!sScriptMgr->OnGossipSelect(_player, unit, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
_player->OnGossipSelect(unit, gossipListId, menuId);
}
- else
+ else if (go)
{
go->AI()->GossipSelect(_player, menuId, gossipListId);
if (!sScriptMgr->OnGossipSelect(_player, go, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId)))
_player->OnGossipSelect(go, gossipListId, menuId);
}
+ else if (item)
+ {
+ sScriptMgr->OnGossipSelect(_player, item, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
+ }
+ else
+ {
+ sScriptMgr->OnGossipSelect(_player, menuId, _player->PlayerTalkClass->GetGossipOptionSender(gossipListId), _player->PlayerTalkClass->GetGossipOptionAction(gossipListId));
+ }
}
}
diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp
index 83f401d..c534db1 100644
--- a/src/server/game/Scripting/ScriptMgr.cpp
+++ b/src/server/game/Scripting/ScriptMgr.cpp
@@ -701,6 +701,24 @@ bool ScriptMgr::OnItemRemove(Player* player, Item* item)
return tmpscript->OnRemove(player, item);
}
+void ScriptMgr::OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action)
+{
+ ASSERT(player);
+ ASSERT(item);
+
+ GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript);
+ tmpscript->OnGossipSelect(player, item, sender, action);
+}
+
+void ScriptMgr::OnGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code)
+{
+ ASSERT(player);
+ ASSERT(item);
+
+ GET_SCRIPT(ItemScript, item->GetScriptId(), tmpscript);
+ tmpscript->OnGossipSelectCode(player, item, sender, action, code);
+}
+
bool ScriptMgr::OnDummyEffect(Unit* caster, uint32 spellId, SpellEffIndex effIndex, Creature* target)
{
ASSERT(caster);
@@ -1283,6 +1301,16 @@ void ScriptMgr::OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newAre
FOREACH_SCRIPT(PlayerScript)->OnUpdateZone(player, newZone, newArea);
}
+void ScriptMgr::OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnGossipSelect(player, menu_id, sender, action);
+}
+
+void ScriptMgr::OnGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code)
+{
+ FOREACH_SCRIPT(PlayerScript)->OnGossipSelectCode(player, menu_id, sender, action, code);
+}
+
// Account
void ScriptMgr::OnAccountLogin(uint32 accountId)
{
diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h
index ee95759..1d0cfa7 100644
--- a/src/server/game/Scripting/ScriptMgr.h
+++ b/src/server/game/Scripting/ScriptMgr.h
@@ -394,6 +394,12 @@ class ItemScript : public ScriptObject
// Called when the item is destroyed.
virtual bool OnRemove(Player* /*player*/, Item* /*item*/) { return false; }
+
+ // Called when a player selects an option in an item gossip window
+ virtual void OnGossipSelect(Player* /*player*/, Item* /*item*/, uint32 /*sender*/, uint32 /*action*/) { }
+
+ // Called when a player selects an option in an item gossip window
+ virtual void OnGossipSelectCode(Player* /*player*/, Item* /*item*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { }
};
class UnitScript : public ScriptObject
@@ -770,6 +776,12 @@ class PlayerScript : public UnitScript
// Called when a player changes to a new map (after moving to new map)
virtual void OnMapChanged(Player* /*player*/) { }
+
+ // Called when a player selects an option in a player gossip window
+ virtual void OnGossipSelect(Player* /*player*/, uint32 /*menu_id*/, uint32 /*sender*/, uint32 /*action*/) { }
+
+ // Called when a player selects an option in a player gossip window
+ virtual void OnGossipSelectCode(Player* /*player*/, uint32 /*menu_id*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { }
};
class AccountScript : public ScriptObject
@@ -955,6 +967,8 @@ class ScriptMgr
bool OnItemUse(Player* player, Item* item, SpellCastTargets const& targets);
bool OnItemExpire(Player* player, ItemTemplate const* proto);
bool OnItemRemove(Player* player, Item* item);
+ void OnGossipSelect(Player* player, Item* item, uint32 sender, uint32 action);
+ void OnGossipSelectCode(Player* player, Item* item, uint32 sender, uint32 action, const char* code);
public: /* CreatureScript */
@@ -1073,6 +1087,8 @@ class ScriptMgr
void OnPlayerSave(Player* player);
void OnPlayerBindToInstance(Player* player, Difficulty difficulty, uint32 mapid, bool permanent);
void OnPlayerUpdateZone(Player* player, uint32 newZone, uint32 newArea);
+ void OnGossipSelect(Player* player, uint32 menu_id, uint32 sender, uint32 action);
+ void OnGossipSelectCode(Player* player, uint32 menu_id, uint32 sender, uint32 action, const char* code);
public: /* AccountScript */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment