diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4638669ba9..cc67a2825e 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -12310,6 +12310,28 @@ void Unit::SendPlaySpellVisualKit(uint32 id, uint32 type, uint32 duration) const SendMessageToSet(packet.Write(), IsPlayer()); } +void Unit::SendPlaySpellVisual(uint32 spellVisualId, Unit const* target /*= nullptr*/, Optional targetPosition /*= {}*/, float travelSpeed /*= 0.f*/, uint16 missReason /*= 0*/, uint16 reflectStatus /*= 0*/, bool speedAsTime /*= false*/) const +{ + if (!sSpellVisualStore.LookupEntry(spellVisualId)) + return; + + WorldPackets::Spells::PlaySpellVisual packet; + packet.SpellVisualID = spellVisualId; + packet.Source = GetGUID(); + if (target) + packet.Target = target->GetGUID(); + + if (targetPosition) + packet.TargetPosition = *targetPosition; + + packet.TravelSpeed = travelSpeed; + packet.MissReason = missReason; + packet.ReflectStatus = reflectStatus; + packet.SpeedAsTime = speedAsTime; + + SendMessageToSet(packet.Write(), true); +} + void Unit::CancelSpellMissiles(uint32 spellId, bool reverseMissile /*= false*/) { bool hasMissile = false; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 4ea4640b50..49d4ae82b3 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1113,6 +1113,7 @@ class TC_GAME_API Unit : public WorldObject Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target); void SetAuraStack(uint32 spellId, Unit* target, uint32 stack); void SendPlaySpellVisualKit(uint32 id, uint32 type, uint32 duration) const; + void SendPlaySpellVisual(uint32 spellVisualId, Unit const* target = nullptr, Optional targetPosition = {}, float travelSpeed = 0.f, uint16 missReason = 0, uint16 reflectStatus = 0, bool speedAsTime = false) const; void CancelSpellMissiles(uint32 spellId, bool reverseMissile = false); void DeMorph(); diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index b57ef1d258..6b5204b06c 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -317,6 +317,56 @@ WorldPacket const* WorldPackets::Spells::CategoryCooldown::Write() return &_worldPacket; } +WorldPacket const* WorldPackets::Spells::PlaySpellVisual::Write() +{ + _worldPacket << float(TargetPosition.GetPositionZ()); + _worldPacket << int32(SpellVisualID); + _worldPacket << uint16(MissReason); + _worldPacket << float(TargetPosition.GetOrientation()); + _worldPacket << float(TargetPosition.GetPositionX()); + _worldPacket << uint16(ReflectStatus); + _worldPacket << float(TargetPosition.GetPositionY()); + + _worldPacket.WriteBit(Target[1]); + _worldPacket.WriteBit(Source[3]); + _worldPacket.WriteBit(Source[0]); + _worldPacket.WriteBit(Target[2]); + _worldPacket.WriteBit(Target[5]); + _worldPacket.WriteBit(Source[2]); + _worldPacket.WriteBit(Source[4]); + _worldPacket.WriteBit(Target[6]); + + _worldPacket.WriteBit(SpeedAsTime); + + _worldPacket.WriteBit(Source[6]); + _worldPacket.WriteBit(Target[7]); + _worldPacket.WriteBit(Source[5]); + _worldPacket.WriteBit(Source[1]); + _worldPacket.WriteBit(Source[7]); + _worldPacket.WriteBit(Target[3]); + _worldPacket.WriteBit(Target[4]); + _worldPacket.FlushBits(); + + _worldPacket.WriteByteSeq(Source[7]); + _worldPacket.WriteByteSeq(Source[4]); + _worldPacket.WriteByteSeq(Target[7]); + _worldPacket.WriteByteSeq(Source[1]); + _worldPacket.WriteByteSeq(Source[3]); + _worldPacket.WriteByteSeq(Source[0]); + _worldPacket.WriteByteSeq(Source[6]); + _worldPacket.WriteByteSeq(Target[0]); + _worldPacket.WriteByteSeq(Target[4]); + _worldPacket.WriteByteSeq(Source[5]); + _worldPacket.WriteByteSeq(Target[1]); + _worldPacket.WriteByteSeq(Target[5]); + _worldPacket.WriteByteSeq(Target[6]); + _worldPacket.WriteByteSeq(Target[2]); + _worldPacket.WriteByteSeq(Source[2]); + _worldPacket.WriteByteSeq(Target[3]); + + return &_worldPacket; +} + WorldPacket const* WorldPackets::Spells::PlaySpellVisualKit::Write() { _worldPacket << uint32(Duration); diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index 59f11b353f..783f65cce3 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -263,6 +263,23 @@ namespace WorldPackets uint32 Duration = 0; }; + class PlaySpellVisual final : public ServerPacket + { + public: + PlaySpellVisual() : ServerPacket(SMSG_PLAY_SPELL_VISUAL, 33) { } + + WorldPacket const* Write() override; + + Position TargetPosition; + ObjectGuid Source; + ObjectGuid Target; + int32 SpellVisualID = 0; + float TravelSpeed = 0.0f; + uint16 MissReason = 0; + uint16 ReflectStatus = 0; + bool SpeedAsTime = false; + }; + struct SpellHistoryEntry { SpellHistoryEntry() { } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 21413067cb..16a788a288 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -1123,7 +1123,7 @@ void OpcodeTable::Initialize() DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_OBJECT_SOUND, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_ONE_SHOT_ANIM_KIT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SOUND, STATUS_NEVER, CONNECTION_TYPE_REALM); - DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); + DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_SPELL_VISUAL_KIT, STATUS_NEVER, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PLAY_TIME_WARNING, STATUS_UNHANDLED, CONNECTION_TYPE_REALM); DEFINE_SERVER_OPCODE_HANDLER(SMSG_PONG, STATUS_NEVER, CONNECTION_TYPE_REALM);