diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 679951a9f..8cd094a85 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -744,309 +744,6 @@ bool Creature::isCanTrainingAndResetTalentsOf(Player* pPlayer) const && pPlayer->getClass() == GetCreatureInfo()->trainer_class; } -void Creature::prepareGossipMenu( Player *pPlayer,uint32 gossipid ) -{ - 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=sObjectMgr.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_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 - 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 = sObjectMgr.GetNpcOptionLocale(gso->Id); - if (no) - { - if (no->OptionText.size() > (size_t)loc_idx && !no->OptionText[loc_idx].empty()) - OptionText=no->OptionText[loc_idx]; - if (no->BoxText.size() > (size_t)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; - - // 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_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_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()); - if (bgTypeId == BATTLEGROUND_TYPE_NONE) - { - sLog.outError("a user (guid %u) requested battlegroundlist from a npc who is no battlemaster", player->GetGUIDLow()); - return; - } - 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() -{ - if (!m_DBTableGuid) - return DEFAULT_GOSSIP_MESSAGE; - - if(uint32 pos = sObjectMgr.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::LoadGossipOptions() { if(m_gossipOptionLoaded) diff --git a/src/game/Creature.h b/src/game/Creature.h index 6ec94ec29..781acb9ad 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -576,16 +576,9 @@ class MANGOS_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(); - GossipOption const* GetGossipOption( uint32 id ) const; void addGossipOption(GossipOption const& gso) { m_goptions.push_back(gso); } + GossipOptionList &GetGossipOptionList() { return m_goptions; } void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); } void Yell(int32 textId, uint32 language, uint64 TargetGuid) { MonsterYell(textId,language,TargetGuid); } diff --git a/src/game/NPCHandler.cpp b/src/game/NPCHandler.cpp index 8dd54a60a..e3101cc1b 100644 --- a/src/game/NPCHandler.cpp +++ b/src/game/NPCHandler.cpp @@ -277,8 +277,8 @@ void WorldSession::HandleGossipHelloOpcode(WorldPacket & recv_data) if (!Script->GossipHello(_player, pCreature)) { _player->TalkedToCreature(pCreature->GetEntry(), pCreature->GetGUID()); - pCreature->prepareGossipMenu(_player); - pCreature->sendPreparedGossip(_player); + _player->PrepareGossipMenu(pCreature); + _player->SendPreparedGossip(pCreature); } } @@ -287,39 +287,40 @@ void WorldSession::HandleGossipSelectOptionOpcode( WorldPacket & recv_data ) sLog.outDebug("WORLD: CMSG_GOSSIP_SELECT_OPTION"); uint32 option; - uint32 unk; + uint32 menuId; uint64 guid; std::string code = ""; - recv_data >> guid >> unk >> option; + recv_data >> guid >> menuId >> option; - if(_player->PlayerTalkClass->GossipOptionCoded( option )) + if (_player->PlayerTalkClass->GossipOptionCoded(option)) { sLog.outBasic("reading string"); recv_data >> code; sLog.outBasic("string read: %s", code.c_str()); } - Creature *unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); - if (!unit) + Creature *pCreature = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_NONE); + + if (!pCreature) { sLog.outDebug( "WORLD: HandleGossipSelectOptionOpcode - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(guid)) ); return; } // remove fake death - if(GetPlayer()->hasUnitState(UNIT_STAT_DIED)) + if (GetPlayer()->hasUnitState(UNIT_STAT_DIED)) GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH); - if(!code.empty()) + if (!code.empty()) { - if (!Script->GossipSelectWithCode(_player, unit, _player->PlayerTalkClass->GossipOptionSender (option), _player->PlayerTalkClass->GossipOptionAction( option ), code.c_str())) - unit->OnGossipSelect (_player, option); + if (!Script->GossipSelectWithCode(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(option), _player->PlayerTalkClass->GossipOptionAction(option), code.c_str())) + _player->OnGossipSelect(pCreature, option); } else { - if (!Script->GossipSelect (_player, unit, _player->PlayerTalkClass->GossipOptionSender (option), _player->PlayerTalkClass->GossipOptionAction (option))) - unit->OnGossipSelect (_player, option); + if (!Script->GossipSelect(_player, pCreature, _player->PlayerTalkClass->GossipOptionSender(option), _player->PlayerTalkClass->GossipOptionAction(option))) + _player->OnGossipSelect(pCreature, option); } } diff --git a/src/game/Player.cpp b/src/game/Player.cpp index f07b4e8a7..77c2e8f86 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -12175,6 +12175,338 @@ void Player::SendNewItem(Item *item, uint32 count, bool received, bool created, GetSession()->SendPacket(&data); } +/*********************************************************/ +/*** GOSSIP SYSTEM ***/ +/*********************************************************/ + +void Player::PrepareGossipMenu(WorldObject *pSource, uint32 gossipid) +{ + PlayerMenu* pMenu = PlayerTalkClass; + pMenu->ClearMenus(); + + if (pSource->GetTypeId() != TYPEID_UNIT) + return; + + Creature *pCreature = (Creature*)pSource; + + // lazy loading single time at use + pCreature->LoadGossipOptions(); + + GossipOptionList &iOptList = pCreature->GetGossipOptionList(); + + for(GossipOptionList::iterator i = iOptList.begin( ); i != iOptList.end( ); ++i) + { + GossipOption* gso = &*i; + + if (gso->GossipId == gossipid) + { + bool cantalking = true; + + if (gso->Id == 1) + { + uint32 textid = GetGossipTextId(pSource); + + GossipText const* gossiptext = sObjectMgr.GetGossipText(textid); + + if (!gossiptext) + cantalking = false; + } + else + { + switch(gso->Action) + { + case GOSSIP_OPTION_QUESTGIVER: + PrepareQuestMenu(pSource->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 (!isDead()) + cantalking = 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()); + cantalking = false; + } + break; + } + case GOSSIP_OPTION_TRAINER: + if (!pCreature->isCanTrainingOf(this, false)) + cantalking = false; + break; + case GOSSIP_OPTION_UNLEARNTALENTS: + if (!pCreature->isCanTrainingAndResetTalentsOf(this)) + cantalking = 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) + cantalking = false; + break; + case GOSSIP_OPTION_TAXIVENDOR: + if (GetSession()->SendLearnNewTaxiNode(pCreature)) + return; + break; + case GOSSIP_OPTION_BATTLEFIELD: + if (!pCreature->isCanInteractWithBattleMaster(this, 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 + default: + sLog.outErrorDb("Creature %u (entry: %u) have unknown gossip option %u", pCreature->GetDBTableGUIDLow(), pCreature->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 = GetSession()->GetSessionDbLocaleIndex(); + + if (loc_idx >= 0) + { + if (NpcOptionLocale const *no = sObjectMgr.GetNpcOptionLocale(gso->Id)) + { + if (no->OptionText.size() > (size_t)loc_idx && !no->OptionText[loc_idx].empty()) + OptionText = no->OptionText[loc_idx]; + + if (no->BoxText.size() > (size_t)loc_idx && !no->BoxText[loc_idx].empty()) + BoxText = no->BoxText[loc_idx]; + } + } + + pMenu->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 (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 || pSource->GetTypeId() != TYPEID_UNIT) + return; + + // 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; + } + + // in case non empty gossip menu (that not included quests list size) show it + // (quest entries from quest menu will be included in list) + PlayerTalkClass->SendGossipMenu(GetGossipTextId(pSource), pSource->GetGUID()); +} + +void Player::OnGossipSelect(WorldObject* pSource, uint32 option) +{ + GossipMenu& gossipmenu = PlayerTalkClass->GetGossipMenu(); + + if (option >= gossipmenu.MenuItemCount()) + return; + + uint32 action = gossipmenu.GetItem(option).m_gAction; + uint32 zoneid = GetZoneId(); + uint64 guid = pSource->GetGUID(); + + GossipOption const *gossip = GetGossipOption(pSource, action); + + if (!gossip) + { + zoneid = 0; + gossip = GetGossipOption(pSource, action); + + if (!gossip) + return; + } + + switch(gossip->Action) + { + case GOSSIP_OPTION_GOSSIP: + { + uint32 textid = GetGossipTextId(action, zoneid); + + if (textid == 0) + textid = GetGossipTextId(pSource); + + PlayerTalkClass->CloseGossip(); + PlayerTalkClass->SendTalking(textid); + 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_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: + case GOSSIP_GUARD_SPELLTRAINER: + case GOSSIP_GUARD_SKILLTRAINER: + PrepareGossipMenu(pSource, gossip->Id); + 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; + } + default: + OnPoiSelect(pSource, gossip); + break; + } +} + +void Player::OnPoiSelect(WorldObject *pSource, 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()); + PlayerTalkClass->SendTalking(textid); + // std::string areaname= gossip->OptionText; + // how this could worked player->PlayerTalkClass->SendPointOfInterest( x, y, icon, 2, 15, areaname.c_str() ); + } +} + +uint32 Player::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 Player::GetGossipTextId(WorldObject *pSource) +{ + if (!pSource || pSource->GetTypeId() != TYPEID_UNIT || !((Creature*)pSource)->GetDBTableGUIDLow()) + return DEFAULT_GOSSIP_MESSAGE; + + if (uint32 pos = sObjectMgr.GetNpcGossip(((Creature*)pSource)->GetDBTableGUIDLow())) + return pos; + + return DEFAULT_GOSSIP_MESSAGE; +} + +GossipOption const* Player::GetGossipOption(WorldObject *pSource, uint32 id) const +{ + if (pSource->GetTypeId() == TYPEID_UNIT) + { + GossipOptionList &iOptlist = ((Creature*)pSource)->GetGossipOptionList(); + + for(GossipOptionList::const_iterator i = iOptlist.begin( ); i != iOptlist.end( ); ++i) + { + if (i->Action == id) + return &*i; + } + } + return NULL; +} + /*********************************************************/ /*** QUEST SYSTEM ***/ /*********************************************************/ @@ -12282,7 +12614,8 @@ void Player::SendPreparedQuest(uint64 guid) // need pet case for some quests if (Creature *pCreature = GetMap()->GetCreatureOrPetOrVehicle(guid)) { - uint32 textid = pCreature->GetNpcTextId(); + uint32 textid = GetGossipTextId(pCreature); + GossipText const* gossiptext = sObjectMgr.GetGossipText(textid); if (!gossiptext) { diff --git a/src/game/Player.h b/src/game/Player.h index dd5864e4c..446b834c5 100644 --- a/src/game/Player.h +++ b/src/game/Player.h @@ -1295,6 +1295,19 @@ class MANGOS_DLL_SPEC Player : public Unit uint32 m_stableSlots; + /*********************************************************/ + /*** GOSSIP SYSTEM ***/ + /*********************************************************/ + + void PrepareGossipMenu(WorldObject *pSource, uint32 gossipid = 0); + void SendPreparedGossip(WorldObject *pSource); + void OnGossipSelect(WorldObject *pSource, uint32 option); + void OnPoiSelect(WorldObject *pSource, GossipOption const *gossip); + + uint32 GetGossipTextId(uint32 action, uint32 zoneid); + uint32 GetGossipTextId(WorldObject *pSource); + GossipOption const* GetGossipOption(WorldObject *pSource, uint32 id) const; + /*********************************************************/ /*** QUEST SYSTEM ***/ /*********************************************************/ diff --git a/src/game/QuestHandler.cpp b/src/game/QuestHandler.cpp index 72a4c3e50..87ef0b093 100644 --- a/src/game/QuestHandler.cpp +++ b/src/game/QuestHandler.cpp @@ -102,8 +102,8 @@ void WorldSession::HandleQuestgiverHelloOpcode(WorldPacket & recv_data) if (Script->GossipHello(_player, pCreature)) return; - pCreature->prepareGossipMenu(_player); - pCreature->sendPreparedGossip(_player); + _player->PrepareGossipMenu(pCreature); + _player->SendPreparedGossip(pCreature); } void WorldSession::HandleQuestgiverAcceptQuestOpcode( WorldPacket & recv_data ) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 4f14a1369..40fce86b5 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "8899" + #define REVISION_NR "8900" #endif // __REVISION_NR_H__