Core/Texts: Refactor Emote/Sound handling and add ConditionID for ChatTextBuilders (#30343)

This commit is contained in:
Jeremy
2024-10-21 02:34:00 +02:00
committed by GitHub
parent bef005e346
commit caccb06190
8 changed files with 91 additions and 143 deletions

View File

@@ -8353,4 +8353,11 @@ enum WorldState : uint32
WS_WAR_MODE_ALLIANCE_BUFF_VALUE = 17043,
};
enum class SoundKitPlayType : uint8
{
Normal = 0,
ObjectSound = 1,
Max = 2
};
#endif

View File

@@ -630,6 +630,8 @@ namespace WorldPackets
{
public:
PlayObjectSound() : ServerPacket(SMSG_PLAY_OBJECT_SOUND, 16 + 16 + 4 + 4 * 3) { }
PlayObjectSound(ObjectGuid targetObjectGUID, ObjectGuid sourceObjectGUID, int32 soundKitID, TaggedPosition<::Position::XYZ> position, int32 broadcastTextID) : ServerPacket(SMSG_PLAY_OBJECT_SOUND, 16 + 16 + 4 + 4 * 3),
TargetObjectGUID(targetObjectGUID), SourceObjectGUID(sourceObjectGUID), SoundKitID(soundKitID), Position(position), BroadcastTextID(broadcastTextID) { }
WorldPacket const* Write() override;

View File

@@ -27,15 +27,56 @@
namespace Trinity
{
ChatPacketSender::ChatPacketSender(ChatMsg chatType, ::Language language, WorldObject const* sender, WorldObject const* receiver,
std::string message, uint32 achievementId /*= 0*/, LocaleConstant locale /*= LOCALE_enUS*/)
: Type(chatType), Language(language), Sender(sender), Receiver(receiver), Text(std::move(message)), AchievementId(achievementId), Locale(locale)
std::string message, uint32 achievementId /*= 0*/, LocaleConstant locale /*= LOCALE_enUS*/, uint32 broadcastTextId /*= 0*/, uint16 emoteId /*= 0*/, uint32 soundKitId /*= 0*/, SoundKitPlayType soundKitPlayType /*= SoundKitPlayType::Normal*/, uint32 playerConditionId /*= 0*/)
: Type(chatType), Language(language), Sender(sender), Receiver(receiver), Text(std::move(message)), AchievementId(achievementId), Locale(locale), PlayerConditionID(playerConditionId)
{
UntranslatedPacket.Initialize(Type, Language, Sender, Receiver, Text, AchievementId, "", Locale);
UntranslatedPacket.Write();
if (sender && sender->IsUnit() && emoteId)
{
EmotePacket.emplace();
EmotePacket->Guid = sender->GetGUID();
EmotePacket->EmoteID = emoteId;
EmotePacket->Write();
}
SoundPacket = nullptr;
if (soundKitId)
{
if (soundKitPlayType == SoundKitPlayType::Normal)
{
SoundPacket = std::make_unique<WorldPackets::Misc::PlaySound>(
sender ? sender->GetGUID() : ObjectGuid::Empty,
soundKitId,
broadcastTextId
);
}
else if (soundKitPlayType == SoundKitPlayType::ObjectSound)
{
SoundPacket = std::make_unique<WorldPackets::Misc::PlayObjectSound>(
receiver ? receiver->GetGUID() : ObjectGuid::Empty,
sender ? sender->GetGUID() : ObjectGuid::Empty,
soundKitId,
receiver ? receiver->GetWorldLocation() : Position(0, 0, 0),
broadcastTextId
);
}
SoundPacket->Write();
}
}
void ChatPacketSender::operator()(Player const* player) const
{
if (!player->MeetPlayerCondition(PlayerConditionID))
return;
if (SoundPacket)
player->SendDirectMessage(SoundPacket->GetRawPacket());
if (EmotePacket)
player->SendDirectMessage(EmotePacket->GetRawPacket());
if (Language == LANG_UNIVERSAL || Language == LANG_ADDON || Language == LANG_ADDON_LOGGED || player->CanUnderstandLanguage(Language))
{
player->SendDirectMessage(UntranslatedPacket.GetRawPacket());
@@ -56,7 +97,23 @@ void ChatPacketSender::operator()(Player const* player) const
ChatPacketSender* BroadcastTextBuilder::operator()(LocaleConstant locale) const
{
BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(_textId);
return new ChatPacketSender(_msgType, bct ? Language(bct->LanguageID) : LANG_UNIVERSAL, _source, _target, bct ? DB2Manager::GetBroadcastTextValue(bct, locale, _gender) : "", _achievementId, locale);
Unit const* unitSender = Object::ToUnit(_source);
uint8 const gender = unitSender ? unitSender->GetGender() : GENDER_UNKNOWN;
uint32 soundKitId = bct ? bct->SoundKitID[gender == GENDER_FEMALE ? 1 : 0] : 0;
return new ChatPacketSender(_msgType,
bct ? Language(bct->LanguageID) : LANG_UNIVERSAL,
_source,
_target,
bct ? DB2Manager::GetBroadcastTextValue(bct, locale, _gender) : "",
_achievementId,
locale,
bct ? bct->ID : 0,
bct ? bct->EmotesID : 0,
soundKitId,
SoundKitPlayType::Normal,
bct ? bct->ConditionID : 0
);
}
ChatPacketSender* CustomChatTextBuilder::operator()(LocaleConstant locale) const
@@ -87,6 +144,7 @@ ChatPacketSender* TrinityStringChatBuilder::operator()(LocaleConstant locale) co
ChatPacketSender* CreatureTextTextBuilder::operator()(LocaleConstant locale) const
{
return new ChatPacketSender(_msgType, _language, _talker, _target, sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale), 0, locale);
return new ChatPacketSender(_msgType, _language, _talker, _target, sCreatureTextMgr->GetLocalizedChatString(_source->GetEntry(), _gender, _textGroup, _textId, locale), 0, locale,
_broadcastTextId, _emoteId, _soundKitId, _soundKitPlayType, _playerConditionId);
}
}

View File

@@ -20,7 +20,10 @@
#include "Common.h"
#include "ChatPackets.h"
#include "MiscPackets.h"
#include "SharedDefines.h"
#include <memory>
#include <string>
class Player;
@@ -39,14 +42,17 @@ namespace Trinity
std::string Text;
uint32 AchievementId;
LocaleConstant Locale;
uint32 PlayerConditionID;
public:
// caches
WorldPackets::Chat::Chat UntranslatedPacket;
mutable Optional<WorldPackets::Chat::Chat> TranslatedPacket;
Optional<WorldPackets::Chat::Emote> EmotePacket;
std::unique_ptr<WorldPackets::ServerPacket> SoundPacket;
ChatPacketSender(ChatMsg chatType, ::Language language, WorldObject const* sender, WorldObject const* receiver, std::string message,
uint32 achievementId = 0, LocaleConstant locale = LOCALE_enUS);
uint32 achievementId = 0, LocaleConstant locale = LOCALE_enUS, uint32 broadcastTextId = 0, uint16 emoteId = 0, uint32 soundKitId = 0, SoundKitPlayType soundKitPlayType = SoundKitPlayType::Normal, uint32 playerConditionId = 0);
void operator()(Player const* player) const;
};
@@ -103,8 +109,8 @@ namespace Trinity
class CreatureTextTextBuilder
{
public:
CreatureTextTextBuilder(WorldObject const* obj, WorldObject const* speaker, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, Language language, WorldObject const* target)
: _source(obj), _talker(speaker), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target) { }
CreatureTextTextBuilder(WorldObject const* obj, WorldObject const* speaker, uint8 gender, ChatMsg msgtype, uint8 textGroup, uint32 id, Language language, WorldObject const* target, uint32 broadcastTextId, uint16 emoteId, uint32 soundKitId, SoundKitPlayType soundKitPlayType, uint32 playerConditionId)
: _source(obj), _talker(speaker), _gender(gender), _msgType(msgtype), _textGroup(textGroup), _textId(id), _language(language), _target(target), _broadcastTextId(broadcastTextId), _emoteId(emoteId), _soundKitId(soundKitId), _soundKitPlayType(soundKitPlayType), _playerConditionId(playerConditionId) { }
ChatPacketSender* operator()(LocaleConstant locale) const;
@@ -117,6 +123,11 @@ namespace Trinity
uint32 _textId;
Language _language;
WorldObject const* _target;
uint32 _broadcastTextId;
uint16 _emoteId;
uint32 _soundKitId;
SoundKitPlayType _soundKitPlayType;
uint32 _playerConditionId;
};
}
// namespace Trinity

View File

@@ -213,36 +213,31 @@ uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject
Language finalLang = (language == LANG_ADDON) ? iter->lang : language;
uint32 finalSound = iter->sound;
SoundKitPlayType finalPlayType = iter->SoundPlayType;
BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(iter->BroadcastTextId);
if (sound)
{
finalSound = sound;
finalPlayType = playType;
}
else if (BroadcastTextEntry const* bct = sBroadcastTextStore.LookupEntry(iter->BroadcastTextId))
else if (bct)
if (uint32 broadcastTextSoundId = bct->SoundKitID[source->GetGender() == GENDER_FEMALE ? 1 : 0])
finalSound = broadcastTextSoundId;
if (range == TEXT_RANGE_NORMAL)
range = iter->TextRange;
if (finalSound)
SendSound(source, finalSound, finalType, whisperTarget, range, team, gmOnly, iter->BroadcastTextId, finalPlayType);
Unit* finalSource = source;
if (srcPlr)
finalSource = srcPlr;
if (iter->emote)
SendEmote(finalSource, iter->emote);
if (srcPlr)
{
Trinity::CreatureTextTextBuilder builder(source, finalSource, finalSource->GetGender(), finalType, iter->groupId, iter->id, finalLang, whisperTarget);
Trinity::CreatureTextTextBuilder builder(source, finalSource, finalSource->GetGender(), finalType, iter->groupId, iter->id, finalLang, whisperTarget, iter->BroadcastTextId, iter->emote, finalSound, finalPlayType, bct->ConditionID);
SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
}
else
{
Trinity::CreatureTextTextBuilder builder(finalSource, finalSource, finalSource->GetGender(), finalType, iter->groupId, iter->id, finalLang, whisperTarget);
Trinity::CreatureTextTextBuilder builder(finalSource, finalSource, finalSource->GetGender(), finalType, iter->groupId, iter->id, finalLang, whisperTarget, iter->BroadcastTextId, iter->emote, finalSound, finalPlayType, bct->ConditionID);
SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly);
}
@@ -269,119 +264,6 @@ float CreatureTextMgr::GetRangeForChatType(ChatMsg msgType)
return dist;
}
void CreatureTextMgr::SendSound(Creature* source, uint32 sound, ChatMsg msgType, WorldObject const* whisperTarget /*= nullptr*/, CreatureTextRange range /*= TEXT_RANGE_NORMAL*/,
Team team /*= TEAM_OTHER*/, bool gmOnly /*= false*/, uint32 keyBroadcastTextId /*= 0*/, SoundKitPlayType playType /*= SoundKitPlayType::Normal*/)
{
if (!sound || !source)
return;
if (playType == SoundKitPlayType::ObjectSound)
{
WorldPackets::Misc::PlayObjectSound pkt;
pkt.TargetObjectGUID = whisperTarget->GetGUID();
pkt.SourceObjectGUID = source->GetGUID();
pkt.SoundKitID = sound;
pkt.Position = whisperTarget->GetWorldLocation();
pkt.BroadcastTextID = keyBroadcastTextId;
SendNonChatPacket(source, pkt.Write(), msgType, whisperTarget, range, team, gmOnly);
}
else if (playType == SoundKitPlayType::Normal)
SendNonChatPacket(source, WorldPackets::Misc::PlaySound(source->GetGUID(), sound, keyBroadcastTextId).Write(), msgType, whisperTarget, range, team, gmOnly);
}
void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket const* data, ChatMsg msgType, WorldObject const* whisperTarget, CreatureTextRange range, Team team, bool gmOnly)
{
switch (msgType)
{
case CHAT_MSG_MONSTER_PARTY:
{
if (!whisperTarget)
return;
if (Player const* whisperPlayer = whisperTarget->ToPlayer())
{
if (Group const* group = whisperPlayer->GetGroup())
group->BroadcastWorker([data](Player* player) { player->SendDirectMessage(data); });
}
return;
}
case CHAT_MSG_MONSTER_WHISPER:
case CHAT_MSG_RAID_BOSS_WHISPER:
{
if (range == TEXT_RANGE_NORMAL) // ignores team and gmOnly
{
if (!whisperTarget || whisperTarget->GetTypeId() != TYPEID_PLAYER)
return;
whisperTarget->ToPlayer()->SendDirectMessage(data);
return;
}
break;
}
default:
break;
}
switch (range)
{
case TEXT_RANGE_AREA:
{
uint32 areaId = source->GetAreaId();
Map::PlayerList const& players = source->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (itr->GetSource()->GetAreaId() == areaId && (!team || Team(itr->GetSource()->GetEffectiveTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
itr->GetSource()->SendDirectMessage(data);
return;
}
case TEXT_RANGE_ZONE:
{
uint32 zoneId = source->GetZoneId();
Map::PlayerList const& players = source->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (itr->GetSource()->GetZoneId() == zoneId && (!team || Team(itr->GetSource()->GetEffectiveTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
itr->GetSource()->SendDirectMessage(data);
return;
}
case TEXT_RANGE_MAP:
{
Map::PlayerList const& players = source->GetMap()->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if ((!team || Team(itr->GetSource()->GetEffectiveTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster()))
itr->GetSource()->SendDirectMessage(data);
return;
}
case TEXT_RANGE_WORLD:
{
SessionMap const& smap = sWorld->GetAllSessions();
for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter)
if (Player* player = iter->second->GetPlayer())
if ((!team || Team(player->GetTeam()) == team) && (!gmOnly || player->IsGameMaster()))
player->SendDirectMessage(data);
return;
}
case TEXT_RANGE_PERSONAL:
if (!whisperTarget || !whisperTarget->IsPlayer())
return;
whisperTarget->ToPlayer()->SendDirectMessage(data);
return;
case TEXT_RANGE_NORMAL:
default:
break;
}
float dist = GetRangeForChatType(msgType);
source->SendMessageToSetInRange(data, dist, true);
}
void CreatureTextMgr::SendEmote(Unit* source, Emote emote)
{
if (!source)
return;
source->HandleEmoteCommand(emote);
}
bool CreatureTextMgr::TextExist(uint32 sourceEntry, uint8 textGroup) const
{
if (!sourceEntry)

View File

@@ -40,13 +40,6 @@ enum CreatureTextRange
TEXT_RANGE_PERSONAL = 5
};
enum class SoundKitPlayType : uint8
{
Normal = 0,
ObjectSound = 1,
Max = 2,
};
struct CreatureTextEntry
{
uint32 creatureId;
@@ -105,9 +98,6 @@ class TC_GAME_API CreatureTextMgr
void LoadCreatureTextLocales();
CreatureTextMap const& GetTextMap() const { return mTextMap; }
static void SendSound(Creature* source, uint32 sound, ChatMsg msgType, WorldObject const* whisperTarget = nullptr, CreatureTextRange range = TEXT_RANGE_NORMAL, Team team = TEAM_OTHER, bool gmOnly = false, uint32 keyBroadcastTextId = 0, SoundKitPlayType playType = SoundKitPlayType::Normal);
static void SendEmote(Unit* source, Emote emote);
//if sent, returns the 'duration' of the text else 0 if error
uint32 SendChat(Creature* source, uint8 textGroup, WorldObject const* whisperTarget = nullptr, ChatMsg msgType = CHAT_MSG_ADDON, Language language = LANG_ADDON, CreatureTextRange range = TEXT_RANGE_NORMAL, uint32 sound = 0, SoundKitPlayType playType = SoundKitPlayType::Normal, Team team = TEAM_OTHER, bool gmOnly = false, Player* srcPlr = nullptr);
bool TextExist(uint32 sourceEntry, uint8 textGroup) const;
@@ -119,8 +109,6 @@ class TC_GAME_API CreatureTextMgr
static float GetRangeForChatType(ChatMsg msgType);
private:
static void SendNonChatPacket(WorldObject* source, WorldPacket const* data, ChatMsg msgType, WorldObject const* whisperTarget, CreatureTextRange range, Team team, bool gmOnly);
CreatureTextMap mTextMap;
LocaleCreatureTextMap mLocaleTextMap;
};

View File

@@ -1106,7 +1106,7 @@ struct boss_the_lich_king : public BossAI
break;
case EVENT_OUTRO_SOUL_BARRAGE:
me->CastSpell(nullptr, SPELL_SOUL_BARRAGE, TRIGGERED_IGNORE_CAST_IN_PROGRESS);
CreatureTextMgr::SendSound(me, SOUND_PAIN, CHAT_MSG_MONSTER_YELL, 0, TEXT_RANGE_NORMAL, TEAM_OTHER, false);
me->PlayDirectSound(SOUND_PAIN);
// set flight
me->SetDisableGravity(true);
me->GetMotionMaster()->MovePoint(POINT_LK_OUTRO_2, OutroFlying);

View File

@@ -998,7 +998,7 @@ class boss_yogg_saron : public CreatureScript
break;
case EVENT_LUNATIC_GAZE:
DoCast(me, SPELL_LUNATIC_GAZE);
CreatureTextMgr::SendSound(me, SOUND_LUNATIC_GAZE, CHAT_MSG_MONSTER_YELL);
me->PlayDirectSound(SOUND_LUNATIC_GAZE);
_events.ScheduleEvent(EVENT_LUNATIC_GAZE, 12s, 0, PHASE_THREE);
break;
case EVENT_DEAFENING_ROAR: