Merge MaNGOS, Gossip System. Autor NoFantasy.
* DB support required * Closes #859 --HG-- branch : trunk
This commit is contained in:
+2
-1
@@ -458,6 +458,8 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "gameobject_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesGameobjectCommand, "", NULL },
|
||||
{ "gameobject_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGOQuestRelationsCommand, "", NULL },
|
||||
{ "gameobject_scripts", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGameObjectScriptsCommand, "", NULL },
|
||||
{ "gossip_menu", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGossipMenuCommand, "", NULL },
|
||||
{ "gossip_menu_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGossipMenuOptionCommand, "", NULL },
|
||||
{ "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL },
|
||||
{ "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL },
|
||||
{ "item_required_target", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemRequiredTragetCommand, "", NULL },
|
||||
@@ -474,7 +476,6 @@ ChatCommand * ChatHandler::getCommandTable()
|
||||
{ "mail_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMailCommand, "", NULL },
|
||||
{ "milling_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesMillingCommand, "", NULL },
|
||||
{ "npc_gossip", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcGossipCommand, "", NULL },
|
||||
{ "npc_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcOptionCommand, "", NULL },
|
||||
{ "npc_spellclick_spells", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadSpellClickSpellsCommand, "",NULL},
|
||||
{ "npc_trainer", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcTrainerCommand, "", NULL },
|
||||
{ "npc_vendor", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadNpcVendorCommand, "", NULL },
|
||||
|
||||
+2
-1
@@ -364,6 +364,8 @@ class TRINITY_DLL_SPEC ChatHandler
|
||||
bool HandleReloadGameGraveyardZoneCommand(const char* args);
|
||||
bool HandleReloadGameObjectScriptsCommand(const char* args);
|
||||
bool HandleReloadGameTeleCommand(const char* args);
|
||||
bool HandleReloadGossipMenuCommand(const char* args);
|
||||
bool HandleReloadGossipMenuOptionCommand(const char* args);
|
||||
bool HandleReloadGOQuestRelationsCommand(const char* args);
|
||||
bool HandleReloadGOQuestInvRelationsCommand(const char* args);
|
||||
bool HandleReloadItemEnchantementsCommand(const char* args);
|
||||
@@ -392,7 +394,6 @@ class TRINITY_DLL_SPEC ChatHandler
|
||||
bool HandleReloadLootTemplatesSpellCommand(const char* args);
|
||||
bool HandleReloadTrinityStringCommand(const char* args);
|
||||
bool HandleReloadNpcGossipCommand(const char* args);
|
||||
bool HandleReloadNpcOptionCommand(const char* args);
|
||||
bool HandleReloadNpcTrainerCommand(const char* args);
|
||||
bool HandleReloadNpcVendorCommand(const char* args);
|
||||
bool HandleReloadPageTextsCommand(const char* args);
|
||||
|
||||
@@ -136,7 +136,6 @@ Unit(),
|
||||
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0),
|
||||
m_lootMoney(0), m_lootRecipient(0),
|
||||
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(0.0f),
|
||||
m_gossipOptionLoaded(false),
|
||||
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_AlreadyCallAssistance(false),
|
||||
m_regenHealth(true), m_AI_locked(false), m_isDeadByDefault(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
|
||||
m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL)
|
||||
@@ -888,372 +887,6 @@ bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const
|
||||
&& pPlayer->getClass() == GetCreatureInfo()->trainer_class;
|
||||
}
|
||||
|
||||
void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid )
|
||||
{
|
||||
//Prevent gossip from NPCs that are possessed.
|
||||
Unit* Charmed = Unit::GetCharmer();
|
||||
if (Charmed)
|
||||
return;
|
||||
|
||||
PlayerMenu* pm=pPlayer->PlayerTalkClass;
|
||||
pm->ClearMenus();
|
||||
|
||||
// lazy loading single time at use
|
||||
LoadGossipOptions();
|
||||
|
||||
for (GossipOptionList::iterator i = m_goptions.begin( ); i != m_goptions.end( ); ++i )
|
||||
{
|
||||
GossipOption* gso=&*i;
|
||||
if(gso->GossipId == gossipid)
|
||||
{
|
||||
bool cantalking=true;
|
||||
if(gso->Id==1)
|
||||
{
|
||||
uint32 textid=GetNpcTextId();
|
||||
GossipText const* gossiptext=objmgr.GetGossipText(textid);
|
||||
if(!gossiptext)
|
||||
cantalking=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (gso->Action)
|
||||
{
|
||||
case GOSSIP_OPTION_QUESTGIVER:
|
||||
pPlayer->PrepareQuestMenu(GetGUID());
|
||||
//if (pm->GetQuestMenu()->MenuItemCount() == 0)
|
||||
cantalking=false;
|
||||
//pm->GetQuestMenu()->ClearMenu();
|
||||
break;
|
||||
case GOSSIP_OPTION_ARMORER:
|
||||
cantalking=false; // added in special mode
|
||||
break;
|
||||
case GOSSIP_OPTION_SPIRITHEALER:
|
||||
if( !pPlayer->isDead() )
|
||||
cantalking=false;
|
||||
break;
|
||||
case GOSSIP_OPTION_VENDOR:
|
||||
{
|
||||
VendorItemData const* vItems = GetVendorItems();
|
||||
if(!vItems || vItems->Empty())
|
||||
{
|
||||
sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.",
|
||||
GetGUIDLow(),GetEntry());
|
||||
cantalking=false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GOSSIP_OPTION_TRAINER:
|
||||
if(!isCanTrainingOf(pPlayer,false))
|
||||
cantalking=false;
|
||||
break;
|
||||
case GOSSIP_OPTION_LEARNDUALSPEC:
|
||||
if(!(pPlayer->GetSpecsCount() == 1 && isCanTrainingAndResetTalentsOf(pPlayer) && !(pPlayer->getLevel() < sWorld.getConfig(CONFIG_MIN_DUALSPEC_LEVEL))))
|
||||
cantalking=false;
|
||||
break;
|
||||
case GOSSIP_OPTION_UNLEARNTALENTS:
|
||||
if(!isCanTrainingAndResetTalentsOf(pPlayer))
|
||||
cantalking=false;
|
||||
break;
|
||||
case GOSSIP_OPTION_UNLEARNPETSKILLS:
|
||||
if(!pPlayer->GetPet() || pPlayer->GetPet()->getPetType() != HUNTER_PET || pPlayer->GetPet()->m_spells.size() <= 1 || GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || GetCreatureInfo()->trainer_class != CLASS_HUNTER)
|
||||
cantalking=false;
|
||||
break;
|
||||
case GOSSIP_OPTION_TAXIVENDOR:
|
||||
if ( pPlayer->GetSession()->SendLearnNewTaxiNode(this) )
|
||||
return;
|
||||
break;
|
||||
case GOSSIP_OPTION_BATTLEFIELD:
|
||||
if(!isCanInteractWithBattleMaster(pPlayer,false))
|
||||
cantalking=false;
|
||||
break;
|
||||
case GOSSIP_OPTION_SPIRITGUIDE:
|
||||
case GOSSIP_OPTION_INNKEEPER:
|
||||
case GOSSIP_OPTION_BANKER:
|
||||
case GOSSIP_OPTION_PETITIONER:
|
||||
case GOSSIP_OPTION_STABLEPET:
|
||||
case GOSSIP_OPTION_TABARDDESIGNER:
|
||||
case GOSSIP_OPTION_AUCTIONEER:
|
||||
break; // no checks
|
||||
case GOSSIP_OPTION_OUTDOORPVP:
|
||||
if ( !sOutdoorPvPMgr.CanTalkTo(pPlayer,this,(*gso)) )
|
||||
cantalking = false;
|
||||
break;
|
||||
default:
|
||||
sLog.outErrorDb("Creature %u (entry: %u) have unknown gossip option %u",GetDBTableGUIDLow(),GetEntry(),gso->Action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//note for future dev: should have database fields for BoxMessage & BoxMoney
|
||||
if(!gso->OptionText.empty() && cantalking)
|
||||
{
|
||||
std::string OptionText = gso->OptionText;
|
||||
std::string BoxText = gso->BoxText;
|
||||
int loc_idx = pPlayer->GetSession()->GetSessionDbLocaleIndex();
|
||||
if (loc_idx >= 0)
|
||||
{
|
||||
NpcOptionLocale const *no = objmgr.GetNpcOptionLocale(gso->Id);
|
||||
if (no)
|
||||
{
|
||||
if (no->OptionText.size() > loc_idx && !no->OptionText[loc_idx].empty())
|
||||
OptionText=no->OptionText[loc_idx];
|
||||
if (no->BoxText.size() > loc_idx && !no->BoxText[loc_idx].empty())
|
||||
BoxText=no->BoxText[loc_idx];
|
||||
}
|
||||
}
|
||||
pm->GetGossipMenu().AddMenuItem((uint8)gso->Icon,OptionText, gossipid,gso->Action,BoxText,gso->BoxMoney,gso->Coded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-)
|
||||
if(pm->Empty())
|
||||
{
|
||||
if(HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_TRAINER))
|
||||
{
|
||||
isCanTrainingOf(pPlayer,true); // output error message if need
|
||||
}
|
||||
if(HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_BATTLEMASTER))
|
||||
{
|
||||
isCanInteractWithBattleMaster(pPlayer,true); // output error message if need
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::sendPreparedGossip(Player* player)
|
||||
{
|
||||
if(!player)
|
||||
return;
|
||||
|
||||
if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) // if world event npc then
|
||||
gameeventmgr.HandleWorldEventGossip(player, this); // update world state with progress
|
||||
|
||||
// in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag)
|
||||
if (!HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_GOSSIP) && !player->PlayerTalkClass->GetQuestMenu().Empty())
|
||||
{
|
||||
player->SendPreparedQuest(GetGUID());
|
||||
return;
|
||||
}
|
||||
|
||||
// in case non empty gossip menu (that not included quests list size) show it
|
||||
// (quest entries from quest menu will be included in list)
|
||||
player->PlayerTalkClass->SendGossipMenu(GetNpcTextId(), GetGUID());
|
||||
}
|
||||
|
||||
void Creature::OnGossipSelect(Player* player, uint32 option)
|
||||
{
|
||||
GossipMenu& gossipmenu = player->PlayerTalkClass->GetGossipMenu();
|
||||
|
||||
if(option >= gossipmenu.MenuItemCount())
|
||||
return;
|
||||
|
||||
uint32 action=gossipmenu.GetItem(option).m_gAction;
|
||||
uint32 zoneid=GetZoneId();
|
||||
uint64 guid=GetGUID();
|
||||
|
||||
GossipOption const *gossip=GetGossipOption( action );
|
||||
if(!gossip)
|
||||
{
|
||||
zoneid=0;
|
||||
gossip=GetGossipOption( action );
|
||||
if(!gossip)
|
||||
return;
|
||||
}
|
||||
|
||||
switch (gossip->Action)
|
||||
{
|
||||
case GOSSIP_OPTION_GOSSIP:
|
||||
{
|
||||
uint32 textid = GetGossipTextId(action, zoneid);
|
||||
if (textid == 0)
|
||||
textid=GetNpcTextId();
|
||||
|
||||
player->PlayerTalkClass->CloseGossip();
|
||||
player->PlayerTalkClass->SendTalking(textid);
|
||||
break;
|
||||
}
|
||||
case GOSSIP_OPTION_OUTDOORPVP:
|
||||
sOutdoorPvPMgr.HandleGossipOption(player, GetGUID(), option);
|
||||
break;
|
||||
case GOSSIP_OPTION_SPIRITHEALER:
|
||||
if (player->isDead())
|
||||
CastSpell(this,17251,true,NULL,NULL,player->GetGUID());
|
||||
break;
|
||||
case GOSSIP_OPTION_QUESTGIVER:
|
||||
player->PrepareQuestMenu( guid );
|
||||
player->SendPreparedQuest( guid );
|
||||
break;
|
||||
case GOSSIP_OPTION_VENDOR:
|
||||
case GOSSIP_OPTION_ARMORER:
|
||||
player->GetSession()->SendListInventory(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_STABLEPET:
|
||||
player->GetSession()->SendStablePet(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_TRAINER:
|
||||
player->GetSession()->SendTrainerList(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_UNLEARNTALENTS:
|
||||
player->PlayerTalkClass->CloseGossip();
|
||||
player->SendTalentWipeConfirm(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_LEARNDUALSPEC:
|
||||
if(player->GetSpecsCount() == 1 && !(player->getLevel() < sWorld.getConfig(CONFIG_MIN_DUALSPEC_LEVEL)))
|
||||
{
|
||||
if (player->GetMoney() < 10000000)
|
||||
{
|
||||
player->SendBuyError( BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
|
||||
player->PlayerTalkClass->CloseGossip();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
player->ModifyMoney(-10000000);
|
||||
|
||||
// Cast spells that teach dual spec
|
||||
// Both are also ImplicitTarget self and must be cast by player
|
||||
player->CastSpell(player,63680,true,NULL,NULL,player->GetGUID());
|
||||
player->CastSpell(player,63624,true,NULL,NULL,player->GetGUID());
|
||||
|
||||
// Should show another Gossip text with "Congratulations..."
|
||||
player->PlayerTalkClass->CloseGossip();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GOSSIP_OPTION_UNLEARNPETSKILLS:
|
||||
player->PlayerTalkClass->CloseGossip();
|
||||
player->SendPetSkillWipeConfirm();
|
||||
break;
|
||||
case GOSSIP_OPTION_TAXIVENDOR:
|
||||
player->GetSession()->SendTaxiMenu(this);
|
||||
break;
|
||||
case GOSSIP_OPTION_INNKEEPER:
|
||||
player->PlayerTalkClass->CloseGossip();
|
||||
player->SetBindPoint( guid );
|
||||
break;
|
||||
case GOSSIP_OPTION_BANKER:
|
||||
player->GetSession()->SendShowBank( guid );
|
||||
break;
|
||||
case GOSSIP_OPTION_PETITIONER:
|
||||
player->PlayerTalkClass->CloseGossip();
|
||||
player->GetSession()->SendPetitionShowList( guid );
|
||||
break;
|
||||
case GOSSIP_OPTION_TABARDDESIGNER:
|
||||
player->PlayerTalkClass->CloseGossip();
|
||||
player->GetSession()->SendTabardVendorActivate( guid );
|
||||
break;
|
||||
case GOSSIP_OPTION_AUCTIONEER:
|
||||
player->GetSession()->SendAuctionHello( guid, this );
|
||||
break;
|
||||
case GOSSIP_OPTION_SPIRITGUIDE:
|
||||
case GOSSIP_GUARD_SPELLTRAINER:
|
||||
case GOSSIP_GUARD_SKILLTRAINER:
|
||||
prepareGossipMenu( player,gossip->Id );
|
||||
sendPreparedGossip( player );
|
||||
break;
|
||||
case GOSSIP_OPTION_BATTLEFIELD:
|
||||
{
|
||||
BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(GetEntry());
|
||||
player->GetSession()->SendBattlegGroundList( GetGUID(), bgTypeId );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
OnPoiSelect( player, gossip );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Creature::OnPoiSelect(Player* player, GossipOption const *gossip)
|
||||
{
|
||||
if(gossip->GossipId==GOSSIP_GUARD_SPELLTRAINER || gossip->GossipId==GOSSIP_GUARD_SKILLTRAINER)
|
||||
{
|
||||
Poi_Icon icon = ICON_POI_BLANK;
|
||||
//need add more case.
|
||||
switch(gossip->Action)
|
||||
{
|
||||
case GOSSIP_GUARD_BANK:
|
||||
icon=ICON_POI_SMALL_HOUSE;
|
||||
break;
|
||||
case GOSSIP_GUARD_RIDE:
|
||||
icon=ICON_POI_RWHORSE;
|
||||
break;
|
||||
case GOSSIP_GUARD_GUILD:
|
||||
icon=ICON_POI_BLUETOWER;
|
||||
break;
|
||||
default:
|
||||
icon=ICON_POI_GREYTOWER;
|
||||
break;
|
||||
}
|
||||
uint32 textid = GetGossipTextId( gossip->Action, GetZoneId() );
|
||||
player->PlayerTalkClass->SendTalking(textid);
|
||||
// std::string areaname= gossip->OptionText;
|
||||
// how this could worked player->PlayerTalkClass->SendPointOfInterest( x, y, icon, 2, 15, areaname.c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Creature::GetGossipTextId(uint32 action, uint32 zoneid)
|
||||
{
|
||||
QueryResult *result= WorldDatabase.PQuery("SELECT textid FROM npc_gossip_textid WHERE action = '%u' AND zoneid ='%u'", action, zoneid );
|
||||
|
||||
if(!result)
|
||||
return 0;
|
||||
|
||||
Field *fields = result->Fetch();
|
||||
uint32 id = fields[0].GetUInt32();
|
||||
|
||||
delete result;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
uint32 Creature::GetNpcTextId()
|
||||
{
|
||||
// don't cache / use cache in case it's a world event announcer
|
||||
if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT)
|
||||
if(uint32 textid = gameeventmgr.GetNpcTextId(m_DBTableGuid))
|
||||
return textid;
|
||||
|
||||
if (!m_DBTableGuid)
|
||||
return DEFAULT_GOSSIP_MESSAGE;
|
||||
|
||||
if(uint32 pos = objmgr.GetNpcGossip(m_DBTableGuid))
|
||||
return pos;
|
||||
|
||||
return DEFAULT_GOSSIP_MESSAGE;
|
||||
}
|
||||
|
||||
GossipOption const* Creature::GetGossipOption( uint32 id ) const
|
||||
{
|
||||
for (GossipOptionList::const_iterator i = m_goptions.begin( ); i != m_goptions.end( ); ++i )
|
||||
{
|
||||
if(i->Action==id )
|
||||
return &*i;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Creature::ResetGossipOptions()
|
||||
{
|
||||
m_gossipOptionLoaded = false;
|
||||
m_goptions.clear();
|
||||
}
|
||||
|
||||
void Creature::LoadGossipOptions()
|
||||
{
|
||||
if(m_gossipOptionLoaded)
|
||||
return;
|
||||
|
||||
uint32 npcflags=GetUInt32Value(UNIT_NPC_FLAGS);
|
||||
|
||||
CacheNpcOptionList const& noList = objmgr.GetNpcOptions ();
|
||||
for (CacheNpcOptionList::const_iterator i = noList.begin (); i != noList.end (); ++i)
|
||||
if(i->NpcFlag & npcflags)
|
||||
addGossipOption(*i);
|
||||
|
||||
m_gossipOptionLoaded = true;
|
||||
}
|
||||
|
||||
void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, uint32 MovementFlags, uint8 type)
|
||||
{
|
||||
/* uint32 timeElap = getMSTime();
|
||||
|
||||
+2
-116
@@ -39,104 +39,6 @@ class Player;
|
||||
class WorldSession;
|
||||
class CreatureGroup;
|
||||
|
||||
enum Gossip_Option
|
||||
{
|
||||
GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE = 0,
|
||||
GOSSIP_OPTION_GOSSIP = 1, //UNIT_NPC_FLAG_GOSSIP = 1,
|
||||
GOSSIP_OPTION_QUESTGIVER = 2, //UNIT_NPC_FLAG_QUESTGIVER = 2,
|
||||
GOSSIP_OPTION_VENDOR = 3, //UNIT_NPC_FLAG_VENDOR = 4,
|
||||
GOSSIP_OPTION_TAXIVENDOR = 4, //UNIT_NPC_FLAG_TAXIVENDOR = 8,
|
||||
GOSSIP_OPTION_TRAINER = 5, //UNIT_NPC_FLAG_TRAINER = 16,
|
||||
GOSSIP_OPTION_SPIRITHEALER = 6, //UNIT_NPC_FLAG_SPIRITHEALER = 32,
|
||||
GOSSIP_OPTION_SPIRITGUIDE = 7, //UNIT_NPC_FLAG_SPIRITGUIDE = 64,
|
||||
GOSSIP_OPTION_INNKEEPER = 8, //UNIT_NPC_FLAG_INNKEEPER = 128,
|
||||
GOSSIP_OPTION_BANKER = 9, //UNIT_NPC_FLAG_BANKER = 256,
|
||||
GOSSIP_OPTION_PETITIONER = 10, //UNIT_NPC_FLAG_PETITIONER = 512,
|
||||
GOSSIP_OPTION_TABARDDESIGNER = 11, //UNIT_NPC_FLAG_TABARDDESIGNER = 1024,
|
||||
GOSSIP_OPTION_BATTLEFIELD = 12, //UNIT_NPC_FLAG_BATTLEFIELDPERSON = 2048,
|
||||
GOSSIP_OPTION_AUCTIONEER = 13, //UNIT_NPC_FLAG_AUCTIONEER = 4096,
|
||||
GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE = 8192,
|
||||
GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER = 16384,
|
||||
GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER)
|
||||
GOSSIP_OPTION_UNLEARNPETSKILLS = 17, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER)
|
||||
GOSSIP_OPTION_LEARNDUALSPEC = 18, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER)
|
||||
GOSSIP_OPTION_OUTDOORPVP = 19 //added by code (option for outdoor pvp creatures)
|
||||
};
|
||||
|
||||
enum Gossip_Guard
|
||||
{
|
||||
GOSSIP_GUARD_BANK = 32,
|
||||
GOSSIP_GUARD_RIDE = 33,
|
||||
GOSSIP_GUARD_GUILD = 34,
|
||||
GOSSIP_GUARD_INN = 35,
|
||||
GOSSIP_GUARD_MAIL = 36,
|
||||
GOSSIP_GUARD_AUCTION = 37,
|
||||
GOSSIP_GUARD_WEAPON = 38,
|
||||
GOSSIP_GUARD_STABLE = 39,
|
||||
GOSSIP_GUARD_BATTLE = 40,
|
||||
GOSSIP_GUARD_SPELLTRAINER = 41,
|
||||
GOSSIP_GUARD_SKILLTRAINER = 42
|
||||
};
|
||||
|
||||
enum Gossip_Guard_Spell
|
||||
{
|
||||
GOSSIP_GUARD_SPELL_WARRIOR = 64,
|
||||
GOSSIP_GUARD_SPELL_PALADIN = 65,
|
||||
GOSSIP_GUARD_SPELL_HUNTER = 66,
|
||||
GOSSIP_GUARD_SPELL_ROGUE = 67,
|
||||
GOSSIP_GUARD_SPELL_PRIEST = 68,
|
||||
GOSSIP_GUARD_SPELL_UNKNOWN1 = 69,
|
||||
GOSSIP_GUARD_SPELL_SHAMAN = 70,
|
||||
GOSSIP_GUARD_SPELL_MAGE = 71,
|
||||
GOSSIP_GUARD_SPELL_WARLOCK = 72,
|
||||
GOSSIP_GUARD_SPELL_UNKNOWN2 = 73,
|
||||
GOSSIP_GUARD_SPELL_DRUID = 74
|
||||
};
|
||||
|
||||
enum Gossip_Guard_Skill
|
||||
{
|
||||
GOSSIP_GUARD_SKILL_ALCHEMY = 80,
|
||||
GOSSIP_GUARD_SKILL_BLACKSMITH = 81,
|
||||
GOSSIP_GUARD_SKILL_COOKING = 82,
|
||||
GOSSIP_GUARD_SKILL_ENCHANT = 83,
|
||||
GOSSIP_GUARD_SKILL_FIRSTAID = 84,
|
||||
GOSSIP_GUARD_SKILL_FISHING = 85,
|
||||
GOSSIP_GUARD_SKILL_HERBALISM = 86,
|
||||
GOSSIP_GUARD_SKILL_LEATHER = 87,
|
||||
GOSSIP_GUARD_SKILL_MINING = 88,
|
||||
GOSSIP_GUARD_SKILL_SKINNING = 89,
|
||||
GOSSIP_GUARD_SKILL_TAILORING = 90,
|
||||
GOSSIP_GUARD_SKILL_ENGINERING = 91
|
||||
};
|
||||
|
||||
enum GossipOptionIcon
|
||||
{
|
||||
GOSSIP_ICON_CHAT = 0, //white chat bubble
|
||||
GOSSIP_ICON_VENDOR = 1, //brown bag
|
||||
GOSSIP_ICON_TAXI = 2, //flight
|
||||
GOSSIP_ICON_TRAINER = 3, //book
|
||||
GOSSIP_ICON_INTERACT_1 = 4, //interaction wheel
|
||||
GOSSIP_ICON_INTERACT_2 = 5, //interaction wheel
|
||||
GOSSIP_ICON_MONEY_BAG = 6, //brown bag with yellow dot
|
||||
GOSSIP_ICON_TALK = 7, //white chat bubble with black dots
|
||||
GOSSIP_ICON_TABARD = 8, //tabard
|
||||
GOSSIP_ICON_BATTLE = 9, //two swords
|
||||
GOSSIP_ICON_DOT = 10 //yellow dot
|
||||
};
|
||||
|
||||
struct GossipOption
|
||||
{
|
||||
uint32 Id;
|
||||
uint32 GossipId;
|
||||
uint32 NpcFlag;
|
||||
uint32 Icon;
|
||||
uint32 Action;
|
||||
uint32 BoxMoney;
|
||||
bool Coded;
|
||||
std::string OptionText;
|
||||
std::string BoxText;
|
||||
};
|
||||
|
||||
enum CreatureFlagsExtra
|
||||
{
|
||||
CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group
|
||||
@@ -176,6 +78,7 @@ struct CreatureInfo
|
||||
char* Name;
|
||||
char* SubName;
|
||||
char* IconName;
|
||||
uint32 GossipMenuId;
|
||||
uint32 minlevel;
|
||||
uint32 maxlevel;
|
||||
uint32 minhealth;
|
||||
@@ -268,7 +171,7 @@ struct CreatureLocale
|
||||
std::vector<std::string> SubName;
|
||||
};
|
||||
|
||||
struct NpcOptionLocale
|
||||
struct GossipMenuItemsLocale
|
||||
{
|
||||
std::vector<std::string> OptionText;
|
||||
std::vector<std::string> BoxText;
|
||||
@@ -461,8 +364,6 @@ struct TrainerSpellData
|
||||
void Clear() { spellList.clear(); }
|
||||
};
|
||||
|
||||
typedef std::list<GossipOption> GossipOptionList;
|
||||
|
||||
typedef std::map<uint32,time_t> CreatureSpellCooldowns;
|
||||
|
||||
// max different by z coordinate for creature aggro reaction
|
||||
@@ -582,18 +483,6 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
||||
std::string GetScriptName() const;
|
||||
uint32 GetScriptId() const;
|
||||
|
||||
void prepareGossipMenu( Player *pPlayer, uint32 gossipid = 0 );
|
||||
void sendPreparedGossip( Player* player );
|
||||
void OnGossipSelect(Player* player, uint32 option);
|
||||
void OnPoiSelect(Player* player, GossipOption const *gossip);
|
||||
|
||||
uint32 GetGossipTextId(uint32 action, uint32 zoneid);
|
||||
uint32 GetNpcTextId();
|
||||
void LoadGossipOptions();
|
||||
void ResetGossipOptions();
|
||||
GossipOption const* GetGossipOption( uint32 id ) const;
|
||||
void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); }
|
||||
|
||||
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }
|
||||
void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); }
|
||||
void TextEmote(int32 textId, uint64 TargetGuid, bool IsBossEmote = false) { MonsterTextEmote(textId,TargetGuid,IsBossEmote); }
|
||||
@@ -760,9 +649,6 @@ class TRINITY_DLL_SPEC Creature : public Unit
|
||||
uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance
|
||||
float m_respawnradius;
|
||||
|
||||
bool m_gossipOptionLoaded;
|
||||
GossipOptionList m_goptions;
|
||||
|
||||
ReactStates m_reactState; // for AI, not charmInfo
|
||||
void RegenerateMana();
|
||||
void RegenerateHealth();
|
||||
|
||||
@@ -1180,7 +1180,7 @@ void GameEventMgr::UpdateEventNPCFlags(uint16 event_id)
|
||||
npcflag |= ci->npcflag;
|
||||
cr->SetUInt32Value(UNIT_NPC_FLAGS,npcflag);
|
||||
// reset gossip options, since the flag change might have added / removed some
|
||||
cr->ResetGossipOptions();
|
||||
//cr->ResetGossipOptions();
|
||||
// update to world
|
||||
cr->SendUpdateObjectToAllExcept(NULL);
|
||||
}
|
||||
|
||||
@@ -979,13 +979,13 @@ void GameObject::Use(Unit* user)
|
||||
|
||||
case GAMEOBJECT_TYPE_QUESTGIVER: //2
|
||||
{
|
||||
if(user->GetTypeId() != TYPEID_PLAYER)
|
||||
if (user->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
Player* player = (Player*)user;
|
||||
|
||||
player->PrepareQuestMenu( GetGUID() );
|
||||
player->SendPreparedQuest( GetGUID() );
|
||||
player->PrepareGossipMenu(this, GetGOInfo()->questgiver.gossipID);
|
||||
player->SendPreparedGossip(this);
|
||||
return;
|
||||
}
|
||||
//Sitting: Wooden bench, chairs enzz
|
||||
@@ -1090,6 +1090,11 @@ void GameObject::Use(Unit* user)
|
||||
data << GetGUID();
|
||||
player->GetSession()->SendPacket(&data);
|
||||
}
|
||||
else if (info->questgiver.gossipID)
|
||||
{
|
||||
player->PrepareGossipMenu(this, info->goober.gossipID);
|
||||
player->SendPreparedGossip(this);
|
||||
}
|
||||
|
||||
// possible quest objective for active quests
|
||||
player->CastedCreatureOrGO(info->id, GetGUID(), 0);
|
||||
|
||||
@@ -491,6 +491,15 @@ struct GameObjectInfo
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
uint32 GetGossipMenuId() const
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.gossipID;
|
||||
case GAMEOBJECT_TYPE_GOOBER: return goober.gossipID;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class OPvPCapturePoint;
|
||||
|
||||
+21
-8
@@ -29,6 +29,7 @@
|
||||
GossipMenu::GossipMenu()
|
||||
{
|
||||
m_gItems.reserve(16); // can be set for max from most often sizes to speedup push_back and less memory use
|
||||
m_gMenuId = 0;
|
||||
}
|
||||
|
||||
GossipMenu::~GossipMenu()
|
||||
@@ -46,13 +47,24 @@ void GossipMenu::AddMenuItem(uint8 Icon, const std::string& Message, uint32 dtSe
|
||||
gItem.m_gMessage = Message;
|
||||
gItem.m_gCoded = Coded;
|
||||
gItem.m_gSender = dtSender;
|
||||
gItem.m_gAction = dtAction;
|
||||
gItem.m_gOptionId = dtAction;
|
||||
gItem.m_gBoxMessage = BoxMessage;
|
||||
gItem.m_gBoxMoney = BoxMoney;
|
||||
|
||||
m_gItems.push_back(gItem);
|
||||
}
|
||||
|
||||
void GossipMenu::AddGossipMenuItemData(uint32 action_menu, uint32 action_poi, uint32 action_script)
|
||||
{
|
||||
GossipMenuItemData pItemData;
|
||||
|
||||
pItemData.m_gAction_menu = action_menu;
|
||||
pItemData.m_gAction_poi = action_poi;
|
||||
pItemData.m_gAction_script = action_script;
|
||||
|
||||
m_gItemsData.push_back(pItemData);
|
||||
}
|
||||
|
||||
void GossipMenu::AddMenuItem(uint8 Icon, const std::string& Message, bool Coded)
|
||||
{
|
||||
AddMenuItem( Icon, Message, 0, 0, "", 0, Coded);
|
||||
@@ -79,7 +91,7 @@ uint32 GossipMenu::MenuItemAction( unsigned int ItemId )
|
||||
{
|
||||
if ( ItemId >= m_gItems.size() ) return 0;
|
||||
|
||||
return m_gItems[ ItemId ].m_gAction;
|
||||
return m_gItems[ ItemId ].m_gOptionId;
|
||||
}
|
||||
|
||||
bool GossipMenu::MenuItemCoded( unsigned int ItemId )
|
||||
@@ -92,6 +104,7 @@ bool GossipMenu::MenuItemCoded( unsigned int ItemId )
|
||||
void GossipMenu::ClearMenu()
|
||||
{
|
||||
m_gItems.clear();
|
||||
m_gItemsData.clear();
|
||||
}
|
||||
|
||||
PlayerMenu::PlayerMenu( WorldSession *session ) : pSession(session)
|
||||
@@ -124,13 +137,13 @@ bool PlayerMenu::GossipOptionCoded( unsigned int Selection )
|
||||
return mGossipMenu.MenuItemCoded( Selection );
|
||||
}
|
||||
|
||||
void PlayerMenu::SendGossipMenu( uint32 TitleTextId, uint64 npcGUID )
|
||||
void PlayerMenu::SendGossipMenu(uint32 TitleTextId, uint64 objectGUID)
|
||||
{
|
||||
WorldPacket data( SMSG_GOSSIP_MESSAGE, (100) ); // guess size
|
||||
data << uint64(npcGUID);
|
||||
data << uint32(0); // new 2.4.0
|
||||
data << uint32( TitleTextId );
|
||||
data << uint32( mGossipMenu.MenuItemCount() ); // max count 0x10
|
||||
WorldPacket data(SMSG_GOSSIP_MESSAGE, (100)); // guess size
|
||||
data << uint64(objectGUID);
|
||||
data << uint32(mGossipMenu.GetMenuId()); // new 2.4.0
|
||||
data << uint32(TitleTextId);
|
||||
data << uint32(mGossipMenu.MenuItemCount()); // max count 0x10
|
||||
|
||||
for (uint32 iI = 0; iI < mGossipMenu.MenuItemCount(); ++iI )
|
||||
{
|
||||
|
||||
+65
-2
@@ -30,6 +30,47 @@ class WorldSession;
|
||||
#define GOSSIP_MAX_MENU_ITEMS 64 // client supported items unknown, but provided number must be enough
|
||||
#define DEFAULT_GOSSIP_MESSAGE 0xffffff
|
||||
|
||||
enum Gossip_Option
|
||||
{
|
||||
GOSSIP_OPTION_NONE = 0, //UNIT_NPC_FLAG_NONE (0)
|
||||
GOSSIP_OPTION_GOSSIP = 1, //UNIT_NPC_FLAG_GOSSIP (1)
|
||||
GOSSIP_OPTION_QUESTGIVER = 2, //UNIT_NPC_FLAG_QUESTGIVER (2)
|
||||
GOSSIP_OPTION_VENDOR = 3, //UNIT_NPC_FLAG_VENDOR (128)
|
||||
GOSSIP_OPTION_TAXIVENDOR = 4, //UNIT_NPC_FLAG_TAXIVENDOR (8192)
|
||||
GOSSIP_OPTION_TRAINER = 5, //UNIT_NPC_FLAG_TRAINER (16)
|
||||
GOSSIP_OPTION_SPIRITHEALER = 6, //UNIT_NPC_FLAG_SPIRITHEALER (16384)
|
||||
GOSSIP_OPTION_SPIRITGUIDE = 7, //UNIT_NPC_FLAG_SPIRITGUIDE (32768)
|
||||
GOSSIP_OPTION_INNKEEPER = 8, //UNIT_NPC_FLAG_INNKEEPER (65536)
|
||||
GOSSIP_OPTION_BANKER = 9, //UNIT_NPC_FLAG_BANKER (131072)
|
||||
GOSSIP_OPTION_PETITIONER = 10, //UNIT_NPC_FLAG_PETITIONER (262144)
|
||||
GOSSIP_OPTION_TABARDDESIGNER = 11, //UNIT_NPC_FLAG_TABARDDESIGNER (524288)
|
||||
GOSSIP_OPTION_BATTLEFIELD = 12, //UNIT_NPC_FLAG_BATTLEFIELDPERSON (1048576)
|
||||
GOSSIP_OPTION_AUCTIONEER = 13, //UNIT_NPC_FLAG_AUCTIONEER (2097152)
|
||||
GOSSIP_OPTION_STABLEPET = 14, //UNIT_NPC_FLAG_STABLE (4194304)
|
||||
GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER (4096)
|
||||
GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER)
|
||||
GOSSIP_OPTION_UNLEARNPETSKILLS = 17, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER)
|
||||
GOSSIP_OPTION_LEARNDUALSPEC = 18, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER)
|
||||
GOSSIP_OPTION_OUTDOORPVP = 19, //added by code (option for outdoor pvp creatures)
|
||||
GOSSIP_OPTION_MAX
|
||||
};
|
||||
|
||||
enum GossipOptionIcon
|
||||
{
|
||||
GOSSIP_ICON_CHAT = 0, //white chat bubble
|
||||
GOSSIP_ICON_VENDOR = 1, //brown bag
|
||||
GOSSIP_ICON_TAXI = 2, //flight
|
||||
GOSSIP_ICON_TRAINER = 3, //book
|
||||
GOSSIP_ICON_INTERACT_1 = 4, //interaction wheel
|
||||
GOSSIP_ICON_INTERACT_2 = 5, //interaction wheel
|
||||
GOSSIP_ICON_MONEY_BAG = 6, //brown bag with yellow dot
|
||||
GOSSIP_ICON_TALK = 7, //white chat bubble with black dots
|
||||
GOSSIP_ICON_TABARD = 8, //tabard
|
||||
GOSSIP_ICON_BATTLE = 9, //two swords
|
||||
GOSSIP_ICON_DOT = 10, //yellow dot
|
||||
GOSSIP_ICON_MAX
|
||||
};
|
||||
|
||||
//POI icons. Many more exist, list not complete.
|
||||
enum Poi_Icon
|
||||
{
|
||||
@@ -82,13 +123,22 @@ struct GossipMenuItem
|
||||
bool m_gCoded;
|
||||
std::string m_gMessage;
|
||||
uint32 m_gSender;
|
||||
uint32 m_gAction;
|
||||
uint32 m_gOptionId;
|
||||
std::string m_gBoxMessage;
|
||||
uint32 m_gBoxMoney;
|
||||
};
|
||||
|
||||
typedef std::vector<GossipMenuItem> GossipMenuItemList;
|
||||
|
||||
struct GossipMenuItemData
|
||||
{
|
||||
uint32 m_gAction_menu;
|
||||
uint32 m_gAction_poi;
|
||||
uint32 m_gAction_script;
|
||||
};
|
||||
|
||||
typedef std::vector<GossipMenuItemData> GossipMenuItemDataList;
|
||||
|
||||
struct QuestMenuItem
|
||||
{
|
||||
uint32 m_qId;
|
||||
@@ -110,6 +160,11 @@ class TRINITY_DLL_SPEC GossipMenu
|
||||
void AddMenuItem(uint8 Icon, char const* Message, bool Coded = false);
|
||||
void AddMenuItem(uint8 Icon, char const* Message, uint32 dtSender, uint32 dtAction, char const* BoxMessage, uint32 BoxMoney, bool Coded = false);
|
||||
|
||||
void SetMenuId(uint32 menu_id) { m_gMenuId = menu_id; }
|
||||
uint32 GetMenuId() { return m_gMenuId; }
|
||||
|
||||
void AddGossipMenuItemData(uint32 action_menu, uint32 action_poi, uint32 action_script);
|
||||
|
||||
unsigned int MenuItemCount() const
|
||||
{
|
||||
return m_gItems.size();
|
||||
@@ -125,6 +180,11 @@ class TRINITY_DLL_SPEC GossipMenu
|
||||
return m_gItems[ Id ];
|
||||
}
|
||||
|
||||
GossipMenuItemData const& GetItemData(unsigned int indexId)
|
||||
{
|
||||
return m_gItemsData[indexId];
|
||||
}
|
||||
|
||||
uint32 MenuItemSender( unsigned int ItemId );
|
||||
uint32 MenuItemAction( unsigned int ItemId );
|
||||
bool MenuItemCoded( unsigned int ItemId );
|
||||
@@ -132,7 +192,10 @@ class TRINITY_DLL_SPEC GossipMenu
|
||||
void ClearMenu();
|
||||
|
||||
protected:
|
||||
GossipMenuItemList m_gItems;
|
||||
GossipMenuItemList m_gItems;
|
||||
GossipMenuItemDataList m_gItemsData;
|
||||
|
||||
uint32 m_gMenuId;
|
||||
};
|
||||
|
||||
class QuestMenu
|
||||
|
||||
+16
-9
@@ -597,7 +597,6 @@ bool ChatHandler::HandleReloadAllLootCommand(const char*)
|
||||
bool ChatHandler::HandleReloadAllNpcCommand(const char* /*args*/)
|
||||
{
|
||||
HandleReloadNpcGossipCommand("a");
|
||||
HandleReloadNpcOptionCommand("a");
|
||||
HandleReloadNpcTrainerCommand("a");
|
||||
HandleReloadNpcVendorCommand("a");
|
||||
HandleReloadPointsOfInterestCommand("a");
|
||||
@@ -773,6 +772,22 @@ bool ChatHandler::HandleReloadCreatureQuestInvRelationsCommand(const char*)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadGossipMenuCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Re-Loading `gossip_menu` Table!" );
|
||||
objmgr.LoadGossipMenu();
|
||||
SendGlobalSysMessage("DB table `gossip_menu` reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadGossipMenuOptionCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Re-Loading `gossip_menu_option` Table!" );
|
||||
objmgr.LoadGossipMenuItems();
|
||||
SendGlobalSysMessage("DB table `gossip_menu_option` reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadGOQuestRelationsCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Loading Quests Relations... (`gameobject_questrelation`)" );
|
||||
@@ -925,14 +940,6 @@ bool ChatHandler::HandleReloadTrinityStringCommand(const char*)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadNpcOptionCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Re-Loading `npc_option` Table!" );
|
||||
objmgr.LoadNpcOptions();
|
||||
SendGlobalGMSysMessage("DB table `npc_option` reloaded.");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ChatHandler::HandleReloadNpcGossipCommand(const char*)
|
||||
{
|
||||
sLog.outString( "Re-Loading `npc_gossip` Table!" );
|
||||
|
||||
+10
-10
@@ -79,14 +79,14 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
|
||||
{
|
||||
sLog.outDebug("WORLD: CMSG_GOSSIP_SELECT_OPTION");
|
||||
|
||||
uint32 option;
|
||||
uint32 unk;
|
||||
uint32 gossipListId;
|
||||
uint32 menuId;
|
||||
uint64 guid;
|
||||
std::string code = "";
|
||||
|
||||
recv_data >> guid >> unk >> option;
|
||||
recv_data >> guid >> menuId >> gossipListId;
|
||||
|
||||
if(_player->PlayerTalkClass->GossipOptionCoded( option ))
|
||||
if(_player->PlayerTalkClass->GossipOptionCoded(gossipListId))
|
||||
{
|
||||
// recheck
|
||||
sLog.outBasic("reading string");
|
||||
@@ -128,21 +128,21 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data )
|
||||
{
|
||||
if(unit)
|
||||
{
|
||||
if(!Script->GossipSelectWithCode( _player, unit, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option ), code.c_str()) )
|
||||
unit->OnGossipSelect( _player, option );
|
||||
if(!Script->GossipSelectWithCode( _player, unit, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str()) )
|
||||
_player->OnGossipSelect(unit, gossipListId, menuId);
|
||||
}
|
||||
else
|
||||
Script->GOSelectWithCode( _player, go, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option ), code.c_str());
|
||||
Script->GOSelectWithCode( _player, go, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId), code.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
if(unit)
|
||||
{
|
||||
if(!Script->GossipSelect( _player, unit, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option )) )
|
||||
unit->OnGossipSelect( _player, option );
|
||||
if(!Script->GossipSelect( _player, unit, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId)) )
|
||||
_player->OnGossipSelect(unit, gossipListId, menuId);
|
||||
}
|
||||
else
|
||||
Script->GOSelect( _player, go, _player->PlayerTalkClass->GossipOptionSender( option ), _player->PlayerTalkClass->GossipOptionAction( option ));
|
||||
Script->GOSelect( _player, go, _player->PlayerTalkClass->GossipOptionSender(gossipListId), _player->PlayerTalkClass->GossipOptionAction(gossipListId));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -291,11 +291,11 @@ void WorldSession::HandleGossipHelloOpcode( WorldPacket & recv_data )
|
||||
}
|
||||
}
|
||||
|
||||
if(!Script->GossipHello( _player, unit ))
|
||||
if(!Script->GossipHello(_player, unit))
|
||||
{
|
||||
_player->TalkedToCreature(unit->GetEntry(),unit->GetGUID());
|
||||
unit->prepareGossipMenu(_player);
|
||||
unit->sendPreparedGossip(_player);
|
||||
_player->TalkedToCreature(unit->GetEntry(), unit->GetGUID());
|
||||
_player->PrepareGossipMenu(unit, unit->GetCreatureInfo()->GossipMenuId);
|
||||
_player->SendPreparedGossip(unit);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+194
-29
@@ -45,6 +45,7 @@
|
||||
#include "Util.h"
|
||||
#include "WaypointManager.h"
|
||||
#include "InstanceData.h" //for condition_instance_data
|
||||
#include "GossipDef.h"
|
||||
|
||||
INSTANTIATE_SINGLETON_1(ObjectMgr);
|
||||
|
||||
@@ -53,6 +54,7 @@ ScriptMapMap sQuestStartScripts;
|
||||
ScriptMapMap sSpellScripts;
|
||||
ScriptMapMap sGameObjectScripts;
|
||||
ScriptMapMap sEventScripts;
|
||||
ScriptMapMap sGossipScripts;
|
||||
ScriptMapMap sWaypointScripts;
|
||||
|
||||
bool normalizePlayerName(std::string& name)
|
||||
@@ -377,14 +379,14 @@ void ObjectMgr::LoadCreatureLocales()
|
||||
|
||||
void ObjectMgr::LoadNpcOptionLocales()
|
||||
{
|
||||
mNpcOptionLocaleMap.clear(); // need for reload case
|
||||
mGossipMenuItemsLocaleMap.clear(); // need for reload case
|
||||
|
||||
QueryResult *result = WorldDatabase.Query("SELECT entry,"
|
||||
QueryResult *result = WorldDatabase.Query("SELECT menu_id,id,"
|
||||
"option_text_loc1,box_text_loc1,option_text_loc2,box_text_loc2,"
|
||||
"option_text_loc3,box_text_loc3,option_text_loc4,box_text_loc4,"
|
||||
"option_text_loc5,box_text_loc5,option_text_loc6,box_text_loc6,"
|
||||
"option_text_loc7,box_text_loc7,option_text_loc8,box_text_loc8 "
|
||||
"FROM locales_npc_option");
|
||||
"FROM locales_gossip_menu_option");
|
||||
|
||||
if(!result)
|
||||
{
|
||||
@@ -393,7 +395,7 @@ void ObjectMgr::LoadNpcOptionLocales()
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded 0 npc_option locale strings. DB table `locales_npc_option` is empty.");
|
||||
sLog.outString(">> Loaded 0 gossip_menu_option locale strings. DB table `locales_npc_option` is empty.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -404,9 +406,10 @@ void ObjectMgr::LoadNpcOptionLocales()
|
||||
Field *fields = result->Fetch();
|
||||
bar.step();
|
||||
|
||||
uint32 entry = fields[0].GetUInt32();
|
||||
uint16 menuId = fields[0].GetUInt16();
|
||||
uint16 id = fields[1].GetUInt16();
|
||||
|
||||
NpcOptionLocale& data = mNpcOptionLocaleMap[entry];
|
||||
GossipMenuItemsLocale& data = mGossipMenuItemsLocaleMap[MAKE_PAIR32(menuId,id)];
|
||||
|
||||
for (uint8 i = 1; i < MAX_LOCALE; ++i)
|
||||
{
|
||||
@@ -440,7 +443,7 @@ void ObjectMgr::LoadNpcOptionLocales()
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %lu npc_option locale strings", (unsigned long)mNpcOptionLocaleMap.size() );
|
||||
sLog.outString( ">> Loaded %lu gossip_menu_option locale strings", (unsigned long)mGossipMenuItemsLocaleMap.size() );
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadPointOfInterestLocales()
|
||||
@@ -4696,6 +4699,13 @@ void ObjectMgr::LoadWaypointScripts()
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadGossipScripts()
|
||||
{
|
||||
LoadScripts(sGossipScripts, "gossip_scripts");
|
||||
|
||||
// checks are done in LoadGossipMenuItems
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadItemTexts()
|
||||
{
|
||||
QueryResult *result = CharacterDatabase.Query("SELECT id, text FROM item_text");
|
||||
@@ -8293,23 +8303,21 @@ void ObjectMgr::LoadNpcTextId()
|
||||
sLog.outString( ">> Loaded %d NpcTextId ", count );
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadNpcOptions()
|
||||
void ObjectMgr::LoadGossipMenu()
|
||||
{
|
||||
m_mCacheNpcOptionList.clear(); // For reload case
|
||||
m_mGossipMenusMap.clear();
|
||||
|
||||
QueryResult *result = WorldDatabase.Query(
|
||||
// 0 1 2 3 4 5 6 7 8
|
||||
"SELECT id,gossip_id,npcflag,icon,action,box_money,coded,option_text,box_text "
|
||||
"FROM npc_option");
|
||||
QueryResult* result = WorldDatabase.Query("SELECT entry, text_id, "
|
||||
"cond_1, cond_1_val_1, cond_1_val_2, cond_2, cond_2_val_1, cond_2_val_2 FROM gossip_menu");
|
||||
|
||||
if( !result )
|
||||
if(!result)
|
||||
{
|
||||
barGoLink bar( 1 );
|
||||
barGoLink bar(1);
|
||||
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outErrorDb(">> Loaded `npc_option`, table is empty!");
|
||||
sLog.outErrorDb(">> Loaded `gossip_menu`, table is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8323,26 +8331,183 @@ void ObjectMgr::LoadNpcOptions()
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
GossipOption go;
|
||||
go.Id = fields[0].GetUInt32();
|
||||
go.GossipId = fields[1].GetUInt32();
|
||||
go.NpcFlag = fields[2].GetUInt32();
|
||||
go.Icon = fields[3].GetUInt32();
|
||||
go.Action = fields[4].GetUInt32();
|
||||
go.BoxMoney = fields[5].GetUInt32();
|
||||
go.Coded = fields[6].GetUInt8()!=0;
|
||||
go.OptionText = fields[7].GetCppString();
|
||||
go.BoxText = fields[8].GetCppString();
|
||||
GossipMenus gMenu;
|
||||
|
||||
m_mCacheNpcOptionList.push_back(go);
|
||||
gMenu.entry = fields[0].GetUInt32();
|
||||
gMenu.text_id = fields[1].GetUInt32();
|
||||
|
||||
ConditionType cond_1 = (ConditionType)fields[2].GetUInt32();
|
||||
uint32 cond_1_val_1 = fields[3].GetUInt32();
|
||||
uint32 cond_1_val_2 = fields[4].GetUInt32();
|
||||
ConditionType cond_2 = (ConditionType)fields[5].GetUInt32();
|
||||
uint32 cond_2_val_1 = fields[6].GetUInt32();
|
||||
uint32 cond_2_val_2 = fields[7].GetUInt32();
|
||||
|
||||
if (!GetGossipText(gMenu.text_id))
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu entry %u are using non-existing text_id %u", gMenu.entry, gMenu.text_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!PlayerCondition::IsValid(cond_1, cond_1_val_1, cond_1_val_2))
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu entry %u, invalid condition 1 for id %u", gMenu.entry, gMenu.text_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!PlayerCondition::IsValid(cond_2, cond_2_val_1, cond_2_val_2))
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu entry %u, invalid condition 2 for id %u", gMenu.entry, gMenu.text_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
gMenu.cond_1 = GetConditionId(cond_1, cond_1_val_1, cond_1_val_2);
|
||||
gMenu.cond_2 = GetConditionId(cond_2, cond_2_val_1, cond_2_val_2);
|
||||
|
||||
m_mGossipMenusMap.insert(GossipMenusMap::value_type(gMenu.entry, gMenu));
|
||||
|
||||
++count;
|
||||
}
|
||||
while(result->NextRow());
|
||||
|
||||
} while (result->NextRow());
|
||||
delete result;
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString( ">> Loaded %d npc_option entries", count );
|
||||
sLog.outString( ">> Loaded %u gossip_menu entries", count);
|
||||
}
|
||||
|
||||
void ObjectMgr::LoadGossipMenuItems()
|
||||
{
|
||||
m_mGossipMenuItemsMap.clear();
|
||||
|
||||
QueryResult *result = WorldDatabase.Query(
|
||||
"SELECT menu_id, id, option_icon, option_text, option_id, npc_option_npcflag, "
|
||||
"action_menu_id, action_poi_id, action_script_id, box_coded, box_money, box_text, "
|
||||
"cond_1, cond_1_val_1, cond_1_val_2, "
|
||||
"cond_2, cond_2_val_1, cond_2_val_2, "
|
||||
"cond_3, cond_3_val_1, cond_3_val_2 "
|
||||
"FROM gossip_menu_option");
|
||||
|
||||
if (!result)
|
||||
{
|
||||
barGoLink bar(1);
|
||||
|
||||
bar.step();
|
||||
|
||||
sLog.outString();
|
||||
sLog.outErrorDb(">> Loaded gossip_menu_option, table is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
barGoLink bar(result->GetRowCount());
|
||||
|
||||
uint32 count = 0;
|
||||
|
||||
std::set<uint32> gossipScriptSet;
|
||||
|
||||
for(ScriptMapMap::const_iterator itr = sGossipScripts.begin(); itr != sGossipScripts.end(); ++itr)
|
||||
gossipScriptSet.insert(itr->first);
|
||||
|
||||
do
|
||||
{
|
||||
bar.step();
|
||||
|
||||
Field* fields = result->Fetch();
|
||||
|
||||
GossipMenuItems gMenuItem;
|
||||
|
||||
gMenuItem.menu_id = fields[0].GetUInt32();
|
||||
gMenuItem.id = fields[1].GetUInt32();
|
||||
gMenuItem.option_icon = fields[2].GetUInt8();
|
||||
gMenuItem.option_text = fields[3].GetCppString();
|
||||
gMenuItem.option_id = fields[4].GetUInt32();
|
||||
gMenuItem.npc_option_npcflag = fields[5].GetUInt32();
|
||||
gMenuItem.action_menu_id = fields[6].GetUInt32();
|
||||
gMenuItem.action_poi_id = fields[7].GetUInt32();
|
||||
gMenuItem.action_script_id = fields[8].GetUInt32();
|
||||
gMenuItem.box_coded = fields[9].GetUInt8() != 0;
|
||||
gMenuItem.box_money = fields[10].GetUInt32();
|
||||
gMenuItem.box_text = fields[11].GetCppString();
|
||||
|
||||
ConditionType cond_1 = (ConditionType)fields[12].GetUInt32();
|
||||
uint32 cond_1_val_1 = fields[13].GetUInt32();
|
||||
uint32 cond_1_val_2 = fields[14].GetUInt32();
|
||||
ConditionType cond_2 = (ConditionType)fields[15].GetUInt32();
|
||||
uint32 cond_2_val_1 = fields[16].GetUInt32();
|
||||
uint32 cond_2_val_2 = fields[17].GetUInt32();
|
||||
ConditionType cond_3 = (ConditionType)fields[18].GetUInt32();
|
||||
uint32 cond_3_val_1 = fields[19].GetUInt32();
|
||||
uint32 cond_3_val_2 = fields[20].GetUInt32();
|
||||
|
||||
if (!PlayerCondition::IsValid(cond_1, cond_1_val_1, cond_1_val_2))
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 1 for id %u", gMenuItem.menu_id, gMenuItem.id);
|
||||
continue;
|
||||
}
|
||||
if (!PlayerCondition::IsValid(cond_2, cond_2_val_1, cond_2_val_2))
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 2 for id %u", gMenuItem.menu_id, gMenuItem.id);
|
||||
continue;
|
||||
}
|
||||
if (!PlayerCondition::IsValid(cond_3, cond_3_val_1, cond_3_val_2))
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu_option menu %u, invalid condition 3 for id %u", gMenuItem.menu_id, gMenuItem.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (gMenuItem.option_icon >= GOSSIP_ICON_MAX)
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has unknown icon id %u. Replacing with GOSSIP_ICON_CHAT", gMenuItem.menu_id, gMenuItem.id, gMenuItem.option_icon);
|
||||
gMenuItem.option_icon = GOSSIP_ICON_CHAT;
|
||||
}
|
||||
|
||||
if (gMenuItem.option_id >= GOSSIP_OPTION_MAX)
|
||||
sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u has unknown option id %u. Option will not be used", gMenuItem.menu_id, gMenuItem.id, gMenuItem.option_id);
|
||||
|
||||
if (gMenuItem.action_poi_id && !GetPointOfInterest(gMenuItem.action_poi_id))
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u use non-existing action_poi_id %u, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_poi_id);
|
||||
gMenuItem.action_poi_id = 0;
|
||||
}
|
||||
|
||||
if (gMenuItem.action_script_id)
|
||||
{
|
||||
if (gMenuItem.option_id != GOSSIP_OPTION_GOSSIP)
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u have action_script_id %u but option_id is not GOSSIP_OPTION_GOSSIP, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_script_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sGossipScripts.find(gMenuItem.action_script_id) == sGossipScripts.end())
|
||||
{
|
||||
sLog.outErrorDb("Table gossip_menu_option for menu %u, id %u have action_script_id %u that does not exist in `gossip_scripts`, ignoring", gMenuItem.menu_id, gMenuItem.id, gMenuItem.action_script_id);
|
||||
continue;
|
||||
}
|
||||
|
||||
gossipScriptSet.erase(gMenuItem.action_script_id);
|
||||
}
|
||||
|
||||
gMenuItem.cond_1 = GetConditionId(cond_1, cond_1_val_1, cond_1_val_2);
|
||||
gMenuItem.cond_2 = GetConditionId(cond_2, cond_2_val_1, cond_2_val_2);
|
||||
gMenuItem.cond_3 = GetConditionId(cond_3, cond_3_val_1, cond_3_val_2);
|
||||
|
||||
m_mGossipMenuItemsMap.insert(GossipMenuItemsMap::value_type(gMenuItem.menu_id, gMenuItem));
|
||||
|
||||
++count;
|
||||
|
||||
}
|
||||
while(result->NextRow());
|
||||
|
||||
delete result;
|
||||
|
||||
if (!gossipScriptSet.empty())
|
||||
{
|
||||
for(std::set<uint32>::const_iterator itr = gossipScriptSet.begin(); itr != gossipScriptSet.end(); ++itr)
|
||||
sLog.outErrorDb("Table `gossip_scripts` contain unused script, id %u.", *itr);
|
||||
}
|
||||
|
||||
sLog.outString();
|
||||
sLog.outString(">> Loaded %u gossip_menu_option entries", count);
|
||||
}
|
||||
|
||||
void ObjectMgr::AddVendorItem( uint32 entry,uint32 item, uint32 maxcount, uint32 incrtime, uint32 extendedcost, bool savetodb)
|
||||
|
||||
+56
-12
@@ -74,7 +74,6 @@ struct GameTele
|
||||
};
|
||||
|
||||
typedef UNORDERED_MAP<uint32, GameTele > GameTeleMap;
|
||||
typedef std::list<GossipOption> CacheNpcOptionList;
|
||||
|
||||
struct ScriptInfo
|
||||
{
|
||||
@@ -97,6 +96,7 @@ extern ScriptMapMap sQuestStartScripts;
|
||||
extern ScriptMapMap sSpellScripts;
|
||||
extern ScriptMapMap sGameObjectScripts;
|
||||
extern ScriptMapMap sEventScripts;
|
||||
extern ScriptMapMap sGossipScripts;
|
||||
extern ScriptMapMap sWaypointScripts;
|
||||
|
||||
struct SpellClickInfo
|
||||
@@ -163,7 +163,7 @@ typedef UNORDERED_MAP<uint32,QuestLocale> QuestLocaleMap;
|
||||
typedef UNORDERED_MAP<uint32,NpcTextLocale> NpcTextLocaleMap;
|
||||
typedef UNORDERED_MAP<uint32,PageTextLocale> PageTextLocaleMap;
|
||||
typedef UNORDERED_MAP<int32,TrinityStringLocale> TrinityStringLocaleMap;
|
||||
typedef UNORDERED_MAP<uint32,NpcOptionLocale> NpcOptionLocaleMap;
|
||||
typedef UNORDERED_MAP<uint32,GossipMenuItemsLocale> GossipMenuItemsLocaleMap;
|
||||
typedef UNORDERED_MAP<uint32,PointOfInterestLocale> PointOfInterestLocaleMap;
|
||||
|
||||
typedef std::multimap<uint32,uint32> QuestRelations;
|
||||
@@ -217,6 +217,38 @@ struct PointOfInterest
|
||||
std::string icon_name;
|
||||
};
|
||||
|
||||
struct GossipMenuItems
|
||||
{
|
||||
uint32 menu_id;
|
||||
uint32 id;
|
||||
uint8 option_icon;
|
||||
std::string option_text;
|
||||
uint32 option_id;
|
||||
uint32 npc_option_npcflag;
|
||||
uint32 action_menu_id;
|
||||
uint32 action_poi_id;
|
||||
uint32 action_script_id;
|
||||
bool box_coded;
|
||||
uint32 box_money;
|
||||
std::string box_text;
|
||||
uint16 cond_1;
|
||||
uint16 cond_2;
|
||||
uint16 cond_3;
|
||||
};
|
||||
|
||||
struct GossipMenus
|
||||
{
|
||||
uint32 entry;
|
||||
uint32 text_id;
|
||||
uint16 cond_1;
|
||||
uint16 cond_2;
|
||||
};
|
||||
|
||||
typedef std::multimap<uint32,GossipMenus> GossipMenusMap;
|
||||
typedef std::pair<GossipMenusMap::const_iterator, GossipMenusMap::const_iterator> GossipMenusMapBounds;
|
||||
typedef std::multimap<uint32,GossipMenuItems> GossipMenuItemsMap;
|
||||
typedef std::pair<GossipMenuItemsMap::const_iterator, GossipMenuItemsMap::const_iterator> GossipMenuItemsMapBounds;
|
||||
|
||||
#define WEATHER_SEASONS 4
|
||||
struct WeatherSeasonChances
|
||||
{
|
||||
@@ -277,7 +309,6 @@ struct PlayerCondition
|
||||
|
||||
// NPC gossip text id
|
||||
typedef UNORDERED_MAP<uint32, uint32> CacheNpcTextIdMap;
|
||||
typedef std::list<GossipOption> CacheNpcOptionList;
|
||||
|
||||
typedef UNORDERED_MAP<uint32, VendorItemData> CacheVendorItemMap;
|
||||
typedef UNORDERED_MAP<uint32, TrainerSpellData> CacheTrainerSpellMap;
|
||||
@@ -537,6 +568,7 @@ class ObjectMgr
|
||||
void LoadQuestStartScripts();
|
||||
void LoadEventScripts();
|
||||
void LoadSpellScripts();
|
||||
void LoadGossipScripts();
|
||||
void LoadWaypointScripts();
|
||||
|
||||
void LoadTransportEvents();
|
||||
@@ -596,8 +628,11 @@ class ObjectMgr
|
||||
void LoadWeatherZoneChances();
|
||||
void LoadGameTele();
|
||||
|
||||
void LoadNpcOptions();
|
||||
void LoadNpcTextId();
|
||||
|
||||
void LoadGossipMenu();
|
||||
void LoadGossipMenuItems();
|
||||
|
||||
void LoadVendors();
|
||||
void LoadTrainerSpell();
|
||||
void LoadGMTickets();
|
||||
@@ -715,10 +750,10 @@ class ObjectMgr
|
||||
if(itr==mPageTextLocaleMap.end()) return NULL;
|
||||
return &itr->second;
|
||||
}
|
||||
NpcOptionLocale const* GetNpcOptionLocale(uint32 entry) const
|
||||
GossipMenuItemsLocale const* GetGossipMenuItemsLocale(uint32 entry) const
|
||||
{
|
||||
NpcOptionLocaleMap::const_iterator itr = mNpcOptionLocaleMap.find(entry);
|
||||
if(itr==mNpcOptionLocaleMap.end()) return NULL;
|
||||
GossipMenuItemsLocaleMap::const_iterator itr = mGossipMenuItemsLocaleMap.find(entry);
|
||||
if(itr==mGossipMenuItemsLocaleMap.end()) return NULL;
|
||||
return &itr->second;
|
||||
}
|
||||
PointOfInterestLocale const* GetPointOfInterestLocale(uint32 poi_id) const
|
||||
@@ -805,8 +840,6 @@ class ObjectMgr
|
||||
bool AddGameTele(GameTele& data);
|
||||
bool DeleteGameTele(const std::string& name);
|
||||
|
||||
CacheNpcOptionList const& GetNpcOptions() const { return m_mCacheNpcOptionList; }
|
||||
|
||||
uint32 GetNpcGossip(uint32 entry) const
|
||||
{
|
||||
CacheNpcTextIdMap::const_iterator iter = m_mCacheNpcTextIdMap.find(entry);
|
||||
@@ -871,6 +904,16 @@ class ObjectMgr
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GossipMenusMapBounds GetGossipMenusMapBounds(uint32 uiMenuId) const
|
||||
{
|
||||
return GossipMenusMapBounds(m_mGossipMenusMap.lower_bound(uiMenuId),m_mGossipMenusMap.upper_bound(uiMenuId));
|
||||
}
|
||||
|
||||
GossipMenuItemsMapBounds GetGossipMenuItemsMapBounds(uint32 uiMenuId) const
|
||||
{
|
||||
return GossipMenuItemsMapBounds(m_mGossipMenuItemsMap.lower_bound(uiMenuId),m_mGossipMenuItemsMap.upper_bound(uiMenuId));
|
||||
}
|
||||
|
||||
void AddOrUpdateGMTicket(GM_Ticket &ticket, bool create = false);
|
||||
void _AddOrUpdateGMTicket(GM_Ticket &ticket);
|
||||
void RemoveGMTicket(uint64 ticketGuid, int64 source = -1, bool permanently = false);
|
||||
@@ -928,7 +971,9 @@ class ObjectMgr
|
||||
|
||||
RepOnKillMap mRepOnKill;
|
||||
|
||||
PointOfInterestMap mPointsOfInterest;
|
||||
GossipMenusMap m_mGossipMenusMap;
|
||||
GossipMenuItemsMap m_mGossipMenuItemsMap;
|
||||
PointOfInterestMap mPointsOfInterest;
|
||||
|
||||
WeatherZoneMap mWeatherZoneMap;
|
||||
|
||||
@@ -997,7 +1042,7 @@ class ObjectMgr
|
||||
NpcTextLocaleMap mNpcTextLocaleMap;
|
||||
PageTextLocaleMap mPageTextLocaleMap;
|
||||
TrinityStringLocaleMap mTrinityStringLocaleMap;
|
||||
NpcOptionLocaleMap mNpcOptionLocaleMap;
|
||||
GossipMenuItemsLocaleMap mGossipMenuItemsLocaleMap;
|
||||
PointOfInterestLocaleMap mPointOfInterestLocaleMap;
|
||||
RespawnTimes mCreatureRespawnTimes;
|
||||
RespawnTimes mGORespawnTimes;
|
||||
@@ -1006,7 +1051,6 @@ class ObjectMgr
|
||||
typedef std::vector<PlayerCondition> ConditionStore;
|
||||
ConditionStore mConditions;
|
||||
|
||||
CacheNpcOptionList m_mCacheNpcOptionList;
|
||||
CacheNpcTextIdMap m_mCacheNpcTextIdMap;
|
||||
CacheVendorItemMap m_mCacheVendorItemMap;
|
||||
CacheTrainerSpellMap m_mCacheTrainerSpellMap;
|
||||
|
||||
@@ -506,7 +506,7 @@ bool OutdoorPvP::HandleGossipOption(Player * plr, uint64 guid, uint32 id)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OutdoorPvP::CanTalkTo(Player * plr, Creature * c, GossipOption &gso)
|
||||
bool OutdoorPvP::CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso)
|
||||
{
|
||||
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
if(itr->second->CanTalkTo(plr, c, gso))
|
||||
@@ -529,7 +529,7 @@ bool OPvPCapturePoint::HandleGossipOption(Player * plr, uint64 guid, uint32 id)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OPvPCapturePoint::CanTalkTo(Player * plr, Creature * c, GossipOption &gso)
|
||||
bool OPvPCapturePoint::CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class GameObject;
|
||||
class WorldPacket;
|
||||
class Creature;
|
||||
class Unit;
|
||||
struct GossipOption;
|
||||
struct GossipMenuItems;
|
||||
|
||||
typedef std::set<Player*> PlayerSet;
|
||||
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
|
||||
virtual bool HandleGossipOption(Player *plr, uint64 guid, uint32 gossipid);
|
||||
|
||||
virtual bool CanTalkTo(Player * plr, Creature * c, GossipOption &gso);
|
||||
virtual bool CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso);
|
||||
|
||||
virtual bool HandleDropFlag(Player * plr, uint32 spellId);
|
||||
|
||||
@@ -217,7 +217,7 @@ public:
|
||||
|
||||
virtual bool HandleGossipOption(Player *plr, uint64 guid, uint32 gossipid);
|
||||
|
||||
virtual bool CanTalkTo(Player * plr, Creature * c, GossipOption &gso);
|
||||
virtual bool CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso);
|
||||
|
||||
void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2 = 0);
|
||||
protected:
|
||||
|
||||
@@ -616,86 +616,9 @@ void OPvPCapturePointEP_PWT::SummonFlightMaster(uint32 team)
|
||||
m_FlightMasterSpawned = team;
|
||||
DelCreature(EP_PWT_FLIGHTMASTER);
|
||||
AddCreature(EP_PWT_FLIGHTMASTER,EP_PWT_FlightMaster.entry,team,EP_PWT_FlightMaster.map,EP_PWT_FlightMaster.x,EP_PWT_FlightMaster.y,EP_PWT_FlightMaster.z,EP_PWT_FlightMaster.o);
|
||||
Creature * c = HashMapHolder<Creature>::Find(m_Creatures[EP_PWT_FLIGHTMASTER]);
|
||||
if(c)
|
||||
{
|
||||
GossipOption gso;
|
||||
gso.Action = GOSSIP_OPTION_OUTDOORPVP;
|
||||
gso.GossipId = 0;
|
||||
gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_NPT));
|
||||
gso.Id = 50;
|
||||
gso.Icon = 0;
|
||||
gso.NpcFlag = 0;
|
||||
c->addGossipOption(gso);
|
||||
|
||||
gso.Action = GOSSIP_OPTION_OUTDOORPVP;
|
||||
gso.GossipId = 0;
|
||||
gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_EWT));
|
||||
gso.Id = 50;
|
||||
gso.Icon = 0;
|
||||
gso.NpcFlag = 0;
|
||||
c->addGossipOption(gso);
|
||||
|
||||
gso.Action = GOSSIP_OPTION_OUTDOORPVP;
|
||||
gso.GossipId = 0;
|
||||
gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_FLIGHT_CGT));
|
||||
gso.Id = 50;
|
||||
gso.Icon = 0;
|
||||
gso.NpcFlag = 0;
|
||||
c->addGossipOption(gso);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool OPvPCapturePointEP_PWT::CanTalkTo(Player * p, Creature * c, GossipOption &gso)
|
||||
{
|
||||
if( p->GetTeam() == m_FlightMasterSpawned &&
|
||||
c->GetGUID() == m_Creatures[EP_PWT_FLIGHTMASTER] &&
|
||||
gso.Id == 50 )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OPvPCapturePointEP_PWT::HandleGossipOption(Player *plr, uint64 guid, uint32 gossipid)
|
||||
{
|
||||
std::map<uint64,uint32>::iterator itr = m_CreatureTypes.find(guid);
|
||||
if(itr != m_CreatureTypes.end())
|
||||
{
|
||||
Creature * cr = HashMapHolder<Creature>::Find(guid);
|
||||
if(!cr)
|
||||
return true;
|
||||
if(itr->second == EP_PWT_FLIGHTMASTER)
|
||||
{
|
||||
uint32 src = EP_PWT_Taxi;
|
||||
uint32 dst = 0;
|
||||
switch(gossipid)
|
||||
{
|
||||
case 0:
|
||||
dst = EP_NPT_Taxi;
|
||||
break;
|
||||
case 1:
|
||||
dst = EP_EWT_Taxi;
|
||||
break;
|
||||
default:
|
||||
dst = EP_CGT_Taxi;
|
||||
break;
|
||||
}
|
||||
|
||||
std::vector<uint32> nodes;
|
||||
nodes.resize(2);
|
||||
nodes[0] = src;
|
||||
nodes[1] = dst;
|
||||
|
||||
plr->PlayerTalkClass->CloseGossip();
|
||||
plr->ActivateTaxiPathTo(nodes, cr);
|
||||
// leave the opvp, seems like moveinlineofsight isn't called when entering a taxi
|
||||
HandlePlayerLeave(plr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// ep
|
||||
OutdoorPvPEP::OutdoorPvPEP()
|
||||
{
|
||||
|
||||
@@ -246,8 +246,6 @@ public:
|
||||
// used when player is activated/inactivated in the area
|
||||
bool HandlePlayerEnter(Player * plr);
|
||||
void HandlePlayerLeave(Player * plr);
|
||||
bool HandleGossipOption(Player *plr, uint64 guid, uint32 gossipid);
|
||||
bool CanTalkTo(Player * plr, Creature * c, GossipOption &gso);
|
||||
protected:
|
||||
void SummonFlightMaster(uint32 team);
|
||||
void UpdateTowerState();
|
||||
|
||||
@@ -231,7 +231,7 @@ void OutdoorPvPMgr::HandleGossipOption(Player *plr, uint64 guid, uint32 gossipid
|
||||
}
|
||||
}
|
||||
|
||||
bool OutdoorPvPMgr::CanTalkTo(Player * plr, Creature * c, GossipOption & gso)
|
||||
bool OutdoorPvPMgr::CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso)
|
||||
{
|
||||
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
void HandleGossipOption(Player * player, uint64 guid, uint32 gossipid);
|
||||
|
||||
bool CanTalkTo(Player * player, Creature * creature, GossipOption & gso);
|
||||
bool CanTalkTo(Player * player, Creature * creature, GossipMenuItems gso);
|
||||
|
||||
void HandleDropFlag(Player * plr, uint32 spellId);
|
||||
|
||||
|
||||
@@ -326,22 +326,16 @@ void OPvPCapturePointZM_GraveYard::SetBeaconState(uint32 controlling_faction)
|
||||
UpdateTowerState();
|
||||
}
|
||||
|
||||
bool OPvPCapturePointZM_GraveYard::CanTalkTo(Player * plr, Creature * c, GossipOption & gso)
|
||||
bool OPvPCapturePointZM_GraveYard::CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso)
|
||||
{
|
||||
uint64 guid = c->GetGUID();
|
||||
std::map<uint64,uint32>::iterator itr = m_CreatureTypes.find(guid);
|
||||
if(itr != m_CreatureTypes.end())
|
||||
{
|
||||
if(itr->second == ZM_ALLIANCE_FIELD_SCOUT && plr->GetTeam() == ALLIANCE && m_BothControllingFaction == ALLIANCE && !m_FlagCarrierGUID && m_GraveYardState != ZM_GRAVEYARD_A)
|
||||
{
|
||||
gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_GOSSIP_ALLIANCE));
|
||||
return true;
|
||||
}
|
||||
else if(itr->second == ZM_HORDE_FIELD_SCOUT && plr->GetTeam() == HORDE && m_BothControllingFaction == HORDE && !m_FlagCarrierGUID && m_GraveYardState != ZM_GRAVEYARD_H)
|
||||
{
|
||||
gso.OptionText.assign(objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_GOSSIP_HORDE));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ public:
|
||||
void SetBeaconState(uint32 controlling_team); // not good atm
|
||||
bool HandleGossipOption(Player * plr, uint64 guid, uint32 gossipid);
|
||||
bool HandleDropFlag(Player * plr, uint32 spellId);
|
||||
bool CanTalkTo(Player * plr, Creature * c, GossipOption &gso);
|
||||
bool CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso);
|
||||
private:
|
||||
uint32 m_GraveYardState;
|
||||
protected:
|
||||
|
||||
+387
-1
@@ -12729,6 +12729,392 @@ void Player::SendNewItem(Item *item, uint32 count, bool received, bool created,
|
||||
GetSession()->SendPacket(&data);
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
/*** GOSSIP SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
void Player::PrepareGossipMenu(WorldObject *pSource, uint32 menuId)
|
||||
{
|
||||
PlayerMenu* pMenu = PlayerTalkClass;
|
||||
pMenu->ClearMenus();
|
||||
|
||||
pMenu->GetGossipMenu().SetMenuId(menuId);
|
||||
|
||||
GossipMenuItemsMapBounds pMenuItemBounds = objmgr.GetGossipMenuItemsMapBounds(menuId);
|
||||
|
||||
// if default menuId and no menu options exist for this, use options from default options
|
||||
if (pMenuItemBounds.first == pMenuItemBounds.second && menuId == GetDefaultGossipMenuForSource(pSource))
|
||||
pMenuItemBounds = objmgr.GetGossipMenuItemsMapBounds(0);
|
||||
|
||||
for(GossipMenuItemsMap::const_iterator itr = pMenuItemBounds.first; itr != pMenuItemBounds.second; ++itr)
|
||||
{
|
||||
bool bCanTalk = true;
|
||||
|
||||
if (itr->second.cond_1 && !objmgr.IsPlayerMeetToCondition(this, itr->second.cond_1))
|
||||
continue;
|
||||
|
||||
if (itr->second.cond_2 && !objmgr.IsPlayerMeetToCondition(this, itr->second.cond_2))
|
||||
continue;
|
||||
|
||||
if (itr->second.cond_3 && !objmgr.IsPlayerMeetToCondition(this, itr->second.cond_3))
|
||||
continue;
|
||||
|
||||
if (pSource->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
Creature *pCreature = (Creature*)pSource;
|
||||
|
||||
uint32 npcflags = pCreature->GetUInt32Value(UNIT_NPC_FLAGS);
|
||||
|
||||
if (!(itr->second.npc_option_npcflag & npcflags))
|
||||
continue;
|
||||
|
||||
switch(itr->second.option_id)
|
||||
{
|
||||
case GOSSIP_OPTION_QUESTGIVER:
|
||||
PrepareQuestMenu(pSource->GetGUID());
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_ARMORER:
|
||||
bCanTalk = false; // added in special mode
|
||||
break;
|
||||
case GOSSIP_OPTION_SPIRITHEALER:
|
||||
if (!isDead())
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_VENDOR:
|
||||
{
|
||||
VendorItemData const* vItems = pCreature->GetVendorItems();
|
||||
if (!vItems || vItems->Empty())
|
||||
{
|
||||
sLog.outErrorDb("Creature %u (Entry: %u) have UNIT_NPC_FLAG_VENDOR but have empty trading item list.", pCreature->GetGUIDLow(), pCreature->GetEntry());
|
||||
bCanTalk = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GOSSIP_OPTION_TRAINER:
|
||||
if (!pCreature->isCanTrainingOf(this, false))
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_LEARNDUALSPEC:
|
||||
if(!(GetSpecsCount() == 1 && pCreature->isCanTrainingAndResetTalentsOf(this) && !(getLevel() < sWorld.getConfig(CONFIG_MIN_DUALSPEC_LEVEL))))
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_UNLEARNTALENTS:
|
||||
if (!pCreature->isCanTrainingAndResetTalentsOf(this))
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_UNLEARNPETSKILLS:
|
||||
if (!GetPet() || GetPet()->getPetType() != HUNTER_PET || GetPet()->m_spells.size() <= 1 || pCreature->GetCreatureInfo()->trainer_type != TRAINER_TYPE_PETS || pCreature->GetCreatureInfo()->trainer_class != CLASS_HUNTER)
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_TAXIVENDOR:
|
||||
if (GetSession()->SendLearnNewTaxiNode(pCreature))
|
||||
return;
|
||||
break;
|
||||
case GOSSIP_OPTION_BATTLEFIELD:
|
||||
if (!pCreature->isCanInteractWithBattleMaster(this, false))
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_STABLEPET:
|
||||
if (getClass() != CLASS_HUNTER)
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_GOSSIP:
|
||||
case GOSSIP_OPTION_SPIRITGUIDE:
|
||||
case GOSSIP_OPTION_INNKEEPER:
|
||||
case GOSSIP_OPTION_BANKER:
|
||||
case GOSSIP_OPTION_PETITIONER:
|
||||
case GOSSIP_OPTION_TABARDDESIGNER:
|
||||
case GOSSIP_OPTION_AUCTIONEER:
|
||||
break; // no checks
|
||||
case GOSSIP_OPTION_OUTDOORPVP:
|
||||
if (!sOutdoorPvPMgr.CanTalkTo(this, pCreature, itr->second))
|
||||
bCanTalk = false;
|
||||
break;
|
||||
default:
|
||||
sLog.outErrorDb("Creature entry %u have unknown gossip option %u for menu %u", pCreature->GetEntry(), itr->second.option_id, itr->second.menu_id);
|
||||
bCanTalk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
GameObject *pGo = (GameObject*)pSource;
|
||||
|
||||
switch(itr->second.option_id)
|
||||
{
|
||||
case GOSSIP_OPTION_QUESTGIVER:
|
||||
if (pGo->GetGoType() == GAMEOBJECT_TYPE_QUESTGIVER)
|
||||
PrepareQuestMenu(pSource->GetGUID());
|
||||
bCanTalk = false;
|
||||
break;
|
||||
case GOSSIP_OPTION_GOSSIP:
|
||||
if (pGo->GetGoType() != GAMEOBJECT_TYPE_QUESTGIVER && pGo->GetGoType() != GAMEOBJECT_TYPE_GOOBER)
|
||||
bCanTalk = false;
|
||||
break;
|
||||
default:
|
||||
bCanTalk = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (bCanTalk)
|
||||
{
|
||||
std::string strOptionText = itr->second.option_text;
|
||||
std::string strBoxText = itr->second.box_text;
|
||||
|
||||
int loc_idx = GetSession()->GetSessionDbLocaleIndex();
|
||||
|
||||
if (loc_idx >= 0)
|
||||
{
|
||||
uint32 idxEntry = MAKE_PAIR32(menuId, itr->second.id);
|
||||
|
||||
if (GossipMenuItemsLocale const *no = objmgr.GetGossipMenuItemsLocale(idxEntry))
|
||||
{
|
||||
if (no->OptionText.size() > (size_t)loc_idx && !no->OptionText[loc_idx].empty())
|
||||
strOptionText = no->OptionText[loc_idx];
|
||||
|
||||
if (no->BoxText.size() > (size_t)loc_idx && !no->BoxText[loc_idx].empty())
|
||||
strBoxText = no->BoxText[loc_idx];
|
||||
}
|
||||
}
|
||||
|
||||
pMenu->GetGossipMenu().AddMenuItem(itr->second.option_icon, strOptionText, 0, itr->second.option_id, strBoxText, itr->second.box_money, itr->second.box_coded);
|
||||
pMenu->GetGossipMenu().AddGossipMenuItemData(itr->second.action_menu_id, itr->second.action_poi_id, itr->second.action_script_id);
|
||||
}
|
||||
}
|
||||
|
||||
// some gossips aren't handled in normal way ... so we need to do it this way .. TODO: handle it in normal way ;-)
|
||||
/*if (pMenu->Empty())
|
||||
{
|
||||
if (pCreature->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_TRAINER))
|
||||
{
|
||||
// output error message if need
|
||||
pCreature->isCanTrainingOf(this, true);
|
||||
}
|
||||
|
||||
if (pCreature->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_BATTLEMASTER))
|
||||
{
|
||||
// output error message if need
|
||||
pCreature->isCanInteractWithBattleMaster(this, true);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void Player::SendPreparedGossip(WorldObject *pSource)
|
||||
{
|
||||
if (!pSource)
|
||||
return;
|
||||
|
||||
if (pSource->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
// in case no gossip flag and quest menu not empty, open quest menu (client expect gossip menu with this flag)
|
||||
if (!((Creature*)pSource)->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_GOSSIP) && !PlayerTalkClass->GetQuestMenu().Empty())
|
||||
{
|
||||
SendPreparedQuest(pSource->GetGUID());
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
// probably need to find a better way here
|
||||
if (!PlayerTalkClass->GetGossipMenu().GetMenuId() && !PlayerTalkClass->GetQuestMenu().Empty())
|
||||
{
|
||||
SendPreparedQuest(pSource->GetGUID());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// in case non empty gossip menu (that not included quests list size) show it
|
||||
// (quest entries from quest menu will be included in list)
|
||||
|
||||
uint32 textId = GetGossipTextId(pSource);
|
||||
|
||||
if (uint32 menuId = PlayerTalkClass->GetGossipMenu().GetMenuId())
|
||||
textId = GetGossipTextId(menuId);
|
||||
|
||||
PlayerTalkClass->SendGossipMenu(textId, pSource->GetGUID());
|
||||
}
|
||||
|
||||
void Player::OnGossipSelect(WorldObject* pSource, uint32 gossipListId, uint32 menuId)
|
||||
{
|
||||
GossipMenu& gossipmenu = PlayerTalkClass->GetGossipMenu();
|
||||
|
||||
if (gossipListId >= gossipmenu.MenuItemCount())
|
||||
return;
|
||||
|
||||
// if not same, then something funky is going on
|
||||
if (menuId != gossipmenu.GetMenuId())
|
||||
return;
|
||||
|
||||
uint32 gossipOptionId = gossipmenu.GetItem(gossipListId).m_gOptionId;
|
||||
uint64 guid = pSource->GetGUID();
|
||||
|
||||
if (pSource->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
{
|
||||
if (gossipOptionId > GOSSIP_OPTION_QUESTGIVER)
|
||||
{
|
||||
sLog.outError("Player guid %u request invalid gossip option for GameObject entry %u", GetGUIDLow(), pSource->GetEntry());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GossipMenuItemData pMenuData = gossipmenu.GetItemData(gossipListId);
|
||||
|
||||
switch(gossipOptionId)
|
||||
{
|
||||
case GOSSIP_OPTION_GOSSIP:
|
||||
{
|
||||
if (pMenuData.m_gAction_menu)
|
||||
{
|
||||
PrepareGossipMenu(pSource, pMenuData.m_gAction_menu);
|
||||
SendPreparedGossip(pSource);
|
||||
}
|
||||
|
||||
if (pMenuData.m_gAction_poi)
|
||||
PlayerTalkClass->SendPointOfInterest(pMenuData.m_gAction_poi);
|
||||
|
||||
if (pMenuData.m_gAction_script)
|
||||
{
|
||||
if (pSource->GetTypeId() == TYPEID_UNIT)
|
||||
GetMap()->ScriptsStart(sGossipScripts, pMenuData.m_gAction_script, this, pSource);
|
||||
else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
GetMap()->ScriptsStart(sGossipScripts, pMenuData.m_gAction_script, pSource, this);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GOSSIP_OPTION_OUTDOORPVP:
|
||||
sOutdoorPvPMgr.HandleGossipOption(this, pSource->GetGUID(), gossipListId);
|
||||
break;
|
||||
case GOSSIP_OPTION_SPIRITHEALER:
|
||||
if (isDead())
|
||||
((Creature*)pSource)->CastSpell(((Creature*)pSource),17251,true,NULL,NULL,GetGUID());
|
||||
break;
|
||||
case GOSSIP_OPTION_QUESTGIVER:
|
||||
PrepareQuestMenu(guid);
|
||||
SendPreparedQuest(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_VENDOR:
|
||||
case GOSSIP_OPTION_ARMORER:
|
||||
GetSession()->SendListInventory(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_STABLEPET:
|
||||
GetSession()->SendStablePet(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_TRAINER:
|
||||
GetSession()->SendTrainerList(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_LEARNDUALSPEC:
|
||||
if(GetSpecsCount() == 1 && !(getLevel() < sWorld.getConfig(CONFIG_MIN_DUALSPEC_LEVEL)))
|
||||
{
|
||||
if (GetMoney() < 10000000)
|
||||
{
|
||||
SendBuyError(BUY_ERR_NOT_ENOUGHT_MONEY, 0, 0, 0);
|
||||
PlayerTalkClass->CloseGossip();
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
ModifyMoney(-10000000);
|
||||
|
||||
// Cast spells that teach dual spec
|
||||
// Both are also ImplicitTarget self and must be cast by player
|
||||
this->CastSpell(this, 63680, true, NULL, NULL, this->GetGUID());
|
||||
this->CastSpell(this, 63624, true, NULL, NULL, this->GetGUID());
|
||||
|
||||
// Should show another Gossip text with "Congratulations..."
|
||||
PlayerTalkClass->CloseGossip();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case GOSSIP_OPTION_UNLEARNTALENTS:
|
||||
PlayerTalkClass->CloseGossip();
|
||||
SendTalentWipeConfirm(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_UNLEARNPETSKILLS:
|
||||
PlayerTalkClass->CloseGossip();
|
||||
SendPetSkillWipeConfirm();
|
||||
break;
|
||||
case GOSSIP_OPTION_TAXIVENDOR:
|
||||
GetSession()->SendTaxiMenu(((Creature*)pSource));
|
||||
break;
|
||||
case GOSSIP_OPTION_INNKEEPER:
|
||||
PlayerTalkClass->CloseGossip();
|
||||
SetBindPoint(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_BANKER:
|
||||
GetSession()->SendShowBank(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_PETITIONER:
|
||||
PlayerTalkClass->CloseGossip();
|
||||
GetSession()->SendPetitionShowList(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_TABARDDESIGNER:
|
||||
PlayerTalkClass->CloseGossip();
|
||||
GetSession()->SendTabardVendorActivate(guid);
|
||||
break;
|
||||
case GOSSIP_OPTION_AUCTIONEER:
|
||||
GetSession()->SendAuctionHello(guid, ((Creature*)pSource));
|
||||
break;
|
||||
case GOSSIP_OPTION_SPIRITGUIDE:
|
||||
PrepareGossipMenu(pSource);
|
||||
SendPreparedGossip(pSource);
|
||||
break;
|
||||
case GOSSIP_OPTION_BATTLEFIELD:
|
||||
{
|
||||
BattleGroundTypeId bgTypeId = sBattleGroundMgr.GetBattleMasterBG(pSource->GetEntry());
|
||||
|
||||
if (bgTypeId == BATTLEGROUND_TYPE_NONE)
|
||||
{
|
||||
sLog.outError("a user (guid %u) requested battlegroundlist from a npc who is no battlemaster", GetGUIDLow());
|
||||
return;
|
||||
}
|
||||
|
||||
GetSession()->SendBattlegGroundList(guid, bgTypeId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Player::GetGossipTextId(WorldObject *pSource)
|
||||
{
|
||||
if (!pSource || pSource->GetTypeId() != TYPEID_UNIT || !((Creature*)pSource)->GetDBTableGUIDLow())
|
||||
return DEFAULT_GOSSIP_MESSAGE;
|
||||
|
||||
if (uint32 pos = objmgr.GetNpcGossip(((Creature*)pSource)->GetDBTableGUIDLow()))
|
||||
return pos;
|
||||
|
||||
return DEFAULT_GOSSIP_MESSAGE;
|
||||
}
|
||||
|
||||
uint32 Player::GetGossipTextId(uint32 menuId)
|
||||
{
|
||||
uint32 textId = DEFAULT_GOSSIP_MESSAGE;
|
||||
|
||||
if (!menuId)
|
||||
return textId;
|
||||
|
||||
GossipMenusMapBounds pMenuBounds = objmgr.GetGossipMenusMapBounds(menuId);
|
||||
|
||||
for(GossipMenusMap::const_iterator itr = pMenuBounds.first; itr != pMenuBounds.second; ++itr)
|
||||
{
|
||||
if (objmgr.IsPlayerMeetToCondition(this, itr->second.cond_1) && objmgr.IsPlayerMeetToCondition(this, itr->second.cond_2))
|
||||
textId = itr->second.text_id;
|
||||
}
|
||||
|
||||
return textId;
|
||||
}
|
||||
|
||||
uint32 Player::GetDefaultGossipMenuForSource(WorldObject *pSource)
|
||||
{
|
||||
if (pSource->GetTypeId() == TYPEID_UNIT)
|
||||
return ((Creature*)pSource)->GetCreatureInfo()->GossipMenuId;
|
||||
else if (pSource->GetTypeId() == TYPEID_GAMEOBJECT)
|
||||
return((GameObject*)pSource)->GetGOInfo()->GetGossipMenuId();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************/
|
||||
/*** QUEST SYSTEM ***/
|
||||
/*********************************************************/
|
||||
@@ -12837,7 +13223,7 @@ void Player::SendPreparedQuest(uint64 guid)
|
||||
Creature *pCreature = ObjectAccessor::GetCreatureOrPetOrVehicle(*this,guid);
|
||||
if (pCreature)
|
||||
{
|
||||
uint32 textid = pCreature->GetNpcTextId();
|
||||
uint32 textid = GetGossipTextId(pCreature);
|
||||
GossipText const* gossiptext = objmgr.GetGossipText(textid);
|
||||
if (!gossiptext)
|
||||
{
|
||||
|
||||
@@ -1246,6 +1246,18 @@ class MANGOS_DLL_SPEC Player : public Unit
|
||||
|
||||
uint32 m_stableSlots;
|
||||
|
||||
/*********************************************************/
|
||||
/*** GOSSIP SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
void PrepareGossipMenu(WorldObject *pSource, uint32 menuId = 0);
|
||||
void SendPreparedGossip(WorldObject *pSource);
|
||||
void OnGossipSelect(WorldObject *pSource, uint32 gossipListId, uint32 menuId);
|
||||
|
||||
uint32 GetGossipTextId(uint32 menuId);
|
||||
uint32 GetGossipTextId(WorldObject *pSource);
|
||||
uint32 GetDefaultGossipMenuForSource(WorldObject *pSource);
|
||||
|
||||
/*********************************************************/
|
||||
/*** QUEST SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
||||
@@ -104,8 +104,8 @@ void WorldSession::HandleQuestgiverHelloOpcode( WorldPacket & recv_data )
|
||||
if(Script->GossipHello( _player, pCreature ) )
|
||||
return;
|
||||
|
||||
pCreature->prepareGossipMenu(_player);
|
||||
pCreature->sendPreparedGossip(_player);
|
||||
_player->PrepareGossipMenu(pCreature, pCreature->GetCreatureInfo()->GossipMenuId);
|
||||
_player->SendPreparedGossip(pCreature);
|
||||
}
|
||||
|
||||
void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data )
|
||||
|
||||
+8
-2
@@ -1547,8 +1547,14 @@ void World::SetInitialWorldSettings()
|
||||
sLog.outString("Loading Npc Text Id...");
|
||||
objmgr.LoadNpcTextId(); // must be after load Creature and NpcText
|
||||
|
||||
sLog.outString("Loading Npc Options...");
|
||||
objmgr.LoadNpcOptions();
|
||||
sLog.outString( "Loading Gossip scripts...");
|
||||
objmgr.LoadGossipScripts(); // must be before gossip menu options
|
||||
|
||||
sLog.outString("Loading Gossip menu...");
|
||||
objmgr.LoadGossipMenu();
|
||||
|
||||
sLog.outString("Loading Gossip menu options...");
|
||||
objmgr.LoadGossipMenuItems();
|
||||
|
||||
sLog.outString("Loading Vendors...");
|
||||
objmgr.LoadVendors(); // must be after load CreatureTemplate and ItemTemplate
|
||||
|
||||
Reference in New Issue
Block a user