refactor(Core/Unit): clean MonsterText methods (#6957)

This commit is contained in:
Kitzunu 2021-10-15 10:25:29 +02:00 committed by GitHub
parent 3c42a7d72d
commit bc82f36f1f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 750 additions and 672 deletions

View file

@ -17,7 +17,7 @@
#include "Cell.h"
#include "CellImpl.h"
#include "Chat.h"
#include "ChatTextBuilder.h"
#include "CreatureTextMgr.h"
#include "GameEventMgr.h"
#include "GossipDef.h"
@ -37,27 +37,6 @@
#include "SpellMgr.h"
#include "Vehicle.h"
class AcoreStringTextBuilder
{
public:
AcoreStringTextBuilder(WorldObject* obj, ChatMsg msgtype, int32 id, uint32 language, WorldObject* target)
: _source(obj), _msgType(msgtype), _textId(id), _language(language), _target(target)
{
}
size_t operator()(WorldPacket* data, LocaleConstant locale) const
{
std::string text = sObjectMgr->GetAcoreString(_textId, locale);
return ChatHandler::BuildChatPacket(*data, _msgType, Language(_language), _source, _target, text, 0, "", locale);
}
WorldObject* _source;
ChatMsg _msgType;
int32 _textId;
uint32 _language;
WorldObject* _target;
};
SmartScript::SmartScript()
{
go = nullptr;
@ -259,7 +238,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
{
if (IsUnit(*itr))
{
(*itr)->SendPlaySound(e.action.sound.sound, e.action.sound.onlySelf > 0);
(*itr)->PlayDirectSound(e.action.sound.sound, e.action.sound.onlySelf ? (*itr)->ToPlayer() : nullptr);
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (%s), sound: %u, onlyself: %u",
(*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), e.action.sound.sound, e.action.sound.onlySelf);
}
@ -302,7 +281,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
if (IsUnit(*itr))
{
uint32 sound = temp[urand(0, count - 1)];
(*itr)->SendPlaySound(sound, e.action.randomSound.onlySelf > 0);
(*itr)->PlayDirectSound(sound, e.action.randomSound.onlySelf ? (*itr)->ToPlayer() : nullptr);
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_SOUND: target: %s (%s), sound: %u, onlyself: %u",
(*itr)->GetName().c_str(), (*itr)->GetGUID().ToString().c_str(), sound, e.action.randomSound.onlySelf);
}
@ -992,7 +971,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
me->DoFleeToGetAssistance();
if (e.action.flee.withEmote)
{
AcoreStringTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, LANG_FLEE, LANG_UNIVERSAL, nullptr);
Acore::BroadcastTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, BROADCAST_TEXT_FLEE_FOR_ASSIST, me->getGender());
sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE);
}
LOG_DEBUG("sql.sql", "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: Creature %s DoFleeToGetAssistance", me->GetGUID().ToString().c_str());
@ -1297,7 +1276,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u
(*itr)->ToCreature()->CallForHelp((float)e.action.callHelp.range);
if (e.action.callHelp.withEmote)
{
AcoreStringTextBuilder builder(*itr, CHAT_MSG_MONSTER_EMOTE, LANG_CALL_FOR_HELP, LANG_UNIVERSAL, nullptr);
Acore::BroadcastTextBuilder builder(*itr, CHAT_MSG_MONSTER_EMOTE, BROADCAST_TEXT_CALL_FOR_HELP, LANG_UNIVERSAL, nullptr);
sCreatureTextMgr->SendChatPacket(*itr, builder, CHAT_MSG_MONSTER_EMOTE);
}
}

View file

@ -23,6 +23,7 @@
#include "BattlegroundAB.h"
#include "CellImpl.h"
#include "Chat.h"
#include "ChatTextBuilder.h"
#include "Common.h"
#include "DatabaseEnv.h"
#include "DBCEnums.h"
@ -43,34 +44,6 @@
#include "World.h"
#include "WorldPacket.h"
namespace Acore
{
class AchievementChatBuilder
{
public:
AchievementChatBuilder(Player const* player, ChatMsg msgType, uint32 textId, uint32 achievementId)
: _player(player), _msgType(msgType), _textId(textId), _achievementId(achievementId) { }
void operator()(WorldPacket& data, LocaleConstant locale)
{
std::string text = "";
BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId);
if (bct)
{
ObjectMgr::GetLocaleString(_player->getGender() == GENDER_MALE ? bct->MaleText : bct->FemaleText, locale, text);
}
ChatHandler::BuildChatPacket(data, _msgType, LANG_UNIVERSAL, _player, _player, text, _achievementId);
}
private:
Player const* _player;
ChatMsg _msgType;
int32 _textId;
uint32 _achievementId;
};
} // namespace Acore
bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria)
{
if (dataType >= MAX_ACHIEVEMENT_CRITERIA_DATA_TYPE)
@ -702,8 +675,8 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
Guild* guild = sGuildMgr->GetGuildById(GetPlayer()->GetGuildId());
if (guild)
{
Acore::AchievementChatBuilder _builder(GetPlayer(), CHAT_MSG_GUILD_ACHIEVEMENT, BROADCAST_TEXT_ACHIEVEMENT_EARNED, achievement->ID);
Acore::LocalizedPacketDo<Acore::AchievementChatBuilder> _localizer(_builder);
Acore::BroadcastTextBuilder _builder(GetPlayer(), CHAT_MSG_GUILD_ACHIEVEMENT, BROADCAST_TEXT_ACHIEVEMENT_EARNED, GetPlayer()->getGender(), GetPlayer(), achievement->ID);
Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> _localizer(_builder);
guild->BroadcastWorker(_localizer, GetPlayer());
}
@ -745,9 +718,10 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement)
Cell cell(p);
cell.SetNoCreate();
Acore::AchievementChatBuilder _builder(GetPlayer(), CHAT_MSG_ACHIEVEMENT, BROADCAST_TEXT_ACHIEVEMENT_EARNED, achievement->ID);
Acore::LocalizedPacketDo<Acore::AchievementChatBuilder> _localizer(_builder);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::AchievementChatBuilder> > _worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), _localizer);
Acore::BroadcastTextBuilder _builder(GetPlayer(), CHAT_MSG_ACHIEVEMENT, BROADCAST_TEXT_ACHIEVEMENT_EARNED, GetPlayer()->getGender(), GetPlayer(), achievement->ID);
Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> _localizer(_builder);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder>> _worker(GetPlayer(), sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), _localizer);
TypeContainerVisitor<Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> >, WorldTypeMapContainer > message(_worker);
Cell::VisitWorldObjects(GetPlayer(), _worker, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}

View file

@ -609,7 +609,7 @@ bool ChatHandler::ShowHelpForCommand(std::vector<ChatCommand> const& table, cons
return ShowHelpForSubCommands(table, "", cmd);
}
size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag,
size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string_view message, uint8 chatTag,
std::string const& senderName /*= ""*/, std::string const& receiverName /*= ""*/,
uint32 achievementId /*= 0*/, bool gmMessage /*= false*/, std::string const& channelName /*= ""*/)
{
@ -689,7 +689,7 @@ size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Languag
return receiverGUIDPos;
}
size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message,
size_t ChatHandler::BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string_view message,
uint32 achievementId /*= 0*/, std::string const& channelName /*= ""*/, LocaleConstant locale /*= DEFAULT_LOCALE*/)
{
ObjectGuid senderGUID;

View file

@ -57,12 +57,12 @@ public:
virtual ~ChatHandler() { }
// Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders
static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string const& message, uint8 chatTag,
static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, ObjectGuid senderGUID, ObjectGuid receiverGUID, std::string_view message, uint8 chatTag,
std::string const& senderName = "", std::string const& receiverName = "",
uint32 achievementId = 0, bool gmMessage = false, std::string const& channelName = "");
// Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders
static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE);
static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string_view message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE);
static char* LineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = nullptr; return start; }

View file

@ -1936,16 +1936,6 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) co
return true;
}
void WorldObject::SendPlaySound(uint32 Sound, bool OnlySelf)
{
WorldPacket data(SMSG_PLAY_SOUND, 4);
data << Sound;
if (OnlySelf && GetTypeId() == TYPEID_PLAYER)
this->ToPlayer()->GetSession()->SendPacket(&data);
else
SendMessageToSet(&data, true); // ToSelf ignored in this case
}
void WorldObject::SendPlayMusic(uint32 Music, bool OnlySelf)
{
WorldPacket data(SMSG_PLAY_MUSIC, 4);
@ -1962,165 +1952,6 @@ void Object::ForceValuesUpdateAtIndex(uint32 i)
AddToObjectUpdateIfNeeded();
}
namespace Acore
{
class MonsterChatBuilder
{
public:
MonsterChatBuilder(WorldObject const* obj, ChatMsg msgtype, int32 textId, uint32 language, WorldObject const* target)
: i_object(obj), i_msgtype(msgtype), i_textId(textId), i_language(Language(language)), i_target(target) { }
void operator()(WorldPacket& data, LocaleConstant loc_idx)
{
if (BroadcastText const* broadcastText = sObjectMgr->GetBroadcastText(i_textId))
{
uint8 gender = GENDER_MALE;
if (Unit const* unit = i_object->ToUnit())
gender = unit->getGender();
std::string text = broadcastText->GetText(loc_idx, gender);
ChatHandler::BuildChatPacket(data, i_msgtype, i_language, i_object, i_target, text, 0, "", loc_idx);
}
else
LOG_ERROR("entities.object", "MonsterChatBuilder: `broadcast_text` id %i missing", i_textId);
}
private:
WorldObject const* i_object;
ChatMsg i_msgtype;
int32 i_textId;
Language i_language;
WorldObject const* i_target;
};
class MonsterCustomChatBuilder
{
public:
MonsterCustomChatBuilder(WorldObject const* obj, ChatMsg msgtype, const char* text, uint32 language, WorldObject const* target)
: i_object(obj), i_msgtype(msgtype), i_text(text), i_language(Language(language)), i_target(target)
{}
void operator()(WorldPacket& data, LocaleConstant loc_idx)
{
ChatHandler::BuildChatPacket(data, i_msgtype, i_language, i_object, i_target, i_text, 0, "", loc_idx);
}
private:
WorldObject const* i_object;
ChatMsg i_msgtype;
const char* i_text;
Language i_language;
WorldObject const* i_target;
};
} // namespace Acore
void WorldObject::MonsterSay(const char* text, uint32 language, WorldObject const* target)
{
CellCoord p = Acore::ComputeCellCoord(GetPositionX(), GetPositionY());
Cell cell(p);
cell.SetNoCreate();
Acore::MonsterCustomChatBuilder say_build(this, CHAT_MSG_MONSTER_SAY, text, language, target);
Acore::LocalizedPacketDo<Acore::MonsterCustomChatBuilder> say_do(say_build);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterCustomChatBuilder> > say_worker(this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do);
TypeContainerVisitor<Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterCustomChatBuilder> >, WorldTypeMapContainer > message(say_worker);
cell.Visit(p, message, *GetMap(), *this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}
void WorldObject::MonsterSay(int32 textId, uint32 language, WorldObject const* target)
{
CellCoord p = Acore::ComputeCellCoord(GetPositionX(), GetPositionY());
Cell cell(p);
cell.SetNoCreate();
Acore::MonsterChatBuilder say_build(this, CHAT_MSG_MONSTER_SAY, textId, language, target);
Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> say_do(say_build);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> > say_worker(this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), say_do);
TypeContainerVisitor<Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
cell.Visit(p, message, *GetMap(), *this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY));
}
void WorldObject::MonsterYell(const char* text, uint32 language, WorldObject const* target)
{
CellCoord p = Acore::ComputeCellCoord(GetPositionX(), GetPositionY());
Cell cell(p);
cell.SetNoCreate();
Acore::MonsterCustomChatBuilder say_build(this, CHAT_MSG_MONSTER_YELL, text, language, target);
Acore::LocalizedPacketDo<Acore::MonsterCustomChatBuilder> say_do(say_build);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterCustomChatBuilder> > say_worker(this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), say_do);
TypeContainerVisitor<Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterCustomChatBuilder> >, WorldTypeMapContainer > message(say_worker);
cell.Visit(p, message, *GetMap(), *this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL));
}
void WorldObject::MonsterYell(int32 textId, uint32 language, WorldObject const* target)
{
CellCoord p = Acore::ComputeCellCoord(GetPositionX(), GetPositionY());
Cell cell(p);
cell.SetNoCreate();
Acore::MonsterChatBuilder say_build(this, CHAT_MSG_MONSTER_YELL, textId, language, target);
Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> say_do(say_build);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> > say_worker(this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), say_do);
TypeContainerVisitor<Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
cell.Visit(p, message, *GetMap(), *this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL));
}
void WorldObject::MonsterTextEmote(const char* text, WorldObject const* target, bool IsBossEmote)
{
WorldPacket data;
ChatHandler::BuildChatPacket(data, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, LANG_UNIVERSAL,
this, target, text);
SendMessageToSetInRange(&data, (IsBossEmote ? 200.0f : sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)), true);
}
void WorldObject::MonsterTextEmote(int32 textId, WorldObject const* target, bool IsBossEmote)
{
CellCoord p = Acore::ComputeCellCoord(GetPositionX(), GetPositionY());
Cell cell(p);
cell.SetNoCreate();
Acore::MonsterChatBuilder say_build(this, IsBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, textId, LANG_UNIVERSAL, target);
Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> say_do(say_build);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> > say_worker(this, (IsBossEmote ? 200.0f : sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)), say_do);
TypeContainerVisitor<Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::MonsterChatBuilder> >, WorldTypeMapContainer > message(say_worker);
cell.Visit(p, message, *GetMap(), *this, (IsBossEmote ? 200.0f : sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE)));
}
void WorldObject::MonsterWhisper(const char* text, Player const* target, bool IsBossWhisper)
{
if (!target)
return;
LocaleConstant loc_idx = target->GetSession()->GetSessionDbLocaleIndex();
WorldPacket data;
ChatHandler::BuildChatPacket(data, IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, text, 0, "", loc_idx);
target->GetSession()->SendPacket(&data);
}
void WorldObject::MonsterWhisper(int32 textId, Player const* target, bool IsBossWhisper)
{
if (!target)
return;
uint8 gender = GENDER_MALE;
if (Unit const* unit = ToUnit())
gender = unit->getGender();
LocaleConstant loc_idx = target->GetSession()->GetSessionDbLocaleIndex();
BroadcastText const* broadcastText = sObjectMgr->GetBroadcastText(textId);
std::string text = broadcastText->GetText(loc_idx, gender);
WorldPacket data;
ChatHandler::BuildChatPacket(data, IsBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, text.c_str(), 0, "", loc_idx);
target->GetSession()->SendPacket(&data);
}
void Unit::BuildHeartBeatMsg(WorldPacket* data) const
{
data->Initialize(MSG_MOVE_HEARTBEAT, 32);

View file

@ -937,15 +937,6 @@ public:
virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; }
void MonsterSay(const char* text, uint32 language, WorldObject const* target);
void MonsterYell(const char* text, uint32 language, WorldObject const* target);
void MonsterTextEmote(const char* text, WorldObject const* target, bool IsBossEmote = false);
void MonsterWhisper(const char* text, Player const* target, bool IsBossWhisper = false);
void MonsterSay(int32 textId, uint32 language, WorldObject const* target);
void MonsterYell(int32 textId, uint32 language, WorldObject const* target);
void MonsterTextEmote(int32 textId, WorldObject const* target, bool IsBossEmote = false);
void MonsterWhisper(int32 textId, Player const* target, bool IsBossWhisper = false);
void PlayDistanceSound(uint32 sound_id, Player* target = nullptr);
void PlayDirectSound(uint32 sound_id, Player* target = nullptr);
void PlayDirectMusic(uint32 music_id, Player* target = nullptr);
@ -971,7 +962,6 @@ public:
FlaggedValuesArray32<int32, uint32, ServerSideVisibilityType, TOTAL_SERVERSIDE_VISIBILITY_TYPES> m_serverSideVisibilityDetect;
// Low Level Packets
void SendPlaySound(uint32 Sound, bool OnlySelf);
void SendPlayMusic(uint32 Music, bool OnlySelf);
virtual void SetMap(Map* map);

View file

@ -8728,7 +8728,7 @@ void Player::StopCastingCharm()
}
}
void Player::Say(const std::string& text, const uint32 language)
void Player::Say(std::string_view text, Language language, WorldObject const* /*= nullptr*/)
{
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_SAY, language, _text);
@ -8738,11 +8738,16 @@ void Player::Say(const std::string& text, const uint32 language)
#endif
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, Language(language), this, this, _text);
ChatHandler::BuildChatPacket(data, CHAT_MSG_SAY, language, this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true);
}
void Player::Yell(const std::string& text, const uint32 language)
void Player::Say(uint32 textId, WorldObject const* target /*= nullptr*/)
{
Talk(textId, CHAT_MSG_SAY, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), target);
}
void Player::Yell(std::string_view text, Language language, WorldObject const* /*= nullptr*/)
{
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_YELL, language, _text);
@ -8752,11 +8757,16 @@ void Player::Yell(const std::string& text, const uint32 language)
#endif
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, Language(language), this, this, _text);
ChatHandler::BuildChatPacket(data, CHAT_MSG_YELL, language, this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), true);
}
void Player::TextEmote(const std::string& text)
void Player::Yell(uint32 textId, WorldObject const* target /*= nullptr*/)
{
Talk(textId, CHAT_MSG_YELL, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), target);
}
void Player::TextEmote(std::string_view text, WorldObject const* /*= nullptr*/, bool /*= false*/)
{
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_EMOTE, LANG_UNIVERSAL, _text);
@ -8766,68 +8776,79 @@ void Player::TextEmote(const std::string& text)
#endif
WorldPacket data;
std::list<Player*> players;
Acore::AnyPlayerInObjectRangeCheck checker(this, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
Acore::PlayerListSearcher<Acore::AnyPlayerInObjectRangeCheck> searcher(this, players, checker);
Cell::VisitWorldObjects(this, searcher, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE));
for (auto const& itr : players)
{
if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_EMOTE) && this->GetTeamId() != itr->GetTeamId())
{
LocaleConstant loc_idx = itr->GetSession()->GetSessionDbLocaleIndex();
if (BroadcastText const* bct = sObjectMgr->GetBroadcastText(EMOTE_BROADCAST_TEXT_ID_STRANGE_GESTURES))
{
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, bct->GetText(loc_idx, this->getGender()));
itr->SendDirectMessage(&data);
}
}
else
{
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
itr->SendDirectMessage(&data);
}
}
ChatHandler::BuildChatPacket(data, CHAT_MSG_EMOTE, LANG_UNIVERSAL, this, this, _text);
SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), true, !sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHAT));
}
void Player::Whisper(const std::string& text, uint32 language, ObjectGuid receiver)
void Player::TextEmote(uint32 textId, WorldObject const* target /*= nullptr*/, bool /*isBossEmote = false*/)
{
Talk(textId, CHAT_MSG_EMOTE, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), target);
}
void Player::Whisper(std::string_view text, Language language, Player* target, bool /*= false*/)
{
ASSERT(target);
bool isAddonMessage = language == LANG_ADDON;
if (!isAddonMessage) // if not addon data
language = LANG_UNIVERSAL; // whispers should always be readable
Player* rPlayer = ObjectAccessor::FindConnectedPlayer(receiver);
std::string _text(text);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, rPlayer);
sScriptMgr->OnPlayerChat(this, CHAT_MSG_WHISPER, language, _text, target);
#ifdef ELUNA
if (!sEluna->OnChat(this, CHAT_MSG_WHISPER, language, _text, rPlayer))
if (!sEluna->OnChat(this, CHAT_MSG_WHISPER, language, _text, target))
{
return;
}
#endif
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, Language(language), this, this, _text);
rPlayer->GetSession()->SendPacket(&data);
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, language, this, this, _text);
target->GetSession()->SendPacket(&data);
// rest stuff shouldn't happen in case of addon message
if (isAddonMessage)
return;
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER_INFORM, Language(language), rPlayer, rPlayer, _text);
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text);
GetSession()->SendPacket(&data);
if (!isAcceptWhispers() && !IsGameMaster() && !rPlayer->IsGameMaster())
if (!isAcceptWhispers() && !IsGameMaster() && !target->IsGameMaster())
{
SetAcceptWhispers(true);
ChatHandler(GetSession()).SendSysMessage(LANG_COMMAND_WHISPERON);
}
// announce afk or dnd message
if (rPlayer->isAFK())
ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_AFK, rPlayer->GetName().c_str(), rPlayer->autoReplyMsg.c_str());
else if (rPlayer->isDND())
ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_DND, rPlayer->GetName().c_str(), rPlayer->autoReplyMsg.c_str());
if (target->isAFK())
{
ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_AFK, target->GetName().c_str(), target->autoReplyMsg.c_str());
}
else if (target->isDND())
{
ChatHandler(GetSession()).PSendSysMessage(LANG_PLAYER_DND, target->GetName().c_str(), target->autoReplyMsg.c_str());
}
}
void Player::Whisper(uint32 textId, Player* target, bool /*isBossWhisper = false*/)
{
if (!target)
{
return;
}
BroadcastText const* bct = sObjectMgr->GetBroadcastText(textId);
if (!bct)
{
LOG_ERROR("entities.unit", "Player::Whisper: `broadcast_text` was not %u found", textId);
return;
}
LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex();
WorldPacket data;
ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale);
target->SendDirectMessage(&data);
}
void Player::PetSpellInitialize()

View file

@ -1159,10 +1159,18 @@ public:
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
[[nodiscard]] uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
void Say(std::string const& text, const uint32 language);
void Yell(std::string const& text, const uint32 language);
void TextEmote(std::string const& text);
void Whisper(std::string const& text, const uint32 language, ObjectGuid receiver);
/// Handles said message in regular chat based on declared language and in config pre-defined Range.
void Say(std::string_view text, Language language, WorldObject const* = nullptr) override;
void Say(uint32 textId, WorldObject const* target = nullptr) override;
/// Handles yelled message in regular chat based on declared language and in config pre-defined Range.
void Yell(std::string_view text, Language language, WorldObject const* = nullptr) override;
void Yell(uint32 textId, WorldObject const* target = nullptr) override;
/// Outputs an universal text which is supposed to be an action.
void TextEmote(std::string_view text, WorldObject const* = nullptr, bool = false) override;
void TextEmote(uint32 textId, WorldObject const* target = nullptr, bool isBossEmote = false) override;
/// Handles whispers from Addons and players based on sender, receiver's guid and language.
void Whisper(std::string_view text, Language language, Player* receiver, bool = false) override;
void Whisper(uint32 textId, Player* target, bool isBossWhisper = false) override;
/*********************************************************/
/*** STORAGE SYSTEM ***/

View file

@ -21,6 +21,8 @@
#include "BattlefieldMgr.h"
#include "Battleground.h"
#include "CellImpl.h"
#include "Chat.h"
#include "ChatTextBuilder.h"
#include "Common.h"
#include "ConditionMgr.h"
#include "Creature.h"
@ -8788,7 +8790,7 @@ bool Unit::HandleProcTriggerSpell(Unit* victim, uint32 damage, AuraEffect* trigg
if (triggerEntry == nullptr)
{
// Don't cast unknown spell
// LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell %u has 0 in EffectTriggered[%d]. Unhandled custom case?", auraSpellInfo->Id, triggeredByAura->GetEffIndex());
LOG_ERROR("entities.unit", "Unit::HandleProcTriggerSpell: Spell %u (effIndex: %u) has unknown TriggerSpell %u. Unhandled custom case?", auraSpellInfo->Id, triggeredByAura->GetEffIndex(), trigger_spell_id);
return false;
}
@ -20083,3 +20085,88 @@ float Unit::GetCollisionHeight() const
return collisionHeight == 0.0f ? defaultHeight : collisionHeight;
}
void Unit::Talk(std::string_view text, ChatMsg msgType, Language language, float textRange, WorldObject const* target)
{
Acore::CustomChatTextBuilder builder(this, msgType, text, language, target);
Acore::LocalizedPacketDo<Acore::CustomChatTextBuilder> localizer(builder);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::CustomChatTextBuilder> > worker(this, textRange, localizer);
Cell::VisitWorldObjects(this, worker, textRange);
}
void Unit::Say(std::string_view text, Language language, WorldObject const* target /*= nullptr*/)
{
Talk(text, CHAT_MSG_MONSTER_SAY, language, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), target);
}
void Unit::Yell(std::string_view text, Language language, WorldObject const* target /*= nullptr*/)
{
Talk(text, CHAT_MSG_MONSTER_YELL, language, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), target);
}
void Unit::TextEmote(std::string_view text, WorldObject const* target /*= nullptr*/, bool isBossEmote /*= false*/)
{
Talk(text, isBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, LANG_UNIVERSAL, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), target);
}
void Unit::Whisper(std::string_view text, Language language, Player* target, bool isBossWhisper /*= false*/)
{
if (!target)
{
return;
}
LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex();
WorldPacket data;
ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, language, this, target, text, 0, "", locale);
target->SendDirectMessage(&data);
}
void Unit::Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target)
{
if (!sObjectMgr->GetBroadcastText(textId))
{
LOG_ERROR("entities.unit", "Unit::Talk: `broadcast_text` (ID: %u) was not found", textId);
return;
}
Acore::BroadcastTextBuilder builder(this, msgType, textId, getGender(), target);
Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> localizer(builder);
Acore::PlayerDistWorker<Acore::LocalizedPacketDo<Acore::BroadcastTextBuilder> > worker(this, textRange, localizer);
Cell::VisitWorldObjects(this, worker, textRange);
}
void Unit::Say(uint32 textId, WorldObject const* target /*= nullptr*/)
{
Talk(textId, CHAT_MSG_MONSTER_SAY, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), target);
}
void Unit::Yell(uint32 textId, WorldObject const* target /*= nullptr*/)
{
Talk(textId, CHAT_MSG_MONSTER_YELL, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_YELL), target);
}
void Unit::TextEmote(uint32 textId, WorldObject const* target /*= nullptr*/, bool isBossEmote /*= false*/)
{
Talk(textId, isBossEmote ? CHAT_MSG_RAID_BOSS_EMOTE : CHAT_MSG_MONSTER_EMOTE, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_TEXTEMOTE), target);
}
void Unit::Whisper(uint32 textId, Player* target, bool isBossWhisper /*= false*/)
{
if (!target)
{
return;
}
BroadcastText const* bct = sObjectMgr->GetBroadcastText(textId);
if (!bct)
{
LOG_ERROR("entities.unit", "Unit::Whisper: `broadcast_text` was not %u found", textId);
return;
}
LocaleConstant locale = target->GetSession()->GetSessionDbLocaleIndex();
WorldPacket data;
ChatHandler::BuildChatPacket(data, isBossWhisper ? CHAT_MSG_RAID_BOSS_WHISPER : CHAT_MSG_MONSTER_WHISPER, LANG_UNIVERSAL, this, target, bct->GetText(locale, getGender()), 0, "", locale);
target->SendDirectMessage(&data);
}

View file

@ -2502,6 +2502,17 @@ public:
// Movement info
Movement::MoveSpline* movespline;
virtual void Talk(std::string_view text, ChatMsg msgType, Language language, float textRange, WorldObject const* target);
virtual void Say(std::string_view text, Language language, WorldObject const* target = nullptr);
virtual void Yell(std::string_view text, Language language, WorldObject const* target = nullptr);
virtual void TextEmote(std::string_view text, WorldObject const* target = nullptr, bool isBossEmote = false);
virtual void Whisper(std::string_view text, Language language, Player* target, bool isBossWhisper = false);
virtual void Talk(uint32 textId, ChatMsg msgType, float textRange, WorldObject const* target);
virtual void Say(uint32 textId, WorldObject const* target = nullptr);
virtual void Yell(uint32 textId, WorldObject const* target = nullptr);
virtual void TextEmote(uint32 textId, WorldObject const* target = nullptr, bool isBossEmote = false);
virtual void Whisper(uint32 textId, Player* target, bool isBossWhisper = false);
[[nodiscard]] float GetCollisionHeight() const override;
[[nodiscard]] float GetCollisionWidth() const override;
[[nodiscard]] float GetCollisionRadius() const override;

View file

@ -4874,7 +4874,7 @@ void ObjectMgr::LoadScripts(ScriptsType type)
tableName.c_str(), tmp.Talk.ChatType, tmp.id);
continue;
}
if (!tmp.Talk.TextID)
if (!GetBroadcastText(uint32(tmp.Talk.TextID)))
{
LOG_ERROR("sql.sql", "Table `%s` has invalid talk text id (dataint = %i) in SCRIPT_COMMAND_TALK for script id %u",
tableName.c_str(), tmp.Talk.TextID, tmp.id);
@ -5640,7 +5640,7 @@ void ObjectMgr::LoadGossipText()
{
if (gText.Options[i].BroadcastTextID)
{
if (!sObjectMgr->GetBroadcastText(gText.Options[i].BroadcastTextID))
if (!GetBroadcastText(gText.Options[i].BroadcastTextID))
{
LOG_ERROR("sql.sql", "GossipText (Id: %u) in table `npc_text` has non-existing or incompatible BroadcastTextID%u %u.", id, i, gText.Options[i].BroadcastTextID);
gText.Options[i].BroadcastTextID = 0;
@ -8794,7 +8794,7 @@ void ObjectMgr::LoadBroadcastTexts()
BroadcastText bct;
bct.Id = fields[0].GetUInt32();
bct.Language = fields[1].GetUInt32();
bct.LanguageID = fields[1].GetUInt32();
bct.MaleText[DEFAULT_LOCALE] = fields[2].GetString();
bct.FemaleText[DEFAULT_LOCALE] = fields[3].GetString();
bct.EmoteId0 = fields[4].GetUInt32();
@ -8816,10 +8816,10 @@ void ObjectMgr::LoadBroadcastTexts()
}
}
if (!GetLanguageDescByID(bct.Language))
if (!GetLanguageDescByID(bct.LanguageID))
{
LOG_DEBUG("misc", "BroadcastText (Id: %u) in table `broadcast_text` using Language %u but Language does not exist.", bct.Id, bct.Language);
bct.Language = LANG_UNIVERSAL;
LOG_DEBUG("misc", "BroadcastText (Id: %u) in table `broadcast_text` using Language %u but Language does not exist.", bct.Id, bct.LanguageID);
bct.LanguageID = LANG_UNIVERSAL;
}
if (bct.EmoteId0)

View file

@ -439,7 +439,7 @@ struct BroadcastText
}
uint32 Id{0};
uint32 Language{0};
uint32 LanguageID{0};
std::vector<std::string> MaleText;
std::vector<std::string> FemaleText;
uint32 EmoteId0{0};

View file

@ -394,11 +394,11 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
}
if (type == CHAT_MSG_SAY)
sender->Say(msg, lang);
sender->Say(msg, Language(lang));
else if (type == CHAT_MSG_EMOTE)
sender->TextEmote(msg);
else if (type == CHAT_MSG_YELL)
sender->Yell(msg, lang);
sender->Yell(msg, Language(lang));
}
break;
case CHAT_MSG_WHISPER:
@ -442,7 +442,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData)
if (!senderIsPlayer && !sender->isAcceptWhispers() && !sender->IsInWhisperWhiteList(receiver->GetGUID()))
sender->AddWhisperWhiteList(receiver->GetGUID());
GetPlayer()->Whisper(msg, lang, receiver->GetGUID());
GetPlayer()->Whisper(msg, Language(lang), receiver);
}
break;
case CHAT_MSG_PARTY:

View file

@ -21,6 +21,8 @@
enum BroadcastTextIds
{
BROADCAST_TEXT_ACHIEVEMENT_EARNED = 29245,
BROADCAST_TEXT_CALL_FOR_HELP = 2541,
BROADCAST_TEXT_FLEE_FOR_ASSIST = 1150
};
enum AcoreStrings
@ -1142,7 +1144,7 @@ enum AcoreStrings
LANG_BATTLEGROUND = 5015,
LANG_ARENA = 5016,
LANG_RAID = 5017,
//= 5018,
// unused = 5018,
LANG_COMMAND_TEMP_FROZEN_PLAYER = 5019,
LANG_NPCINFO_PHASEMASK = 5020,
LANG_NPCINFO_ARMOR = 5021,
@ -1154,12 +1156,12 @@ enum AcoreStrings
LANG_GOINFO_NAME = 5027,
LANG_GOINFO_LOOTID = 5028,
LANG_COMMAND_LOOKUP_MAX_RESULTS = 5029,
LANG_FLEE = 5030,
// unused = 5030,
LANG_NPCINFO_AIINFO = 5031,
LANG_COMMAND_NO_BATTLEGROUND_FOUND = 5032,
LANG_COMMAND_NO_ACHIEVEMENT_CRITERIA_FOUND = 5033,
LANG_COMMAND_NO_OUTDOOR_PVP_FORUND = 5034,
LANG_CALL_FOR_HELP = 5035,
// unused = 5035,
LANG_NPCINFO_EQUIPMENT = 5036,
LANG_NPCINFO_MECHANIC_IMMUNE = 5037,
LANG_NPCINFO_UNIT_FIELD_FLAGS = 5038,

View file

@ -359,85 +359,59 @@ void Map::ScriptsProcess()
switch (step.script->command)
{
case SCRIPT_COMMAND_TALK:
{
if (step.script->Talk.ChatType > CHAT_TYPE_WHISPER && step.script->Talk.ChatType != CHAT_MSG_RAID_BOSS_WHISPER)
{
LOG_ERROR("maps.script", "%s invalid chat type (%u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->Talk.ChatType);
break;
}
if (step.script->Talk.Flags & SF_TALK_USE_PLAYER)
{
if (Player* player = _GetScriptPlayerSourceOrTarget(source, target, step.script))
{
LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex();
BroadcastText const* broadcastText = sObjectMgr->GetBroadcastText(step.script->Talk.TextID);
std::string text = broadcastText->GetText(loc_idx, player->getGender());
switch (step.script->Talk.ChatType)
{
case CHAT_TYPE_SAY:
player->Say(text, LANG_UNIVERSAL);
break;
case CHAT_TYPE_YELL:
player->Yell(text, LANG_UNIVERSAL);
break;
case CHAT_TYPE_TEXT_EMOTE:
case CHAT_TYPE_BOSS_EMOTE:
player->TextEmote(text);
break;
case CHAT_TYPE_WHISPER:
case CHAT_MSG_RAID_BOSS_WHISPER:
{
ObjectGuid targetGUID = target ? target->GetGUID() : ObjectGuid::Empty;
if (!targetGUID || !targetGUID.IsPlayer())
LOG_ERROR("maps.script", "%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
else
player->Whisper(text, LANG_UNIVERSAL, targetGUID);
break;
}
default:
break; // must be already checked at load
}
}
source = _GetScriptPlayerSourceOrTarget(source, target, step.script);
}
else
{
// Source or target must be Creature.
if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))
source = _GetScriptCreatureSourceOrTarget(source, target, step.script);
}
if (source)
{
Unit* sourceUnit = source->ToUnit();
if (!sourceUnit)
{
ObjectGuid targetGUID = target ? target->GetGUID() : ObjectGuid::Empty;
switch (step.script->Talk.ChatType)
LOG_ERROR("scripts", "%s source object (%s) is not an unit, skipping.", step.script->GetDebugInfo().c_str(), source->GetGUID().ToString().c_str());
break;
}
switch (step.script->Talk.ChatType)
{
case CHAT_TYPE_SAY:
sourceUnit->Say(step.script->Talk.TextID, target);
break;
case CHAT_TYPE_YELL:
sourceUnit->Yell(step.script->Talk.TextID, target);
break;
case CHAT_TYPE_TEXT_EMOTE:
case CHAT_TYPE_BOSS_EMOTE:
sourceUnit->TextEmote(step.script->Talk.TextID, target, step.script->Talk.ChatType == CHAT_TYPE_BOSS_EMOTE);
break;
case CHAT_TYPE_WHISPER:
case CHAT_MSG_RAID_BOSS_WHISPER:
{
case CHAT_TYPE_SAY:
cSource->MonsterSay(step.script->Talk.TextID, LANG_UNIVERSAL, target);
break;
case CHAT_TYPE_YELL:
cSource->MonsterYell(step.script->Talk.TextID, LANG_UNIVERSAL, target);
break;
case CHAT_TYPE_TEXT_EMOTE:
cSource->MonsterTextEmote(step.script->Talk.TextID, target);
break;
case CHAT_TYPE_BOSS_EMOTE:
cSource->MonsterTextEmote(step.script->Talk.TextID, target, true);
break;
case CHAT_TYPE_WHISPER:
if (!targetGUID || !targetGUID.IsPlayer())
LOG_ERROR("maps.script", "%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
else
cSource->MonsterWhisper(step.script->Talk.TextID, target->ToPlayer());
break;
case CHAT_MSG_RAID_BOSS_WHISPER:
if (!targetGUID || !targetGUID.IsPlayer())
LOG_ERROR("maps.script", "%s attempt to raidbosswhisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
else
cSource->MonsterWhisper(step.script->Talk.TextID, target->ToPlayer(), true);
break;
default:
break; // must be already checked at load
Player* receiver = target ? target->ToPlayer() : nullptr;
if (!receiver)
LOG_ERROR("scripts", "%s attempt to whisper to non-player unit, skipping.", step.script->GetDebugInfo().c_str());
else
sourceUnit->Whisper(step.script->Talk.TextID, receiver, step.script->Talk.ChatType == CHAT_MSG_RAID_BOSS_WHISPER);
break;
}
default:
break; // must be already checked at load
}
}
break;
}
case SCRIPT_COMMAND_EMOTE:
// Source or target must be Creature.
if (Creature* cSource = _GetScriptCreatureSourceOrTarget(source, target, step.script))

View file

@ -1,4 +1,4 @@
/*
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
@ -3970,7 +3970,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
if (m_caster->getGender() > 0)
gender = "her";
sprintf(buf, "%s rubs %s [Decahedral Dwarven Dice] between %s hands and rolls. One %u and one %u.", m_caster->GetName().c_str(), gender, gender, urand(1, 10), urand(1, 10));
m_caster->MonsterTextEmote(buf, nullptr);
m_caster->TextEmote(buf);
break;
}
// Roll 'dem Bones - Worn Troll Dice
@ -3981,7 +3981,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
if (m_caster->getGender() > 0)
gender = "her";
sprintf(buf, "%s causually tosses %s [Worn Troll Dice]. One %u and one %u.", m_caster->GetName().c_str(), gender, urand(1, 6), urand(1, 6));
m_caster->MonsterTextEmote(buf, nullptr);
m_caster->TextEmote(buf);
break;
}
// Death Knight Initiate Visual
@ -6392,9 +6392,7 @@ void Spell::EffectPlaySound(SpellEffIndex effIndex)
return;
}
WorldPacket data(SMSG_PLAY_SOUND, 4);
data << uint32(soundId);
unitTarget->ToPlayer()->GetSession()->SendPacket(&data);
player->PlayDirectSound(soundId, player);
}
void Spell::EffectRemoveAura(SpellEffIndex effIndex)

View file

@ -0,0 +1,61 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "ChatTextBuilder.h"
#include "Chat.h"
#include "ObjectMgr.h"
#include <cstdarg>
void Acore::BroadcastTextBuilder::operator()(WorldPacket& data, LocaleConstant locale) const
{
BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId);
ChatHandler::BuildChatPacket(data, _msgType, bct ? Language(bct->LanguageID) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _gender) : "", _achievementId, "", locale);
}
size_t Acore::BroadcastTextBuilder::operator()(WorldPacket* data, LocaleConstant locale) const
{
BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId);
return ChatHandler::BuildChatPacket(*data, _msgType, bct ? Language(bct->LanguageID) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _gender) : "", _achievementId, "", locale);
}
void Acore::CustomChatTextBuilder::operator()(WorldPacket& data, LocaleConstant locale) const
{
ChatHandler::BuildChatPacket(data, _msgType, _language, _source, _target, _text, 0, "", locale);
}
void Acore::AcoreStringChatBuilder::operator()(WorldPacket& data, LocaleConstant locale) const
{
char const* text = sObjectMgr->GetAcoreString(_textId, locale);
if (_args)
{
// we need copy va_list before use or original va_list will corrupted
va_list ap;
va_copy(ap, *_args);
static size_t const BufferSize = 2048;
char strBuffer[BufferSize];
vsnprintf(strBuffer, BufferSize, text, ap);
va_end(ap);
ChatHandler::BuildChatPacket(data, _msgType, LANG_UNIVERSAL, _source, _target, strBuffer, 0, "", locale);
}
else
{
ChatHandler::BuildChatPacket(data, _msgType, LANG_UNIVERSAL, _source, _target, text, 0, "", locale);
}
}

View file

@ -0,0 +1,82 @@
/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __CHATTEXT_BUILDER_H
#define __CHATTEXT_BUILDER_H
#include "Common.h"
#include "SharedDefines.h"
#include <string>
class WorldObject;
class WorldPacket;
namespace Acore
{
class BroadcastTextBuilder
{
public:
BroadcastTextBuilder(WorldObject const* obj, ChatMsg msgType, uint32 textId, uint8 gender, WorldObject const* target = nullptr, uint32 achievementId = 0)
: _source(obj), _msgType(msgType), _textId(textId), _gender(gender), _target(target), _achievementId(achievementId) { }
void operator()(WorldPacket& data, LocaleConstant locale) const;
size_t operator()(WorldPacket* data, LocaleConstant locale) const;
private:
WorldObject const* _source;
ChatMsg _msgType;
uint32 _textId;
uint8 _gender;
WorldObject const* _target;
uint32 _achievementId;
};
class CustomChatTextBuilder
{
public:
CustomChatTextBuilder(WorldObject const* obj, ChatMsg msgType, std::string_view text, Language language = LANG_UNIVERSAL, WorldObject const* target = nullptr)
: _source(obj), _msgType(msgType), _text(text), _language(language), _target(target) { }
void operator()(WorldPacket& data, LocaleConstant locale) const;
private:
WorldObject const* _source;
ChatMsg _msgType;
std::string _text;
Language _language;
WorldObject const* _target;
};
class AcoreStringChatBuilder
{
public:
AcoreStringChatBuilder(WorldObject const* obj, ChatMsg msgType, uint32 textId, WorldObject const* target = nullptr, va_list* args = nullptr)
: _source(obj), _msgType(msgType), _textId(textId), _target(target), _args(args) { }
void operator()(WorldPacket& data, LocaleConstant locale) const;
private:
WorldObject const* _source;
ChatMsg _msgType;
uint32 _textId;
WorldObject const* _target;
va_list* _args;
};
}
// namespace Acore
#endif // __CHATTEXT_BUILDER_H