From 40ec7e29995792e69da6347ed4189c456c81b01e Mon Sep 17 00:00:00 2001 From: Hondacrx Date: Mon, 11 Nov 2024 10:31:00 -0500 Subject: [PATCH] Core/Texts: Refactor Emote/Sound handling and add ConditionID for ChatTextBuilders Port From (https://github.com/TrinityCore/TrinityCore/commit/caccb06190376d6812e40da36b27e22df8d7f546) --- Source/Game/Networking/Packets/MiscPackets.cs | 9 + Source/Game/Text/ChatTextBuilder.cs | 59 +++- Source/Game/Text/CreatureTextManager.cs | 267 ++++-------------- 3 files changed, 126 insertions(+), 209 deletions(-) diff --git a/Source/Game/Networking/Packets/MiscPackets.cs b/Source/Game/Networking/Packets/MiscPackets.cs index 4f86d0ebd..05804777f 100644 --- a/Source/Game/Networking/Packets/MiscPackets.cs +++ b/Source/Game/Networking/Packets/MiscPackets.cs @@ -883,6 +883,15 @@ namespace Game.Networking.Packets { public PlayObjectSound() : base(ServerOpcodes.PlayObjectSound) { } + public PlayObjectSound(ObjectGuid targetObjectGUID, ObjectGuid sourceObjectGUID, uint soundKitID, Vector3 position, int broadcastTextID) : base(ServerOpcodes.PlayObjectSound) + { + TargetObjectGUID = targetObjectGUID; + SourceObjectGUID = sourceObjectGUID; + SoundKitID = soundKitID; + Position = position; + BroadcastTextID = broadcastTextID; + } + public override void Write() { _worldPacket.WriteUInt32(SoundKitID); diff --git a/Source/Game/Text/ChatTextBuilder.cs b/Source/Game/Text/ChatTextBuilder.cs index b4c5c591a..3849ff870 100644 --- a/Source/Game/Text/ChatTextBuilder.cs +++ b/Source/Game/Text/ChatTextBuilder.cs @@ -5,6 +5,7 @@ using Framework.Constants; using Framework.Dynamic; using Game.DataStorage; using Game.Entities; +using Game.Networking; using Game.Networking.Packets; using System.Collections.Generic; @@ -24,12 +25,16 @@ namespace Game.Chat string Text; uint AchievementId; Locale Locale; + uint PlayerConditionID; // caches public ChatPkt UntranslatedPacket; public ChatPkt TranslatedPacket; + public EmoteMessage EmotePacket; + public ServerPacket SoundPacket; - public ChatPacketSender(ChatMsg chatType, Language language, WorldObject sender, WorldObject receiver, string message, uint achievementId = 0, Locale locale = Locale.enUS) + public ChatPacketSender(ChatMsg chatType, Language language, WorldObject sender, WorldObject receiver, string message, uint achievementId = 0, Locale locale = Locale.enUS, + uint broadcastTextId = 0, ushort emoteId = 0, uint soundKitId = 0, SoundKitPlayType soundKitPlayType = SoundKitPlayType.Normal, uint playerConditionId = 0) { Type = chatType; Language = language; @@ -38,14 +43,46 @@ namespace Game.Chat Text = message; AchievementId = achievementId; Locale = locale; + PlayerConditionID = playerConditionId; UntranslatedPacket = new(); UntranslatedPacket.Initialize(Type, Language, Sender, Receiver, Text, AchievementId, "", Locale); UntranslatedPacket.Write(); + + if (sender != null && sender.IsUnit() && emoteId != 0) + { + EmotePacket = new(); + EmotePacket.Guid = sender.GetGUID(); + EmotePacket.EmoteID = emoteId; + EmotePacket.Write(); + } + + SoundPacket = null; + if (soundKitId != 0) + { + if (soundKitPlayType == SoundKitPlayType.Normal) + { + SoundPacket = new PlaySound(sender != null ? sender.GetGUID() : ObjectGuid.Empty, soundKitId, broadcastTextId); + } + else if (soundKitPlayType == SoundKitPlayType.ObjectSound) + { + SoundPacket = new PlayObjectSound(receiver != null ? receiver.GetGUID() : ObjectGuid.Empty, sender != null ? sender.GetGUID() : ObjectGuid.Empty, soundKitId, receiver != null ? receiver.GetWorldLocation() : new Position(0, 0, 0), (int)broadcastTextId); + } + SoundPacket.Write(); + } } public void Invoke(Player player) { + if (!player.MeetPlayerCondition(PlayerConditionID)) + return; + + if (SoundPacket != null) + player.SendPacket(SoundPacket); + + if (EmotePacket != null) + player.SendPacket(EmotePacket); + if (Language == Language.Universal || Language == Language.Addon || Language == Language.AddonLogged || player.CanUnderstandLanguage(Language)) { player.SendPacket(UntranslatedPacket); @@ -62,7 +99,7 @@ namespace Game.Chat player.SendPacket(TranslatedPacket); } } - + public class BroadcastTextBuilder : MessageBuilder { public BroadcastTextBuilder(WorldObject obj, ChatMsg msgtype, uint textId, Gender gender, WorldObject target = null, uint achievementId = 0) @@ -78,7 +115,23 @@ namespace Game.Chat public override ChatPacketSender Invoke(Locale locale = Locale.enUS) { BroadcastTextRecord bct = CliDB.BroadcastTextStorage.LookupByKey(_textId); - return new ChatPacketSender(_msgType, bct != null ? (Language)bct.LanguageID : Language.Universal, _source, _target, bct != null ? Global.DB2Mgr.GetBroadcastTextValue(bct, locale, _gender) : "", _achievementId, locale); + Unit unitSender = _source?.ToUnit(); + Gender gender = unitSender != null ? unitSender.GetGender() : Gender.Unknown; + uint soundKitId = bct != null ? bct.SoundKitID[gender == Gender.Female ? 1 : 0] : 0; + + return new ChatPacketSender(_msgType, + bct != null ? (Language)bct.LanguageID : Language.Universal, + _source, + _target, + bct != null ? Global.DB2Mgr.GetBroadcastTextValue(bct, locale, _gender) : "", + _achievementId, + locale, + bct != null ? bct.Id : 0, + bct != null ? bct.EmotesID : (ushort)0, + soundKitId, + SoundKitPlayType.Normal, + bct != null ? (uint)bct.ConditionID : 0 + ); } WorldObject _source; diff --git a/Source/Game/Text/CreatureTextManager.cs b/Source/Game/Text/CreatureTextManager.cs index 21999e267..b5c42aaff 100644 --- a/Source/Game/Text/CreatureTextManager.cs +++ b/Source/Game/Text/CreatureTextManager.cs @@ -106,7 +106,7 @@ namespace Game if (!mTextMap.ContainsKey(temp.creatureId)) { - mTextMap[temp.creatureId] = new MultiMap(); + mTextMap[temp.creatureId] = new MultiMap(); ++creatureCount; } @@ -189,43 +189,35 @@ namespace Game Language finalLang = (language == Language.Addon) ? textEntry.lang : language; uint finalSound = textEntry.sound; SoundKitPlayType finalPlayType = textEntry.SoundPlayType; + BroadcastTextRecord bct = CliDB.BroadcastTextStorage.LookupByKey(textEntry.BroadcastTextId); if (sound != 0) { finalSound = sound; finalPlayType = playType; } - else + else if (bct != null) { - BroadcastTextRecord bct = CliDB.BroadcastTextStorage.LookupByKey(textEntry.BroadcastTextId); - if (bct != null) - { - uint broadcastTextSoundId = bct.SoundKitID[source.GetGender() == Gender.Female ? 1 : 0]; - if (broadcastTextSoundId != 0) - finalSound = broadcastTextSoundId; - } + uint broadcastTextSoundId = bct.SoundKitID[source.GetGender() == Gender.Female ? 1 : 0]; + if (broadcastTextSoundId != 0) + finalSound = broadcastTextSoundId; } + if (range == CreatureTextRange.Normal) range = textEntry.TextRange; - if (finalSound != 0) - SendSound(source, finalSound, finalType, whisperTarget, range, team, gmOnly, textEntry.BroadcastTextId, finalPlayType); - Unit finalSource = source; if (srcPlr != null) finalSource = srcPlr; - if (textEntry.emote != 0) - SendEmote(finalSource, textEntry.emote); - if (srcPlr != null) { - PlayerTextBuilder builder = new(source, finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget); + CreatureTextBuilder builder = new(source, finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget, textEntry.BroadcastTextId, (ushort)textEntry.emote, finalSound, finalPlayType, (uint)bct.ConditionID); SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly); } else { - CreatureTextBuilder builder = new(finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget); + CreatureTextBuilder builder = new(finalSource, finalSource, finalSource.GetGender(), finalType, textEntry.groupId, textEntry.id, finalLang, whisperTarget, textEntry.BroadcastTextId, (ushort)textEntry.emote, finalSound, finalPlayType, (uint)bct.ConditionID); SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly); } @@ -252,122 +244,6 @@ namespace Game return dist; } - public void SendSound(Creature source, uint sound, ChatMsg msgType, WorldObject whisperTarget = null, CreatureTextRange range = CreatureTextRange.Normal, Team team = Team.Other, bool gmOnly = false, uint keyBroadcastTextId = 0, SoundKitPlayType playType = SoundKitPlayType.Normal) - { - if (sound == 0 || source == null) - return; - - if (playType == SoundKitPlayType.ObjectSound) - { - PlayObjectSound pkt = new(); - pkt.TargetObjectGUID = whisperTarget.GetGUID(); - pkt.SourceObjectGUID = source.GetGUID(); - pkt.SoundKitID = sound; - pkt.Position = whisperTarget.GetWorldLocation(); - pkt.BroadcastTextID = (int)keyBroadcastTextId; - SendNonChatPacket(source, pkt, msgType, whisperTarget, range, team, gmOnly); - } - else if (playType == SoundKitPlayType.Normal) - SendNonChatPacket(source, new PlaySound(source.GetGUID(), sound, keyBroadcastTextId), msgType, whisperTarget, range, team, gmOnly); - } - - void SendNonChatPacket(WorldObject source, ServerPacket data, ChatMsg msgType, WorldObject whisperTarget, CreatureTextRange range, Team team, bool gmOnly) - { - float dist = GetRangeForChatType(msgType); - - switch (msgType) - { - case ChatMsg.MonsterParty: - if (whisperTarget == null) - return; - - Player whisperPlayer = whisperTarget.ToPlayer(); - if (whisperPlayer != null) - { - Group group = whisperPlayer.GetGroup(); - if (group != null) - group.BroadcastWorker(player => player.SendPacket(data)); - } - return; - case ChatMsg.MonsterWhisper: - case ChatMsg.RaidBossWhisper: - { - if (range == CreatureTextRange.Normal)//ignores team and gmOnly - { - if (whisperTarget == null || !whisperTarget.IsTypeId(TypeId.Player)) - return; - - whisperTarget.ToPlayer().SendPacket(data); - return; - } - break; - } - default: - break; - } - - switch (range) - { - case CreatureTextRange.Area: - { - uint areaId = source.GetAreaId(); - var players = source.GetMap().GetPlayers(); - foreach (var pl in players) - if (pl.GetAreaId() == areaId && (team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) - pl.SendPacket(data); - return; - } - case CreatureTextRange.Zone: - { - uint zoneId = source.GetZoneId(); - var players = source.GetMap().GetPlayers(); - foreach (var pl in players) - if (pl.GetZoneId() == zoneId && (team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) - pl.SendPacket(data); - return; - } - case CreatureTextRange.Map: - { - var players = source.GetMap().GetPlayers(); - foreach (var pl in players) - if ((team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) - pl.SendPacket(data); - return; - } - case CreatureTextRange.World: - { - var smap = Global.WorldMgr.GetAllSessions(); - foreach (var session in smap) - { - Player player = session.GetPlayer(); - if (player != null) - if ((team == 0 || player.GetTeam() == team) && (!gmOnly || player.IsGameMaster())) - player.SendPacket(data); - } - return; - } - case CreatureTextRange.Personal: - if (whisperTarget == null || !whisperTarget.IsPlayer()) - return; - - whisperTarget.ToPlayer().SendPacket(data); - return; - case CreatureTextRange.Normal: - default: - break; - } - - source.SendMessageToSetInRange(data, dist, true); - } - - void SendEmote(Unit source, Emote emote) - { - if (source == null) - return; - - source.HandleEmoteCommand(emote); - } - public bool TextExist(uint sourceEntry, byte textGroup) { if (sourceEntry == 0) @@ -443,17 +319,17 @@ namespace Game { case ChatMsg.MonsterWhisper: case ChatMsg.RaidBossWhisper: + { + if (range == CreatureTextRange.Normal) //ignores team and gmOnly { - if (range == CreatureTextRange.Normal) //ignores team and gmOnly - { - if (whisperTarget == null || !whisperTarget.IsTypeId(TypeId.Player)) - return; - - localizer.Invoke(whisperTarget.ToPlayer()); + if (whisperTarget == null || !whisperTarget.IsTypeId(TypeId.Player)) return; - } - break; + + localizer.Invoke(whisperTarget.ToPlayer()); + return; } + break; + } default: break; } @@ -461,43 +337,43 @@ namespace Game switch (range) { case CreatureTextRange.Area: - { - uint areaId = source.GetAreaId(); - var players = source.GetMap().GetPlayers(); - foreach (var pl in players) - if (pl.GetAreaId() == areaId && (team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) - localizer.Invoke(pl); - return; - } + { + uint areaId = source.GetAreaId(); + var players = source.GetMap().GetPlayers(); + foreach (var pl in players) + if (pl.GetAreaId() == areaId && (team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) + localizer.Invoke(pl); + return; + } case CreatureTextRange.Zone: - { - uint zoneId = source.GetZoneId(); - var players = source.GetMap().GetPlayers(); - foreach (var pl in players) - if (pl.GetZoneId() == zoneId && (team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) - localizer.Invoke(pl); - return; - } + { + uint zoneId = source.GetZoneId(); + var players = source.GetMap().GetPlayers(); + foreach (var pl in players) + if (pl.GetZoneId() == zoneId && (team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) + localizer.Invoke(pl); + return; + } case CreatureTextRange.Map: - { - var players = source.GetMap().GetPlayers(); - foreach (var pl in players) - if ((team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) - localizer.Invoke(pl); - return; - } + { + var players = source.GetMap().GetPlayers(); + foreach (var pl in players) + if ((team == 0 || pl.GetEffectiveTeam() == team) && (!gmOnly || pl.IsGameMaster())) + localizer.Invoke(pl); + return; + } case CreatureTextRange.World: + { + var smap = Global.WorldMgr.GetAllSessions(); + foreach (var session in smap) { - var smap = Global.WorldMgr.GetAllSessions(); - foreach (var session in smap) - { - Player player = session.GetPlayer(); - if (player != null) - if ((team == 0 || player.GetTeam() == team) && (!gmOnly || player.IsGameMaster())) - localizer.Invoke(player); - } - return; + Player player = session.GetPlayer(); + if (player != null) + if ((team == 0 || player.GetTeam() == team) && (!gmOnly || player.IsGameMaster())) + localizer.Invoke(player); } + return; + } case CreatureTextRange.Personal: if (whisperTarget == null || !whisperTarget.IsPlayer()) return; @@ -615,7 +491,7 @@ namespace Game public class CreatureTextBuilder : MessageBuilder { - public CreatureTextBuilder(WorldObject obj, Gender gender, ChatMsg msgtype, byte textGroup, uint id, Language language, WorldObject target) + public CreatureTextBuilder(WorldObject obj, WorldObject speaker, Gender gender, ChatMsg msgtype, byte textGroup, uint id, Language language, WorldObject target, uint broadcastTextId, ushort emoteId, uint soundKitId, SoundKitPlayType soundKitPlayType, uint playerConditionId) { _source = obj; _gender = gender; @@ -624,43 +500,17 @@ namespace Game _textId = id; _language = language; _target = target; + _broadcastTextId = broadcastTextId; + _emoteId = emoteId; + _soundKitId = soundKitId; + _soundKitPlayType = soundKitPlayType; + _playerConditionId = playerConditionId; } public override ChatPacketSender Invoke(Locale locale = Locale.enUS) { string text = Global.CreatureTextMgr.GetLocalizedChatString(_source.GetEntry(), _gender, _textGroup, _textId, locale); - return new ChatPacketSender(_msgType, _language, _source, _target, text, 0, locale); - } - - WorldObject _source; - Gender _gender; - ChatMsg _msgType; - byte _textGroup; - uint _textId; - Language _language; - WorldObject _target; - } - - public class PlayerTextBuilder : MessageBuilder - { - public PlayerTextBuilder(WorldObject obj, WorldObject speaker, Gender gender, ChatMsg msgtype, byte textGroup, uint id, Language language, WorldObject target) - { - _source = obj; - _gender = gender; - _talker = speaker; - _msgType = msgtype; - _textGroup = textGroup; - _textId = id; - _language = language; - _target = target; - } - - public override PacketSenderOwning Invoke(Locale loc_idx = Locale.enUS) - { - string text = Global.CreatureTextMgr.GetLocalizedChatString(_source.GetEntry(), _gender, _textGroup, _textId, loc_idx); - PacketSenderOwning chat = new(); - chat.Data.Initialize(_msgType, _language, _talker, _target, text, 0, "", loc_idx); - return chat; + return new ChatPacketSender(_msgType, _language, _talker, _target, text, 0, locale, _broadcastTextId, _emoteId, _soundKitId, _soundKitPlayType, _playerConditionId); } WorldObject _source; @@ -671,5 +521,10 @@ namespace Game uint _textId; Language _language; WorldObject _target; + uint _broadcastTextId; + ushort _emoteId; + uint _soundKitId; + SoundKitPlayType _soundKitPlayType; + uint _playerConditionId; } } \ No newline at end of file