diff options
-rw-r--r-- | src/server/game/Battlegrounds/BattlegroundMgr.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.cpp | 51 | ||||
-rw-r--r-- | src/server/game/Entities/Creature/GossipDef.h | 30 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 77 | ||||
-rw-r--r-- | src/server/game/Handlers/AuctionHouseHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/BankHandler.cpp | 4 | ||||
-rw-r--r-- | src/server/game/Handlers/GuildHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/ItemHandler.cpp | 2 | ||||
-rw-r--r-- | src/server/game/Handlers/MailHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Handlers/NPCHandler.cpp | 11 | ||||
-rw-r--r-- | src/server/game/Handlers/PetitionsHandler.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 130 | ||||
-rw-r--r-- | src/server/game/Handlers/TaxiHandler.cpp | 3 |
13 files changed, 193 insertions, 132 deletions
diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index ca21d466b37..1f5392f2dae 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -23,6 +23,7 @@ #include "DatabaseEnv.h" #include "DisableMgr.h" #include "GameEventMgr.h" +#include "GossipDef.h" #include "Language.h" #include "Log.h" #include "MapManager.h" @@ -452,6 +453,8 @@ void BattlegroundMgr::SendBattlegroundList(Player* player, ObjectGuid const& gui if (!bgTemplate) return; + player->PlayerTalkClass->GetInteractionData().StartInteraction(guid, PlayerInteractionType::BattleMaster); + WorldPackets::Battleground::BattlefieldList battlefieldList; battlefieldList.BattlemasterGuid = guid; battlefieldList.BattlemasterListID = bgTypeId; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 75fc7f8ce87..c1a359b0fff 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -219,8 +219,7 @@ void PlayerMenu::ClearMenus() void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) { - _interactionData.Reset(); - _interactionData.SourceGuid = objectGUID; + _interactionData.StartInteraction(objectGUID, PlayerInteractionType::Gossip); WorldPackets::NPC::GossipMessage packet; packet.GossipGUID = objectGUID; @@ -364,6 +363,39 @@ void PlayerChoiceData::AddResponse(uint32 id, uint16 clientIdentifier) _responses.push_back({ .Id = id, .ClientIdentifier = clientIdentifier }); } +InteractionData::InteractionData() = default; +InteractionData::InteractionData(InteractionData const& other) = default; +InteractionData::InteractionData(InteractionData&& other) noexcept = default; +InteractionData& InteractionData::operator=(InteractionData const& other) = default; +InteractionData& InteractionData::operator=(InteractionData&& other) noexcept = default; +InteractionData::~InteractionData() = default; + +void InteractionData::StartInteraction(ObjectGuid target, PlayerInteractionType type) +{ + SourceGuid = target; + Type = type; + IsLaunchedByQuest = false; + switch (type) + { + case PlayerInteractionType::Trainer: + _data.emplace<TrainerData>(); + break; + case PlayerInteractionType::PlayerChoice: + _data.emplace<PlayerChoiceData>(); + break; + default: + break; + } +} + +void InteractionData::Reset() +{ + SourceGuid.Clear(); + Type = PlayerInteractionType::None; + IsLaunchedByQuest = false; + _data.emplace<std::monostate>(); +} + void QuestMenu::ClearMenu() { _questMenuItems.clear(); @@ -372,6 +404,9 @@ void QuestMenu::ClearMenu() void PlayerMenu::SendQuestGiverQuestListMessage(Object* questgiver) { ObjectGuid guid = questgiver->GetGUID(); + + GetInteractionData().StartInteraction(guid, PlayerInteractionType::QuestGiver); + LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); WorldPackets::Quest::QuestGiverQuestListMessage questList; @@ -432,8 +467,10 @@ void PlayerMenu::SendQuestGiverStatus(QuestGiverStatus questStatus, ObjectGuid n TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_STATUS NPC={}, status={}", npcGUID.ToString(), AsUnderlyingType(questStatus)); } -void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup) const +void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup) { + GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType::QuestGiver); + WorldPackets::Quest::QuestGiverQuestDetails packet; packet.QuestTitle = quest->GetLogTitle(); @@ -532,8 +569,10 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_QUERY_RESPONSE questid={}", quest->GetQuestId()); } -void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched) const +void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched) { + GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType::QuestGiver); + WorldPackets::Quest::QuestGiverOfferRewardMessage packet; packet.QuestTitle = quest->GetLogTitle(); @@ -602,7 +641,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_OFFER_REWARD NPC={}, questid={}", npcGUID.ToString(), quest->GetQuestId()); } -void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGUID, bool canComplete, bool autoLaunched) const +void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGUID, bool canComplete, bool autoLaunched) { // We can always call to RequestItems, but this packet only goes out if there are actually // items. Otherwise, we'll skip straight to the OfferReward @@ -613,6 +652,8 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU return; } + GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType::QuestGiver); + WorldPackets::Quest::QuestGiverRequestItems packet; packet.QuestTitle = quest->GetLogTitle(); diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index da83b064300..4a9c06f8e81 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -28,6 +28,7 @@ class Object; class Quest; class WorldSession; struct GossipMenuItems; +enum class PlayerInteractionType : int32; enum class QuestGiverStatus : uint64; #define GOSSIP_MAX_MENU_ITEMS 32 @@ -260,7 +261,7 @@ private: Optional<SystemTimePoint> _expireTime; }; -class InteractionData +class TC_GAME_API InteractionData { template <typename> struct TaggedId @@ -275,20 +276,23 @@ class InteractionData using TrainerData = TaggedId<TrainerTag>; public: - void Reset() - { - SourceGuid.Clear(); - IsLaunchedByQuest = false; - _data.emplace<std::monostate>(); - } + InteractionData(); + InteractionData(InteractionData const& other); + InteractionData(InteractionData&& other) noexcept; + InteractionData& operator=(InteractionData const& other); + InteractionData& operator=(InteractionData&& other) noexcept; + ~InteractionData(); + + void StartInteraction(ObjectGuid target, PlayerInteractionType type); + bool IsInteractingWith(ObjectGuid target, PlayerInteractionType type) const { return SourceGuid == target && Type == type; } + void Reset(); ObjectGuid SourceGuid; + PlayerInteractionType Type = { }; - Optional<uint32> GetTrainerId() const { return std::holds_alternative<TrainerData>(_data) ? std::get<TrainerData>(_data).Id : Optional<uint32>(); } - void SetTrainerId(uint32 trainerId) { _data.emplace<TrainerData>(trainerId); } + TrainerData* GetTrainer() { return std::holds_alternative<TrainerData>(_data) ? &std::get<TrainerData>(_data) : nullptr; } PlayerChoiceData* GetPlayerChoice() { return std::holds_alternative<PlayerChoiceData>(_data) ? &std::get<PlayerChoiceData>(_data) : nullptr; } - void SetPlayerChoice(uint32 choiceId) { _data.emplace<PlayerChoiceData>(choiceId); } uint16 AddPlayerChoiceResponse(uint32 responseId) { @@ -336,10 +340,10 @@ class TC_GAME_API PlayerMenu void SendQuestGiverQuestListMessage(Object* questgiver); void SendQuestQueryResponse(Quest const* quest) const; - void SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup) const; + void SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup); - void SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched) const; - void SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGUID, bool canComplete, bool autoLaunched) const; + void SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUID, bool autoLaunched); + void SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGUID, bool canComplete, bool autoLaunched); private: GossipMenu _gossipMenu; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index f33d76ee8d4..be44c7a9898 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -9237,6 +9237,18 @@ void Player::SetBindPoint(ObjectGuid guid) const void Player::SendRespecWipeConfirm(ObjectGuid const& guid, uint32 cost, SpecResetType respecType) const { + switch (respecType) + { + case SPEC_RESET_TALENTS: + PlayerTalkClass->GetInteractionData().StartInteraction(guid, PlayerInteractionType::TalentMaster); + break; + case SPEC_RESET_SPECIALIZATION: + PlayerTalkClass->GetInteractionData().StartInteraction(guid, PlayerInteractionType::SpecializationMaster); + break; + default: + break; + } + WorldPackets::Talent::RespecWipeConfirm respecWipeConfirm; respecWipeConfirm.RespecMaster = guid; respecWipeConfirm.Cost = cost; @@ -14148,7 +14160,10 @@ void Player::OnGossipSelect(WorldObject* source, int32 gossipOptionId, uint32 me break; case GossipOptionNpc::GuildBanker: if (Guild* const guild = GetGuild()) + { + PlayerTalkClass->GetInteractionData().StartInteraction(source->GetGUID(), PlayerInteractionType::GuildBanker); guild->SendBankList(GetSession(), 0, true); + } else Guild::SendCommandResult(GetSession(), GUILD_COMMAND_VIEW_TAB, ERR_GUILD_PLAYER_NOT_IN_GUILD); break; @@ -14197,6 +14212,36 @@ void Player::OnGossipSelect(WorldObject* source, int32 gossipOptionId, uint32 me if (!handled) { + static constexpr std::array<PlayerInteractionType, AsUnderlyingType(GossipOptionNpc::Count)> GossipOptionNpcToInteractionType = + { + PlayerInteractionType::None, PlayerInteractionType::Vendor, PlayerInteractionType::TaxiNode, + PlayerInteractionType::Trainer, PlayerInteractionType::SpiritHealer, PlayerInteractionType::Binder, + PlayerInteractionType::Banker, PlayerInteractionType::PetitionVendor, PlayerInteractionType::GuildTabardVendor, + PlayerInteractionType::BattleMaster, PlayerInteractionType::Auctioneer, PlayerInteractionType::TalentMaster, + PlayerInteractionType::StableMaster, PlayerInteractionType::None, PlayerInteractionType::GuildBanker, + PlayerInteractionType::None, PlayerInteractionType::None, PlayerInteractionType::None, + PlayerInteractionType::MailInfo, PlayerInteractionType::None, PlayerInteractionType::LFGDungeon, + PlayerInteractionType::ArtifactForge, PlayerInteractionType::None, PlayerInteractionType::SpecializationMaster, + PlayerInteractionType::None, PlayerInteractionType::None, PlayerInteractionType::GarrArchitect, + PlayerInteractionType::GarrMission, PlayerInteractionType::ShipmentCrafter, PlayerInteractionType::GarrTradeskill, + PlayerInteractionType::GarrRecruitment, PlayerInteractionType::AdventureMap, PlayerInteractionType::GarrTalent, + PlayerInteractionType::ContributionCollector, PlayerInteractionType::Transmogrifier, PlayerInteractionType::AzeriteRespec, + PlayerInteractionType::IslandQueue, PlayerInteractionType::ItemInteraction, PlayerInteractionType::WorldMap, + PlayerInteractionType::Soulbind, PlayerInteractionType::ChromieTime, PlayerInteractionType::CovenantPreview, + PlayerInteractionType::LegendaryCrafting, PlayerInteractionType::NewPlayerGuide, PlayerInteractionType::LegendaryCrafting, + PlayerInteractionType::Renown, PlayerInteractionType::BlackMarketAuctioneer, PlayerInteractionType::PerksProgramVendor, + PlayerInteractionType::ProfessionsCraftingOrder, PlayerInteractionType::Professions, PlayerInteractionType::ProfessionsCustomerOrder, + PlayerInteractionType::TraitSystem, PlayerInteractionType::BarbersChoice, PlayerInteractionType::MajorFactionRenown, + PlayerInteractionType::PersonalTabardVendor, PlayerInteractionType::ForgeMaster, PlayerInteractionType::CharacterBanker, + PlayerInteractionType::AccountBanker, PlayerInteractionType::ProfessionRespec, PlayerInteractionType::PlaceholderType72, + PlayerInteractionType::PlaceholderType75, PlayerInteractionType::PlaceholderType76, PlayerInteractionType::GuildRename, + PlayerInteractionType::PlaceholderType77, PlayerInteractionType::ItemUpgrade + }; + + PlayerInteractionType interactionType = GossipOptionNpcToInteractionType[AsUnderlyingType(gossipOptionNpc)]; + if (interactionType != PlayerInteractionType::None) + PlayerTalkClass->GetInteractionData().StartInteraction(source->GetGUID(), interactionType); + if (item->GossipNpcOptionID) { GossipMenuAddon const* addon = sObjectMgr->GetGossipMenuAddon(menuId); @@ -14211,33 +14256,6 @@ void Player::OnGossipSelect(WorldObject* source, int32 gossipOptionId, uint32 me } else { - static constexpr std::array<PlayerInteractionType, AsUnderlyingType(GossipOptionNpc::Count)> GossipOptionNpcToInteractionType = - { - PlayerInteractionType::None, PlayerInteractionType::Vendor, PlayerInteractionType::TaxiNode, - PlayerInteractionType::Trainer, PlayerInteractionType::SpiritHealer, PlayerInteractionType::Binder, - PlayerInteractionType::Banker, PlayerInteractionType::PetitionVendor, PlayerInteractionType::GuildTabardVendor, - PlayerInteractionType::BattleMaster, PlayerInteractionType::Auctioneer, PlayerInteractionType::TalentMaster, - PlayerInteractionType::StableMaster, PlayerInteractionType::None, PlayerInteractionType::GuildBanker, - PlayerInteractionType::None, PlayerInteractionType::None, PlayerInteractionType::None, - PlayerInteractionType::MailInfo, PlayerInteractionType::None, PlayerInteractionType::LFGDungeon, - PlayerInteractionType::ArtifactForge, PlayerInteractionType::None, PlayerInteractionType::SpecializationMaster, - PlayerInteractionType::None, PlayerInteractionType::None, PlayerInteractionType::GarrArchitect, - PlayerInteractionType::GarrMission, PlayerInteractionType::ShipmentCrafter, PlayerInteractionType::GarrTradeskill, - PlayerInteractionType::GarrRecruitment, PlayerInteractionType::AdventureMap, PlayerInteractionType::GarrTalent, - PlayerInteractionType::ContributionCollector, PlayerInteractionType::Transmogrifier, PlayerInteractionType::AzeriteRespec, - PlayerInteractionType::IslandQueue, PlayerInteractionType::ItemInteraction, PlayerInteractionType::WorldMap, - PlayerInteractionType::Soulbind, PlayerInteractionType::ChromieTime, PlayerInteractionType::CovenantPreview, - PlayerInteractionType::LegendaryCrafting, PlayerInteractionType::NewPlayerGuide, PlayerInteractionType::LegendaryCrafting, - PlayerInteractionType::Renown, PlayerInteractionType::BlackMarketAuctioneer, PlayerInteractionType::PerksProgramVendor, - PlayerInteractionType::ProfessionsCraftingOrder, PlayerInteractionType::Professions, PlayerInteractionType::ProfessionsCustomerOrder, - PlayerInteractionType::TraitSystem, PlayerInteractionType::BarbersChoice, PlayerInteractionType::MajorFactionRenown, - PlayerInteractionType::PersonalTabardVendor, PlayerInteractionType::ForgeMaster, PlayerInteractionType::CharacterBanker, - PlayerInteractionType::AccountBanker, PlayerInteractionType::ProfessionRespec, PlayerInteractionType::PlaceholderType72, - PlayerInteractionType::PlaceholderType75, PlayerInteractionType::PlaceholderType76, PlayerInteractionType::GuildRename, - PlayerInteractionType::PlaceholderType77, PlayerInteractionType::ItemUpgrade - }; - - PlayerInteractionType interactionType = GossipOptionNpcToInteractionType[AsUnderlyingType(gossipOptionNpc)]; if (interactionType != PlayerInteractionType::None) { WorldPackets::NPC::NPCInteractionOpenResult npcInteraction; @@ -29978,9 +29996,8 @@ void Player::SendPlayerChoice(ObjectGuid sender, int32 choiceId) LocaleConstant locale = GetSession()->GetSessionDbLocaleIndex(); PlayerChoiceLocale const* playerChoiceLocale = locale != DEFAULT_LOCALE ? sObjectMgr->GetPlayerChoiceLocale(choiceId) : nullptr; - PlayerTalkClass->GetInteractionData().Reset(); - PlayerTalkClass->GetInteractionData().SourceGuid = sender; - PlayerTalkClass->GetInteractionData().SetPlayerChoice(choiceId); + PlayerTalkClass->GetInteractionData().StartInteraction(sender, PlayerInteractionType::PlayerChoice); + PlayerTalkClass->GetInteractionData().GetPlayerChoice()->SetChoiceId(choiceId); WorldPackets::Quest::DisplayPlayerChoice displayPlayerChoice; displayPlayerChoice.SenderGUID = sender; diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 6d74c1621cd..41936528511 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -23,6 +23,7 @@ #include "Creature.h" #include "DatabaseEnv.h" #include "GameTime.h" +#include "GossipDef.h" #include "Item.h" #include "Language.h" #include "Log.h" @@ -1004,6 +1005,8 @@ void WorldSession::SendAuctionHello(ObjectGuid guid, Unit const* unit) if (!ahEntry) return; + GetPlayer()->PlayerTalkClass->GetInteractionData().StartInteraction(guid, PlayerInteractionType::Auctioneer); + WorldPackets::AuctionHouse::AuctionHelloResponse auctionHelloResponse; auctionHelloResponse.Auctioneer = guid; auctionHelloResponse.AuctionHouseID = ahEntry->ID; diff --git a/src/server/game/Handlers/BankHandler.cpp b/src/server/game/Handlers/BankHandler.cpp index bf8b3a92ff4..91a65dfb58b 100644 --- a/src/server/game/Handlers/BankHandler.cpp +++ b/src/server/game/Handlers/BankHandler.cpp @@ -324,8 +324,8 @@ void WorldSession::HandleAutoStoreBankReagentOpcode(WorldPackets::Bank::AutoStor void WorldSession::SendShowBank(ObjectGuid guid, PlayerInteractionType interactionType) { - _player->PlayerTalkClass->GetInteractionData().Reset(); - _player->PlayerTalkClass->GetInteractionData().SourceGuid = guid; + _player->PlayerTalkClass->GetInteractionData().StartInteraction(guid, interactionType); + WorldPackets::NPC::NPCInteractionOpenResult npcInteraction; npcInteraction.Npc = guid; npcInteraction.InteractionType = interactionType; diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index c778ca97ca8..2dbc1c5e02a 100644 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -19,6 +19,7 @@ #include "AchievementPackets.h" #include "Common.h" #include "GameTime.h" +#include "GossipDef.h" #include "Guild.h" #include "GuildMgr.h" #include "GuildPackets.h" @@ -249,6 +250,8 @@ void WorldSession::HandleGuildBankActivate(WorldPackets::Guild::GuildBankActivat return; } + GetPlayer()->PlayerTalkClass->GetInteractionData().StartInteraction(packet.Banker, PlayerInteractionType::GuildBanker); + guild->SendBankList(this, 0, packet.FullUpdate); } diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index c3bbf6c1fa7..e63ed58e7e4 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -606,6 +606,8 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); + GetPlayer()->PlayerTalkClass->GetInteractionData().StartInteraction(vendorGuid, PlayerInteractionType::Vendor); + // Stop the npc if moving if (uint32 pause = vendor->GetMovementTemplate().GetInteractionPauseTimer()) vendor->PauseMovement(pause); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index e6df9fa28d1..fbe5e3ea090 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -576,8 +576,7 @@ void WorldSession::HandleGetMailList(WorldPackets::Mail::MailGetList& getList) ++response.TotalNumRecords; } - player->PlayerTalkClass->GetInteractionData().Reset(); - player->PlayerTalkClass->GetInteractionData().SourceGuid = getList.Mailbox; + player->PlayerTalkClass->GetInteractionData().StartInteraction(getList.Mailbox, PlayerInteractionType::MailInfo); SendPacket(response.Write()); // recalculate m_nextMailDelivereTime and unReadMails diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 3505651926b..06fd9155c29 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -122,9 +122,8 @@ void WorldSession::SendTrainerList(Creature* npc, uint32 trainerId) return; } - _player->PlayerTalkClass->GetInteractionData().Reset(); - _player->PlayerTalkClass->GetInteractionData().SourceGuid = npc->GetGUID(); - _player->PlayerTalkClass->GetInteractionData().SetTrainerId(trainerId); + _player->PlayerTalkClass->GetInteractionData().StartInteraction(npc->GetGUID(), PlayerInteractionType::Trainer); + _player->PlayerTalkClass->GetInteractionData().GetTrainer()->Id = trainerId; trainer->SendSpells(npc, _player, GetSessionDbLocaleIndex()); } @@ -143,10 +142,10 @@ void WorldSession::HandleTrainerBuySpellOpcode(WorldPackets::NPC::TrainerBuySpel if (GetPlayer()->HasUnitState(UNIT_STATE_DIED)) GetPlayer()->RemoveAurasByType(SPELL_AURA_FEIGN_DEATH); - if (_player->PlayerTalkClass->GetInteractionData().SourceGuid != packet.TrainerGUID) + if (!_player->PlayerTalkClass->GetInteractionData().IsInteractingWith(packet.TrainerGUID, PlayerInteractionType::Trainer)) return; - if (_player->PlayerTalkClass->GetInteractionData().GetTrainerId() != uint32(packet.TrainerID)) + if (_player->PlayerTalkClass->GetInteractionData().GetTrainer()->Id != uint32(packet.TrainerID)) return; Trainer::Trainer const* trainer = sObjectMgr->GetTrainer(packet.TrainerID); @@ -198,7 +197,7 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPackets::NPC::GossipSelec return; // Prevent cheating on C++ scripted menus - if (_player->PlayerTalkClass->GetInteractionData().SourceGuid != packet.GossipUnit) + if (!_player->PlayerTalkClass->GetInteractionData().IsInteractingWith(packet.GossipUnit, PlayerInteractionType::Gossip)) return; Creature* unit = nullptr; diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 7cade43cddc..acbd1db23b1 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -19,6 +19,7 @@ #include "Common.h" #include "CharacterCache.h" #include "DatabaseEnv.h" +#include "GossipDef.h" #include "Guild.h" #include "GuildMgr.h" #include "Item.h" @@ -455,10 +456,10 @@ void WorldSession::SendPetitionShowList(ObjectGuid guid) return; } + GetPlayer()->PlayerTalkClass->GetInteractionData().StartInteraction(guid, PlayerInteractionType::PetitionVendor); + WorldPackets::Petition::ServerPetitionShowList packet; packet.Unit = guid; packet.Price = uint32(sWorld->getIntConfig(CONFIG_CHARTER_COST_GUILD)); SendPacket(packet.Write()); - - TC_LOG_DEBUG("network", "Sent SMSG_PETITION_SHOW_LIST"); } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 1fe2dbc32b9..d86bbf17cb1 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -28,6 +28,7 @@ #include "GossipDef.h" #include "Group.h" #include "Log.h" +#include "Memory.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" @@ -94,118 +95,103 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPackets::Quest::QuestG else object = ObjectAccessor::FindPlayer(packet.QuestGiverGUID); - auto CLOSE_GOSSIP_CLEAR_SHARING_INFO = ([this]() + auto CLOSE_GOSSIP_CLEAR_SHARING_INFO = Trinity::make_unique_ptr_with_deleter(_player, [](Player* player) { - _player->PlayerTalkClass->SendCloseGossip(); - _player->ClearQuestSharingInfo(); + player->PlayerTalkClass->SendCloseGossip(); + player->ClearQuestSharingInfo(); }); // no or incorrect quest giver if (!object) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } if (Player* playerQuestObject = object->ToPlayer()) { if ((_player->GetPlayerSharingQuest().IsEmpty() && _player->GetPlayerSharingQuest() != packet.QuestGiverGUID) || !playerQuestObject->CanShareQuest(packet.QuestID)) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } + if (!_player->IsInSameRaidWith(playerQuestObject)) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } } else { if (!object->hasQuest(packet.QuestID)) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } } // some kind of WPE protection if (!_player->CanInteractWithQuestGiver(object)) - { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); return; - } - if (Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID)) + Quest const* quest = sObjectMgr->GetQuestTemplate(packet.QuestID); + if (!quest) + return; + + // prevent cheating + if (!GetPlayer()->CanTakeQuest(quest, true)) + return; + + if (!_player->GetPlayerSharingQuest().IsEmpty()) { - // prevent cheating - if (!GetPlayer()->CanTakeQuest(quest, true)) + Player* player = ObjectAccessor::FindPlayer(_player->GetPlayerSharingQuest()); + if (player) { - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); - return; + player->SendPushToPartyResponse(_player, QuestPushReason::Accepted); + _player->ClearQuestSharingInfo(); } + } - if (!_player->GetPlayerSharingQuest().IsEmpty()) - { - Player* player = ObjectAccessor::FindPlayer(_player->GetPlayerSharingQuest()); - if (player) - { - player->SendPushToPartyResponse(_player, QuestPushReason::Accepted); - _player->ClearQuestSharingInfo(); - } - } + if (!_player->CanAddQuest(quest, true)) + return; - if (_player->CanAddQuest(quest, true)) - { - _player->AddQuestAndCheckCompletion(quest, object); + (void)CLOSE_GOSSIP_CLEAR_SHARING_INFO.release(); + + _player->AddQuestAndCheckCompletion(quest, object); - if (quest->IsPushedToPartyOnAccept()) + if (quest->IsPushedToPartyOnAccept()) + { + if (Group* group = _player->GetGroup()) + { + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { - if (Group* group = _player->GetGroup()) - { - for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) - { - Player* player = itr->GetSource(); + Player* player = itr->GetSource(); - if (!player || player == _player || !player->IsInMap(_player)) // not self and in same map - continue; + if (!player || player == _player || !player->IsInMap(_player)) // not self and in same map + continue; - if (player->CanTakeQuest(quest, true)) - { - player->SetQuestSharingInfo(_player->GetGUID(), quest->GetQuestId()); + if (player->CanTakeQuest(quest, true)) + { + player->SetQuestSharingInfo(_player->GetGUID(), quest->GetQuestId()); - // need confirmation that any gossip window will close - player->PlayerTalkClass->SendCloseGossip(); + // need confirmation that any gossip window will close + player->PlayerTalkClass->SendCloseGossip(); - _player->SendQuestConfirmAccept(quest, player); - } - } + _player->SendQuestConfirmAccept(quest, player); } } - - if (quest->HasFlag(QUEST_FLAGS_LAUNCH_GOSSIP_ACCEPT) && !quest->HasFlagEx(QUEST_FLAGS_EX_SUPPRESS_GOSSIP_ACCEPT)) - { - auto launchGossip = [&](WorldObject* worldObject) - { - _player->PlayerTalkClass->ClearMenus(); - _player->PrepareGossipMenu(worldObject, _player->GetGossipMenuForSource(worldObject), true); - _player->SendPreparedGossip(worldObject); - _player->PlayerTalkClass->GetInteractionData().IsLaunchedByQuest = true; - }; - - if (Creature* creature = object->ToCreature()) - launchGossip(creature); - else if (GameObject* go = object->ToGameObject()) - launchGossip(go); - } - else - _player->PlayerTalkClass->SendCloseGossip(); - - return; } } - CLOSE_GOSSIP_CLEAR_SHARING_INFO(); + if (quest->HasFlag(QUEST_FLAGS_LAUNCH_GOSSIP_ACCEPT) && !quest->HasFlagEx(QUEST_FLAGS_EX_SUPPRESS_GOSSIP_ACCEPT)) + { + auto launchGossip = [&](WorldObject* worldObject) + { + _player->PlayerTalkClass->ClearMenus(); + _player->PrepareGossipMenu(worldObject, _player->GetGossipMenuForSource(worldObject), true); + _player->SendPreparedGossip(worldObject); + _player->PlayerTalkClass->GetInteractionData().IsLaunchedByQuest = true; + }; + + if (Creature* creature = object->ToCreature()) + launchGossip(creature); + else if (GameObject* go = object->ToGameObject()) + launchGossip(go); + } + // do not close gossip if quest accept script started a new interaction + else if (!_player->PlayerTalkClass->GetInteractionData().IsInteractingWith(object->GetGUID(), PlayerInteractionType::QuestGiver)) + _player->PlayerTalkClass->GetInteractionData().IsLaunchedByQuest = true; + else + _player->PlayerTalkClass->SendCloseGossip(); } void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPackets::Quest::QuestGiverQueryQuest& packet) diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index c807e2cb4ed..5c8082bb9c5 100644 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -23,6 +23,7 @@ #include "DatabaseEnv.h" #include "DB2Stores.h" #include "FlightPathMovementGenerator.h" +#include "GossipDef.h" #include "Log.h" #include "MotionMaster.h" #include "ObjectAccessor.h" @@ -96,6 +97,8 @@ void WorldSession::SendTaxiMenu(Creature* unit) if (!curloc) return; + GetPlayer()->PlayerTalkClass->GetInteractionData().StartInteraction(unit->GetGUID(), PlayerInteractionType::TaxiNode); + bool lastTaxiCheaterState = GetPlayer()->isTaxiCheater(); if (unit->GetEntry() == 29480) GetPlayer()->SetTaxiCheater(true); // Grimwing in Ebon Hold, special case. NOTE: Not perfect, Zul'Aman should not be included according to WoWhead, and I think taxicheat includes it. |