Core/Gossip: Track started interaction types and reset only questgiver on quest accept

Port From (https://github.com/TrinityCore/TrinityCore/commit/c02e311eef9e635738b9e48559d5455ef016d8b4)
This commit is contained in:
Hondacrx
2025-08-19 21:29:25 -04:00
parent bd71d172da
commit 068c3c7ce5
13 changed files with 176 additions and 141 deletions
@@ -398,6 +398,8 @@ namespace Game.BattleGrounds
if (bgTemplate == null) if (bgTemplate == null)
return; return;
player.PlayerTalkClass.GetInteractionData().StartInteraction(guid, PlayerInteractionType.BattleMaster);
BattlefieldList battlefieldList = new(); BattlefieldList battlefieldList = new();
battlefieldList.BattlemasterGuid = guid; battlefieldList.BattlemasterGuid = guid;
battlefieldList.BattlemasterListID = (int)bgTypeId; battlefieldList.BattlemasterListID = (int)bgTypeId;
-1
View File
@@ -275,7 +275,6 @@ namespace Game.DataStorage
_curvePoints.AddRange(curveId, curvePoints.Select(p => p.Pos)); _curvePoints.AddRange(curveId, curvePoints.Select(p => p.Pos));
} }
foreach (EmotesTextSoundRecord emoteTextSound in EmotesTextSoundStorage.Values) foreach (EmotesTextSoundRecord emoteTextSound in EmotesTextSoundStorage.Values)
_emoteTextSounds[Tuple.Create(emoteTextSound.EmotesTextId, emoteTextSound.RaceId, emoteTextSound.SexId, emoteTextSound.ClassId)] = emoteTextSound; _emoteTextSounds[Tuple.Create(emoteTextSound.EmotesTextId, emoteTextSound.RaceId, emoteTextSound.SexId, emoteTextSound.ClassId)] = emoteTextSound;
+41 -12
View File
@@ -207,24 +207,45 @@ namespace Game.Misc
public class InteractionData public class InteractionData
{ {
public ObjectGuid SourceGuid; public ObjectGuid SourceGuid;
public PlayerInteractionType InteractionType;
public bool IsLaunchedByQuest; public bool IsLaunchedByQuest;
ushort _playerChoiceResponseIdentifierGenerator = 0; // not reset between interactions ushort _playerChoiceResponseIdentifierGenerator = 0; // not reset between interactions
uint trainerId; TrainerData trainerData;
PlayerChoiceData playerChoiceData; PlayerChoiceData playerChoiceData;
public void StartInteraction(ObjectGuid target, PlayerInteractionType type)
{
SourceGuid = target;
InteractionType = type;
IsLaunchedByQuest = false;
switch (type)
{
case PlayerInteractionType.Trainer:
trainerData = new();
break;
case PlayerInteractionType.PlayerChoice:
playerChoiceData = new();
break;
default:
break;
}
}
public bool IsInteractingWith(ObjectGuid target, PlayerInteractionType type) { return SourceGuid == target && InteractionType == type; }
public void Reset() public void Reset()
{ {
SourceGuid.Clear(); SourceGuid.Clear();
InteractionType = PlayerInteractionType.None;
IsLaunchedByQuest = false; IsLaunchedByQuest = false;
trainerId = 0; trainerData = null;
playerChoiceData = null;
} }
public uint? GetTrainerId() { return trainerId; } public TrainerData GetTrainer() { return trainerData; }
public void SetTrainerId(uint _trainerId) { trainerId = _trainerId; }
public PlayerChoiceData GetPlayerChoice() { return playerChoiceData; } public PlayerChoiceData GetPlayerChoice() { return playerChoiceData; }
public void SetPlayerChoice(uint choiceId) { playerChoiceData = new PlayerChoiceData(choiceId); }
public ushort AddPlayerChoiceResponse(uint responseId) public ushort AddPlayerChoiceResponse(uint responseId)
{ {
@@ -250,8 +271,7 @@ namespace Game.Misc
public void SendGossipMenu(uint titleTextId, ObjectGuid objectGUID) public void SendGossipMenu(uint titleTextId, ObjectGuid objectGUID)
{ {
_interactionData.Reset(); _interactionData.StartInteraction(objectGUID, PlayerInteractionType.Gossip);
_interactionData.SourceGuid = objectGUID;
GossipMessagePkt packet = new(); GossipMessagePkt packet = new();
packet.GossipGUID = objectGUID; packet.GossipGUID = objectGUID;
@@ -362,6 +382,9 @@ namespace Game.Misc
public void SendQuestGiverQuestListMessage(WorldObject questgiver) public void SendQuestGiverQuestListMessage(WorldObject questgiver)
{ {
ObjectGuid guid = questgiver.GetGUID(); ObjectGuid guid = questgiver.GetGUID();
GetInteractionData().StartInteraction(guid, PlayerInteractionType.QuestGiver);
Locale localeConstant = _session.GetSessionDbLocaleIndex(); Locale localeConstant = _session.GetSessionDbLocaleIndex();
QuestGiverQuestListMessage questList = new(); QuestGiverQuestListMessage questList = new();
@@ -429,6 +452,8 @@ namespace Game.Misc
public void SendQuestGiverQuestDetails(Quest quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup) public void SendQuestGiverQuestDetails(Quest quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup)
{ {
GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType.QuestGiver);
QuestGiverQuestDetails packet = new(); QuestGiverQuestDetails packet = new();
packet.QuestTitle = quest.LogTitle; packet.QuestTitle = quest.LogTitle;
@@ -532,6 +557,8 @@ namespace Game.Misc
public void SendQuestGiverOfferReward(Quest quest, ObjectGuid npcGUID, bool autoLaunched) public void SendQuestGiverOfferReward(Quest quest, ObjectGuid npcGUID, bool autoLaunched)
{ {
GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType.QuestGiver);
QuestGiverOfferRewardMessage packet = new(); QuestGiverOfferRewardMessage packet = new();
packet.QuestTitle = quest.LogTitle; packet.QuestTitle = quest.LogTitle;
@@ -616,6 +643,8 @@ namespace Game.Misc
return; return;
} }
GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType.QuestGiver);
QuestGiverRequestItems packet = new(); QuestGiverRequestItems packet = new();
packet.QuestTitle = quest.LogTitle; packet.QuestTitle = quest.LogTitle;
@@ -852,17 +881,17 @@ namespace Game.Misc
public ConditionsReference Conditions; public ConditionsReference Conditions;
} }
public class TrainerData
{
public uint Id;
}
public class PlayerChoiceData public class PlayerChoiceData
{ {
uint _choiceId; uint _choiceId;
List<Response> _responses = new(); List<Response> _responses = new();
DateTime? _expireTime; DateTime? _expireTime;
public PlayerChoiceData(uint choiceId)
{
_choiceId = choiceId;
}
public uint? FindIdByClientIdentifier(ushort clientIdentifier) public uint? FindIdByClientIdentifier(ushort clientIdentifier)
{ {
var itr = _responses.Find(p => p.ClientIdentifier == clientIdentifier); var itr = _responses.Find(p => p.ClientIdentifier == clientIdentifier);
@@ -688,6 +688,18 @@ namespace Game.Entities
public void SendRespecWipeConfirm(ObjectGuid guid, uint cost, SpecResetType respecType) public void SendRespecWipeConfirm(ObjectGuid guid, uint cost, SpecResetType respecType)
{ {
switch (respecType)
{
case SpecResetType.Talents:
PlayerTalkClass.GetInteractionData().StartInteraction(guid, PlayerInteractionType.TalentMaster);
break;
case SpecResetType.Specialization:
PlayerTalkClass.GetInteractionData().StartInteraction(guid, PlayerInteractionType.SpecializationMaster);
break;
default:
break;
}
RespecWipeConfirm respecWipeConfirm = new(); RespecWipeConfirm respecWipeConfirm = new();
respecWipeConfirm.RespecMaster = guid; respecWipeConfirm.RespecMaster = guid;
respecWipeConfirm.Cost = cost; respecWipeConfirm.Cost = cost;
+26 -20
View File
@@ -2787,6 +2787,7 @@ namespace Game.Entities
PlayerTalkClass.SendGossipMenu(textId, source.GetGUID()); PlayerTalkClass.SendGossipMenu(textId, source.GetGUID());
} }
public void OnGossipSelect(WorldObject source, int gossipOptionId, uint menuId) public void OnGossipSelect(WorldObject source, int gossipOptionId, uint menuId)
{ {
GossipMenu gossipMenu = PlayerTalkClass.GetGossipMenu(); GossipMenu gossipMenu = PlayerTalkClass.GetGossipMenu();
@@ -2882,7 +2883,10 @@ namespace Game.Entities
case GossipOptionNpc.GuildBanker: case GossipOptionNpc.GuildBanker:
Guild guild = GetGuild(); Guild guild = GetGuild();
if (guild != null) if (guild != null)
{
PlayerTalkClass.GetInteractionData().StartInteraction(source.GetGUID(), PlayerInteractionType.GuildBanker);
guild.SendBankList(GetSession(), 0, true); guild.SendBankList(GetSession(), 0, true);
}
else else
Guild.SendCommandResult(GetSession(), GuildCommandType.ViewTab, GuildCommandError.PlayerNotInGuild); Guild.SendCommandResult(GetSession(), GuildCommandType.ViewTab, GuildCommandError.PlayerNotInGuild);
break; break;
@@ -2930,23 +2934,9 @@ namespace Game.Entities
} }
if (!handled) if (!handled)
{
if (item.GossipNpcOptionID.HasValue)
{
GossipMenuAddon addon = ObjectMgr.GetGossipMenuAddon(menuId);
GossipOptionNPCInteraction npcInteraction = new();
npcInteraction.GossipGUID = source.GetGUID();
npcInteraction.GossipNpcOptionID = item.GossipNpcOptionID.Value;
if (addon != null && addon.FriendshipFactionID != 0)
npcInteraction.FriendshipFactionID = addon.FriendshipFactionID;
SendPacket(npcInteraction);
}
else
{ {
PlayerInteractionType[] GossipOptionNpcToInteractionType = PlayerInteractionType[] GossipOptionNpcToInteractionType =
{ [
PlayerInteractionType.None, PlayerInteractionType.Vendor, PlayerInteractionType.TaxiNode, PlayerInteractionType.None, PlayerInteractionType.Vendor, PlayerInteractionType.TaxiNode,
PlayerInteractionType.Trainer, PlayerInteractionType.SpiritHealer, PlayerInteractionType.Binder, PlayerInteractionType.Trainer, PlayerInteractionType.SpiritHealer, PlayerInteractionType.Binder,
PlayerInteractionType.Banker, PlayerInteractionType.PetitionVendor, PlayerInteractionType.GuildTabardVendor, PlayerInteractionType.Banker, PlayerInteractionType.PetitionVendor, PlayerInteractionType.GuildTabardVendor,
@@ -2966,12 +2956,29 @@ namespace Game.Entities
PlayerInteractionType.ProfessionsCraftingOrder, PlayerInteractionType.Professions, PlayerInteractionType.ProfessionsCustomerOrder, PlayerInteractionType.ProfessionsCraftingOrder, PlayerInteractionType.Professions, PlayerInteractionType.ProfessionsCustomerOrder,
PlayerInteractionType.TraitSystem, PlayerInteractionType.BarbersChoice, PlayerInteractionType.MajorFactionRenown, PlayerInteractionType.TraitSystem, PlayerInteractionType.BarbersChoice, PlayerInteractionType.MajorFactionRenown,
PlayerInteractionType.PersonalTabardVendor, PlayerInteractionType.ForgeMaster, PlayerInteractionType.CharacterBanker, PlayerInteractionType.PersonalTabardVendor, PlayerInteractionType.ForgeMaster, PlayerInteractionType.CharacterBanker,
PlayerInteractionType.AccountBanker, PlayerInteractionType.ProfessionRespec,PlayerInteractionType.PlaceholderType72, PlayerInteractionType.AccountBanker, PlayerInteractionType.ProfessionRespec, PlayerInteractionType.PlaceholderType72,
PlayerInteractionType.PlaceholderType75, PlayerInteractionType.PlaceholderType76, PlayerInteractionType.GuildRename, PlayerInteractionType.PlaceholderType75, PlayerInteractionType.PlaceholderType76, PlayerInteractionType.GuildRename,
PlayerInteractionType.PlaceholderType77, PlayerInteractionType.ItemUpgrade PlayerInteractionType.PlaceholderType77, PlayerInteractionType.ItemUpgrade
}; ];
PlayerInteractionType interactionType = GossipOptionNpcToInteractionType[(int)gossipOptionNpc]; PlayerInteractionType interactionType = GossipOptionNpcToInteractionType[(int)gossipOptionNpc];
if (interactionType != PlayerInteractionType.None)
PlayerTalkClass.GetInteractionData().StartInteraction(source.GetGUID(), interactionType);
if (item.GossipNpcOptionID.HasValue)
{
GossipMenuAddon addon = ObjectMgr.GetGossipMenuAddon(menuId);
GossipOptionNPCInteraction npcInteraction = new();
npcInteraction.GossipGUID = source.GetGUID();
npcInteraction.GossipNpcOptionID = item.GossipNpcOptionID.Value;
if (addon != null && addon.FriendshipFactionID != 0)
npcInteraction.FriendshipFactionID = addon.FriendshipFactionID;
SendPacket(npcInteraction);
}
else
{
if (interactionType != PlayerInteractionType.None) if (interactionType != PlayerInteractionType.None)
{ {
NPCInteractionOpenResult npcInteraction = new(); NPCInteractionOpenResult npcInteraction = new();
@@ -4953,9 +4960,8 @@ namespace Game.Entities
Locale locale = GetSession().GetSessionDbLocaleIndex(); Locale locale = GetSession().GetSessionDbLocaleIndex();
PlayerChoiceLocale playerChoiceLocale = locale != Locale.enUS ? ObjectMgr.GetPlayerChoiceLocale(choiceId) : null; PlayerChoiceLocale playerChoiceLocale = locale != Locale.enUS ? ObjectMgr.GetPlayerChoiceLocale(choiceId) : null;
PlayerTalkClass.GetInteractionData().Reset(); PlayerTalkClass.GetInteractionData().StartInteraction(sender, PlayerInteractionType.PlayerChoice);
PlayerTalkClass.GetInteractionData().SourceGuid = sender; PlayerTalkClass.GetInteractionData().GetPlayerChoice().SetChoiceId((uint)choiceId);
PlayerTalkClass.GetInteractionData().SetPlayerChoice((uint)choiceId);
DisplayPlayerChoice displayPlayerChoice = new(); DisplayPlayerChoice displayPlayerChoice = new();
displayPlayerChoice.SenderGUID = sender; displayPlayerChoice.SenderGUID = sender;
+2
View File
@@ -993,6 +993,8 @@ namespace Game
if (ahEntry == null) if (ahEntry == null)
return; return;
GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(guid, PlayerInteractionType.Auctioneer);
AuctionHelloResponse auctionHelloResponse = new(); AuctionHelloResponse auctionHelloResponse = new();
auctionHelloResponse.Auctioneer = guid; auctionHelloResponse.Auctioneer = guid;
auctionHelloResponse.AuctionHouseID = ahEntry.Id; auctionHelloResponse.AuctionHouseID = ahEntry.Id;
+2 -2
View File
@@ -307,8 +307,8 @@ namespace Game
public void SendShowBank(ObjectGuid guid, PlayerInteractionType interactionType) public void SendShowBank(ObjectGuid guid, PlayerInteractionType interactionType)
{ {
_player.PlayerTalkClass.GetInteractionData().Reset(); _player.PlayerTalkClass.GetInteractionData().StartInteraction(guid, interactionType);
_player.PlayerTalkClass.GetInteractionData().SourceGuid = guid;
NPCInteractionOpenResult npcInteraction = new(); NPCInteractionOpenResult npcInteraction = new();
npcInteraction.Npc = guid; npcInteraction.Npc = guid;
npcInteraction.InteractionType = interactionType; npcInteraction.InteractionType = interactionType;
+2
View File
@@ -265,6 +265,8 @@ namespace Game
return; return;
} }
GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(packet.Banker, PlayerInteractionType.GuildBanker);
guild.SendBankList(this, 0, packet.FullUpdate); guild.SendBankList(this, 0, packet.FullUpdate);
} }
+1 -2
View File
@@ -562,8 +562,7 @@ namespace Game
response.Mails.Add(new MailListEntry(m, player)); response.Mails.Add(new MailListEntry(m, player));
} }
player.PlayerTalkClass.GetInteractionData().Reset(); player.PlayerTalkClass.GetInteractionData().StartInteraction(getList.Mailbox, PlayerInteractionType.MailInfo);
player.PlayerTalkClass.GetInteractionData().SourceGuid = getList.Mailbox;
SendPacket(response); SendPacket(response);
// recalculate m_nextMailDelivereTime and unReadMails // recalculate m_nextMailDelivereTime and unReadMails
+7 -6
View File
@@ -89,9 +89,8 @@ namespace Game
return; return;
} }
_player.PlayerTalkClass.GetInteractionData().Reset(); _player.PlayerTalkClass.GetInteractionData().StartInteraction(npc.GetGUID(), PlayerInteractionType.Trainer);
_player.PlayerTalkClass.GetInteractionData().SourceGuid = npc.GetGUID(); _player.PlayerTalkClass.GetInteractionData().GetTrainer().Id = trainerId;
_player.PlayerTalkClass.GetInteractionData().SetTrainerId(trainerId);
trainer.SendSpells(npc, _player, GetSessionDbLocaleIndex()); trainer.SendSpells(npc, _player, GetSessionDbLocaleIndex());
} }
@@ -109,10 +108,10 @@ namespace Game
if (_player.HasUnitState(UnitState.Died)) if (_player.HasUnitState(UnitState.Died))
_player.RemoveAurasByType(AuraType.FeignDeath); _player.RemoveAurasByType(AuraType.FeignDeath);
if (_player.PlayerTalkClass.GetInteractionData().SourceGuid != packet.TrainerGUID) if (!_player.PlayerTalkClass.GetInteractionData().IsInteractingWith(packet.TrainerGUID, PlayerInteractionType.Trainer))
return; return;
if (_player.PlayerTalkClass.GetInteractionData().GetTrainerId() != packet.TrainerID) if (_player.PlayerTalkClass.GetInteractionData().GetTrainer().Id != packet.TrainerID)
return; return;
// check present spell in trainer spell list // check present spell in trainer spell list
@@ -177,7 +176,7 @@ namespace Game
return; return;
// Prevent cheating on C# scripted menus // Prevent cheating on C# scripted menus
if (GetPlayer().PlayerTalkClass.GetInteractionData().SourceGuid != packet.GossipUnit) if (!_player.PlayerTalkClass.GetInteractionData().IsInteractingWith(packet.GossipUnit, PlayerInteractionType.Gossip))
return; return;
Creature unit = null; Creature unit = null;
@@ -424,6 +423,8 @@ namespace Game
if (GetPlayer().HasUnitState(UnitState.Died)) if (GetPlayer().HasUnitState(UnitState.Died))
GetPlayer().RemoveAurasByType(AuraType.FeignDeath); GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(vendorGuid, PlayerInteractionType.Vendor);
// Stop the npc if moving // Stop the npc if moving
uint pause = vendor.GetMovementTemplate().GetInteractionPauseTimer(); uint pause = vendor.GetMovementTemplate().GetInteractionPauseTimer();
if (pause != 0) if (pause != 0)
+1 -2
View File
@@ -425,8 +425,7 @@ namespace Game
return; return;
} }
WorldPacket data = new(ServerOpcodes.PetitionShowList); GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(guid, PlayerInteractionType.PetitionVendor);
data.WritePackedGuid(guid); // npc guid
ServerPetitionShowList packet = new(); ServerPetitionShowList packet = new();
packet.Unit = guid; packet.Unit = guid;
+10 -28
View File
@@ -77,50 +77,34 @@ namespace Game
// no or incorrect quest giver // no or incorrect quest giver
if (obj == null) if (obj == null)
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return; return;
}
Player playerQuestObject = obj.ToPlayer(); Player playerQuestObject = obj.ToPlayer();
if (playerQuestObject != null) if (playerQuestObject != null)
{ {
if ((_player.GetPlayerSharingQuest().IsEmpty() && _player.GetPlayerSharingQuest() != packet.QuestGiverGUID) || !playerQuestObject.CanShareQuest(packet.QuestID)) if ((_player.GetPlayerSharingQuest().IsEmpty() && _player.GetPlayerSharingQuest() != packet.QuestGiverGUID) || !playerQuestObject.CanShareQuest(packet.QuestID))
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return; return;
}
if (!_player.IsInSameRaidWith(playerQuestObject)) if (!_player.IsInSameRaidWith(playerQuestObject))
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return; return;
} }
}
else else
{ {
if (!obj.HasQuest(packet.QuestID)) if (!obj.HasQuest(packet.QuestID))
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return; return;
} }
}
// some kind of WPE protection // some kind of WPE protection
if (!_player.CanInteractWithQuestGiver(obj)) if (!_player.CanInteractWithQuestGiver(obj))
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return; return;
}
Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID); Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID);
if (quest != null) if (quest == null)
{ return;
// prevent cheating // prevent cheating
if (!GetPlayer().CanTakeQuest(quest, true)) if (!GetPlayer().CanTakeQuest(quest, true))
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return; return;
}
if (!_player.GetPlayerSharingQuest().IsEmpty()) if (!_player.GetPlayerSharingQuest().IsEmpty())
{ {
@@ -132,8 +116,9 @@ namespace Game
} }
} }
if (_player.CanAddQuest(quest, true)) if (!_player.CanAddQuest(quest, true))
{ return;
_player.AddQuestAndCheckCompletion(quest, obj); _player.AddQuestAndCheckCompletion(quest, obj);
if (quest.IsPushedToPartyOnAccept()) if (quest.IsPushedToPartyOnAccept())
@@ -181,14 +166,11 @@ namespace Game
launchGossip(go); launchGossip(go);
} }
} }
// do not close gossip if quest accept script started a new interaction
else if (!_player.PlayerTalkClass.GetInteractionData().IsInteractingWith(obj.GetGUID(), PlayerInteractionType.QuestGiver))
_player.PlayerTalkClass.GetInteractionData().IsLaunchedByQuest = true;
else else
_player.PlayerTalkClass.SendCloseGossip(); _player.PlayerTalkClass.SendCloseGossip();
return;
}
}
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
} }
[WorldPacketHandler(ClientOpcodes.QuestGiverQueryQuest, Processing = PacketProcessing.Inplace)] [WorldPacketHandler(ClientOpcodes.QuestGiverQueryQuest, Processing = PacketProcessing.Inplace)]
+2
View File
@@ -85,6 +85,8 @@ namespace Game
if (curloc == 0) if (curloc == 0)
return; return;
GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(unit.GetGUID(), PlayerInteractionType.TaxiNode);
bool lastTaxiCheaterState = GetPlayer().IsTaxiCheater(); bool lastTaxiCheaterState = GetPlayer().IsTaxiCheater();
if (unit.GetEntry() == 29480) 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. 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.