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)
return;
player.PlayerTalkClass.GetInteractionData().StartInteraction(guid, PlayerInteractionType.BattleMaster);
BattlefieldList battlefieldList = new();
battlefieldList.BattlemasterGuid = guid;
battlefieldList.BattlemasterListID = (int)bgTypeId;
-1
View File
@@ -275,7 +275,6 @@ namespace Game.DataStorage
_curvePoints.AddRange(curveId, curvePoints.Select(p => p.Pos));
}
foreach (EmotesTextSoundRecord emoteTextSound in EmotesTextSoundStorage.Values)
_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 ObjectGuid SourceGuid;
public PlayerInteractionType InteractionType;
public bool IsLaunchedByQuest;
ushort _playerChoiceResponseIdentifierGenerator = 0; // not reset between interactions
uint trainerId;
TrainerData trainerData;
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()
{
SourceGuid.Clear();
InteractionType = PlayerInteractionType.None;
IsLaunchedByQuest = false;
trainerId = 0;
trainerData = null;
playerChoiceData = null;
}
public uint? GetTrainerId() { return trainerId; }
public void SetTrainerId(uint _trainerId) { trainerId = _trainerId; }
public TrainerData GetTrainer() { return trainerData; }
public PlayerChoiceData GetPlayerChoice() { return playerChoiceData; }
public void SetPlayerChoice(uint choiceId) { playerChoiceData = new PlayerChoiceData(choiceId); }
public ushort AddPlayerChoiceResponse(uint responseId)
{
@@ -250,8 +271,7 @@ namespace Game.Misc
public void SendGossipMenu(uint titleTextId, ObjectGuid objectGUID)
{
_interactionData.Reset();
_interactionData.SourceGuid = objectGUID;
_interactionData.StartInteraction(objectGUID, PlayerInteractionType.Gossip);
GossipMessagePkt packet = new();
packet.GossipGUID = objectGUID;
@@ -362,6 +382,9 @@ namespace Game.Misc
public void SendQuestGiverQuestListMessage(WorldObject questgiver)
{
ObjectGuid guid = questgiver.GetGUID();
GetInteractionData().StartInteraction(guid, PlayerInteractionType.QuestGiver);
Locale localeConstant = _session.GetSessionDbLocaleIndex();
QuestGiverQuestListMessage questList = new();
@@ -429,6 +452,8 @@ namespace Game.Misc
public void SendQuestGiverQuestDetails(Quest quest, ObjectGuid npcGUID, bool autoLaunched, bool displayPopup)
{
GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType.QuestGiver);
QuestGiverQuestDetails packet = new();
packet.QuestTitle = quest.LogTitle;
@@ -532,6 +557,8 @@ namespace Game.Misc
public void SendQuestGiverOfferReward(Quest quest, ObjectGuid npcGUID, bool autoLaunched)
{
GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType.QuestGiver);
QuestGiverOfferRewardMessage packet = new();
packet.QuestTitle = quest.LogTitle;
@@ -616,6 +643,8 @@ namespace Game.Misc
return;
}
GetInteractionData().StartInteraction(npcGUID, PlayerInteractionType.QuestGiver);
QuestGiverRequestItems packet = new();
packet.QuestTitle = quest.LogTitle;
@@ -852,17 +881,17 @@ namespace Game.Misc
public ConditionsReference Conditions;
}
public class TrainerData
{
public uint Id;
}
public class PlayerChoiceData
{
uint _choiceId;
List<Response> _responses = new();
DateTime? _expireTime;
public PlayerChoiceData(uint choiceId)
{
_choiceId = choiceId;
}
public uint? FindIdByClientIdentifier(ushort 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)
{
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.RespecMaster = guid;
respecWipeConfirm.Cost = cost;
+25 -19
View File
@@ -2787,6 +2787,7 @@ namespace Game.Entities
PlayerTalkClass.SendGossipMenu(textId, source.GetGUID());
}
public void OnGossipSelect(WorldObject source, int gossipOptionId, uint menuId)
{
GossipMenu gossipMenu = PlayerTalkClass.GetGossipMenu();
@@ -2882,7 +2883,10 @@ namespace Game.Entities
case GossipOptionNpc.GuildBanker:
Guild guild = GetGuild();
if (guild != null)
{
PlayerTalkClass.GetInteractionData().StartInteraction(source.GetGUID(), PlayerInteractionType.GuildBanker);
guild.SendBankList(GetSession(), 0, true);
}
else
Guild.SendCommandResult(GetSession(), GuildCommandType.ViewTab, GuildCommandError.PlayerNotInGuild);
break;
@@ -2930,23 +2934,9 @@ namespace Game.Entities
}
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.None, PlayerInteractionType.Vendor, PlayerInteractionType.TaxiNode,
PlayerInteractionType.Trainer, PlayerInteractionType.SpiritHealer, PlayerInteractionType.Binder,
PlayerInteractionType.Banker, PlayerInteractionType.PetitionVendor, PlayerInteractionType.GuildTabardVendor,
@@ -2969,9 +2959,26 @@ namespace Game.Entities
PlayerInteractionType.AccountBanker, PlayerInteractionType.ProfessionRespec, PlayerInteractionType.PlaceholderType72,
PlayerInteractionType.PlaceholderType75, PlayerInteractionType.PlaceholderType76, PlayerInteractionType.GuildRename,
PlayerInteractionType.PlaceholderType77, PlayerInteractionType.ItemUpgrade
};
];
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)
{
NPCInteractionOpenResult npcInteraction = new();
@@ -4953,9 +4960,8 @@ namespace Game.Entities
Locale locale = GetSession().GetSessionDbLocaleIndex();
PlayerChoiceLocale playerChoiceLocale = locale != Locale.enUS ? ObjectMgr.GetPlayerChoiceLocale(choiceId) : null;
PlayerTalkClass.GetInteractionData().Reset();
PlayerTalkClass.GetInteractionData().SourceGuid = sender;
PlayerTalkClass.GetInteractionData().SetPlayerChoice((uint)choiceId);
PlayerTalkClass.GetInteractionData().StartInteraction(sender, PlayerInteractionType.PlayerChoice);
PlayerTalkClass.GetInteractionData().GetPlayerChoice().SetChoiceId((uint)choiceId);
DisplayPlayerChoice displayPlayerChoice = new();
displayPlayerChoice.SenderGUID = sender;
+2
View File
@@ -993,6 +993,8 @@ namespace Game
if (ahEntry == null)
return;
GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(guid, PlayerInteractionType.Auctioneer);
AuctionHelloResponse auctionHelloResponse = new();
auctionHelloResponse.Auctioneer = guid;
auctionHelloResponse.AuctionHouseID = ahEntry.Id;
+2 -2
View File
@@ -307,8 +307,8 @@ namespace Game
public void SendShowBank(ObjectGuid guid, PlayerInteractionType interactionType)
{
_player.PlayerTalkClass.GetInteractionData().Reset();
_player.PlayerTalkClass.GetInteractionData().SourceGuid = guid;
_player.PlayerTalkClass.GetInteractionData().StartInteraction(guid, interactionType);
NPCInteractionOpenResult npcInteraction = new();
npcInteraction.Npc = guid;
npcInteraction.InteractionType = interactionType;
+2
View File
@@ -265,6 +265,8 @@ namespace Game
return;
}
GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(packet.Banker, PlayerInteractionType.GuildBanker);
guild.SendBankList(this, 0, packet.FullUpdate);
}
+1 -2
View File
@@ -562,8 +562,7 @@ namespace Game
response.Mails.Add(new MailListEntry(m, player));
}
player.PlayerTalkClass.GetInteractionData().Reset();
player.PlayerTalkClass.GetInteractionData().SourceGuid = getList.Mailbox;
player.PlayerTalkClass.GetInteractionData().StartInteraction(getList.Mailbox, PlayerInteractionType.MailInfo);
SendPacket(response);
// recalculate m_nextMailDelivereTime and unReadMails
+7 -6
View File
@@ -89,9 +89,8 @@ namespace Game
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());
}
@@ -109,10 +108,10 @@ namespace Game
if (_player.HasUnitState(UnitState.Died))
_player.RemoveAurasByType(AuraType.FeignDeath);
if (_player.PlayerTalkClass.GetInteractionData().SourceGuid != packet.TrainerGUID)
if (!_player.PlayerTalkClass.GetInteractionData().IsInteractingWith(packet.TrainerGUID, PlayerInteractionType.Trainer))
return;
if (_player.PlayerTalkClass.GetInteractionData().GetTrainerId() != packet.TrainerID)
if (_player.PlayerTalkClass.GetInteractionData().GetTrainer().Id != packet.TrainerID)
return;
// check present spell in trainer spell list
@@ -177,7 +176,7 @@ namespace Game
return;
// Prevent cheating on C# scripted menus
if (GetPlayer().PlayerTalkClass.GetInteractionData().SourceGuid != packet.GossipUnit)
if (!_player.PlayerTalkClass.GetInteractionData().IsInteractingWith(packet.GossipUnit, PlayerInteractionType.Gossip))
return;
Creature unit = null;
@@ -424,6 +423,8 @@ namespace Game
if (GetPlayer().HasUnitState(UnitState.Died))
GetPlayer().RemoveAurasByType(AuraType.FeignDeath);
GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(vendorGuid, PlayerInteractionType.Vendor);
// Stop the npc if moving
uint pause = vendor.GetMovementTemplate().GetInteractionPauseTimer();
if (pause != 0)
+1 -2
View File
@@ -425,8 +425,7 @@ namespace Game
return;
}
WorldPacket data = new(ServerOpcodes.PetitionShowList);
data.WritePackedGuid(guid); // npc guid
GetPlayer().PlayerTalkClass.GetInteractionData().StartInteraction(guid, PlayerInteractionType.PetitionVendor);
ServerPetitionShowList packet = new();
packet.Unit = guid;
+10 -28
View File
@@ -77,50 +77,34 @@ namespace Game
// no or incorrect quest giver
if (obj == null)
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return;
}
Player playerQuestObject = obj.ToPlayer();
if (playerQuestObject != null)
{
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 (!obj.HasQuest(packet.QuestID))
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return;
}
}
// some kind of WPE protection
if (!_player.CanInteractWithQuestGiver(obj))
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return;
}
Quest quest = Global.ObjectMgr.GetQuestTemplate(packet.QuestID);
if (quest != null)
{
if (quest == null)
return;
// prevent cheating
if (!GetPlayer().CanTakeQuest(quest, true))
{
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
return;
}
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);
if (quest.IsPushedToPartyOnAccept())
@@ -181,14 +166,11 @@ namespace Game
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
_player.PlayerTalkClass.SendCloseGossip();
return;
}
}
CLOSE_GOSSIP_CLEAR_SHARING_INFO();
}
[WorldPacketHandler(ClientOpcodes.QuestGiverQueryQuest, Processing = PacketProcessing.Inplace)]
+2
View File
@@ -85,6 +85,8 @@ namespace Game
if (curloc == 0)
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.