aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/server/game/Entities/Creature/Trainer.cpp4
-rw-r--r--src/server/game/Entities/Player/Player.cpp4
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp19
-rw-r--r--src/server/game/Entities/Unit/Unit.h4
-rw-r--r--src/server/game/Guilds/Guild.h1
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp114
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h117
-rw-r--r--src/server/game/Spells/Spell.cpp11
-rw-r--r--src/server/scripts/Outland/BlackTemple/boss_illidan.cpp2
9 files changed, 156 insertions, 120 deletions
diff --git a/src/server/game/Entities/Creature/Trainer.cpp b/src/server/game/Entities/Creature/Trainer.cpp
index 29679993176..e28b86efceb 100644
--- a/src/server/game/Entities/Creature/Trainer.cpp
+++ b/src/server/game/Entities/Creature/Trainer.cpp
@@ -105,8 +105,8 @@ namespace Trainer
player->ModifyMoney(-moneyCost);
- npc->SendPlaySpellVisual(179);
- npc->SendPlaySpellImpact(player->GetGUID(), 362);
+ npc->SendPlaySpellVisualKit(179, 0); // 53 SpellCastDirected
+ player->SendPlaySpellVisualKit(362, 1); // 113 EmoteSalute
// learn explicitly or cast explicitly
if (trainerSpell->IsCastable())
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 497c803a8be..9c928b5fb73 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2016,12 +2016,12 @@ void Player::RegenerateAll()
// Food emote comes above drinking emote if we have to decide (mage regen food for example)
if ((*itr)->GetBase()->HasEffectType(SPELL_AURA_MOD_REGEN) && (*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED)
{
- SendPlaySpellVisual(SPELL_VISUAL_KIT_FOOD);
+ SendPlaySpellVisualKit(SPELL_VISUAL_KIT_FOOD, 0);
break;
}
else if ((*itr)->GetBase()->HasEffectType(SPELL_AURA_MOD_POWER_REGEN) && (*itr)->GetSpellInfo()->AuraInterruptFlags & AURA_INTERRUPT_FLAG_NOT_SEATED)
{
- SendPlaySpellVisual(SPELL_VISUAL_KIT_DRINK);
+ SendPlaySpellVisualKit(SPELL_VISUAL_KIT_DRINK, 0);
break;
}
}
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index af4fcb052d6..f5abdb65ce5 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -70,6 +70,7 @@
#include "SpellInfo.h"
#include "SpellHistory.h"
#include "SpellMgr.h"
+#include "SpellPackets.h"
#include "StringConvert.h"
#include "TemporarySummon.h"
#include "Transport.h"
@@ -12048,20 +12049,12 @@ void Unit::SetAuraStack(uint32 spellId, Unit* target, uint32 stack)
aura->SetStackAmount(stack);
}
-void Unit::SendPlaySpellVisual(uint32 id) const
+void Unit::SendPlaySpellVisualKit(uint32 id, uint32 type) const
{
- WorldPacket data(SMSG_PLAY_SPELL_VISUAL, 8 + 4);
- data << uint64(GetGUID());
- data << uint32(id); // SpellVisualKit.dbc index
- SendMessageToSet(&data, true);
-}
-
-void Unit::SendPlaySpellImpact(ObjectGuid guid, uint32 id) const
-{
- WorldPacket data(SMSG_PLAY_SPELL_IMPACT, 8 + 4);
- data << uint64(guid); // target
- data << uint32(id); // SpellVisualKit.dbc index
- SendMessageToSet(&data, false);
+ WorldPackets::Spells::PlaySpellVisualKit playSpellVisualKit(type);
+ playSpellVisualKit.Unit = GetGUID();
+ playSpellVisualKit.KitRecID = id;
+ SendMessageToSet(playSpellVisualKit.Write(), true);
}
bool Unit::CanApplyResilience() const
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 8bd1618ada0..8f5ce6448ae 100644
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1182,8 +1182,8 @@ class TC_GAME_API Unit : public WorldObject
Aura* AddAura(uint32 spellId, Unit* target);
Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target);
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
- void SendPlaySpellVisual(uint32 id) const;
- void SendPlaySpellImpact(ObjectGuid guid, uint32 id) const;
+
+ void SendPlaySpellVisualKit(uint32 id, uint32 type) const;
void DeMorph();
diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h
index e42d62bab88..26ca49d3b49 100644
--- a/src/server/game/Guilds/Guild.h
+++ b/src/server/game/Guilds/Guild.h
@@ -717,6 +717,7 @@ class TC_GAME_API Guild
bool DeleteMember(CharacterDatabaseTransaction trans, ObjectGuid guid, bool isDisbanding = false, bool isKicked = false);
bool ChangeMemberRank(CharacterDatabaseTransaction trans, ObjectGuid guid, uint8 newRank);
bool IsMember(ObjectGuid guid) const;
+ uint32 GetMembersCount() const { return uint32(m_members.size()); }
uint64 GetMemberAvailableMoneyForRepairItems(ObjectGuid guid) const;
// Bank
diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp
index fa74294b13e..37d38d1da60 100644
--- a/src/server/game/Server/Packets/SpellPackets.cpp
+++ b/src/server/game/Server/Packets/SpellPackets.cpp
@@ -19,46 +19,34 @@
#include "SharedDefines.h"
#include "Spell.h"
#include "SpellInfo.h"
+#include <span>
-void WorldPackets::Spells::CancelCast::Read()
+namespace WorldPackets::Spells
{
- _worldPacket >> CastID;
- _worldPacket >> SpellID;
-}
-
-void WorldPackets::Spells::CancelAura::Read()
-{
- _worldPacket >> SpellID;
-}
-
-void WorldPackets::Spells::PetCancelAura::Read()
+void CancelAura::Read()
{
- _worldPacket >> PetGUID;
_worldPacket >> SpellID;
}
-void WorldPackets::Spells::CancelChannelling::Read()
+void CancelChannelling::Read()
{
_worldPacket >> ChannelSpell;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellMissStatus const& spellMissStatus)
+void PetCancelAura::Read()
{
- data << uint64(spellMissStatus.TargetGUID);
- data << uint8(spellMissStatus.Reason);
- if (spellMissStatus.Reason == SPELL_MISS_REFLECT)
- data << uint8(spellMissStatus.ReflectStatus);
- return data;
+ _worldPacket >> PetGUID;
+ _worldPacket >> SpellID;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::TargetLocation const& targetLocation)
+ByteBuffer& operator<<(ByteBuffer& data, TargetLocation const& targetLocation)
{
data << targetLocation.Transport.WriteAsPacked(); // relative position guid here - transport for example
data << targetLocation.Location.PositionXYZStream();
return data;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellTargetData const& spellTargetData)
+ByteBuffer& operator<<(ByteBuffer& data, SpellTargetData const& spellTargetData)
{
data << uint32(spellTargetData.Flags);
@@ -76,40 +64,52 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellTargetData c
if (spellTargetData.Name)
data << *spellTargetData.Name;
+
+ return data;
+}
+
+ByteBuffer& operator<<(ByteBuffer& data, SpellMissStatus const& spellMissStatus)
+{
+ data << uint64(spellMissStatus.TargetGUID);
+ data << uint8(spellMissStatus.Reason);
+ if (spellMissStatus.Reason == SPELL_MISS_REFLECT)
+ data << uint8(spellMissStatus.ReflectStatus);
+
return data;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::RuneData const& runeData)
+ByteBuffer& operator<<(ByteBuffer& data, RuneData const& runeData)
{
data << uint8(runeData.Start);
data << uint8(runeData.Count);
for (uint8 cooldown : runeData.Cooldowns)
data << uint8(cooldown);
+
return data;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::MissileTrajectoryResult const& traj)
+ByteBuffer& operator<<(ByteBuffer& data, MissileTrajectoryResult const& traj)
{
data << float(traj.Pitch);
data << uint32(traj.TravelTime);
return data;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellAmmo const& spellAmmo)
+ByteBuffer& operator<<(ByteBuffer& data, SpellAmmo const& spellAmmo)
{
data << uint32(spellAmmo.DisplayID);
data << uint32(spellAmmo.InventoryType);
return data;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::CreatureImmunities const& immunities)
+ByteBuffer& operator<<(ByteBuffer& data, CreatureImmunities const& immunities)
{
data << uint32(immunities.School);
data << uint32(immunities.Value);
return data;
}
-ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData const& spellCastData)
+ByteBuffer& operator<<(ByteBuffer& data, SpellCastData const& spellCastData)
{
data << spellCastData.CasterGUID.WriteAsPacked();
data << spellCastData.CasterUnit.WriteAsPacked();
@@ -125,19 +125,16 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData con
// Spells like 40647 (with a huge radius) can easily reach this limit (spell might need
// target conditions but we still need to limit the number of targets sent and keeping
// correct count for both hit and miss).
- static std::size_t const PACKET_TARGET_LIMIT = std::numeric_limits<uint8>::max();
- if (spellCastData.HitTargets->size() > PACKET_TARGET_LIMIT)
- spellCastData.HitTargets->resize(PACKET_TARGET_LIMIT);
-
- data << uint8(spellCastData.HitTargets->size());
- for (ObjectGuid const& target : *spellCastData.HitTargets)
- data << uint64(target);
+ static constexpr std::size_t PACKET_TARGET_LIMIT = std::numeric_limits<uint8>::max();
- if (spellCastData.MissStatus->size() > PACKET_TARGET_LIMIT)
- spellCastData.MissStatus->resize(PACKET_TARGET_LIMIT);
+ std::span<ObjectGuid const> hitTargets(spellCastData.HitTargets->data(), std::min(spellCastData.HitTargets->size(), PACKET_TARGET_LIMIT));
+ data << uint8(hitTargets.size());
+ for (ObjectGuid const& target : hitTargets)
+ data << target;
- data << uint8(spellCastData.MissStatus->size());
- for (WorldPackets::Spells::SpellMissStatus const& status : *spellCastData.MissStatus)
+ std::span<SpellMissStatus const> missTargets(spellCastData.MissStatus->data(), std::min(spellCastData.MissStatus->size(), PACKET_TARGET_LIMIT));
+ data << uint8(missTargets.size());
+ for (SpellMissStatus const& status : missTargets)
data << status;
}
@@ -164,37 +161,66 @@ ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData con
data << uint32(0);
}
- if (spellCastData.Target.Flags & TARGET_FLAG_DEST_LOCATION)
- data << uint8(0);
+ if (spellCastData.DestLocSpellCastIndex)
+ data << uint8(*spellCastData.DestLocSpellCastIndex);
+
+ if (spellCastData.TargetPoints)
+ {
+ data << int32(spellCastData.TargetPoints->size());
+ for (TargetLocation const& targetPoint : *spellCastData.TargetPoints)
+ {
+ data << targetPoint.Location.PositionXYZStream();
+ data << targetPoint.Transport;
+ }
+ }
+
return data;
}
-WorldPacket const* WorldPackets::Spells::SpellGo::Write()
+WorldPacket const* SpellStart::Write()
{
_worldPacket << Cast;
+
return &_worldPacket;
}
-WorldPacket const* WorldPackets::Spells::SpellStart::Write()
+WorldPacket const* SpellGo::Write()
{
_worldPacket << Cast;
+
return &_worldPacket;
}
-WorldPacket const* WorldPackets::Spells::ResyncRunes::Write()
+WorldPacket const* PlaySpellVisualKit::Write()
+{
+ _worldPacket << Unit;
+ _worldPacket << int32(KitRecID);
+
+ return &_worldPacket;
+}
+
+void CancelCast::Read()
+{
+ _worldPacket >> CastID;
+ _worldPacket >> SpellID;
+}
+
+WorldPacket const* ResyncRunes::Write()
{
_worldPacket << Count;
- for (WorldPackets::Spells::ResyncRune const& rune : Runes)
+ for (ResyncRune const& rune : Runes)
{
_worldPacket << rune.RuneType;
_worldPacket << rune.Cooldown;
}
+
return &_worldPacket;
}
-WorldPacket const* WorldPackets::Spells::MountResult::Write()
+WorldPacket const* MountResult::Write()
{
_worldPacket << int32(Result);
return &_worldPacket;
}
+}
diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h
index 764187a4b1e..f714d12f989 100644
--- a/src/server/game/Server/Packets/SpellPackets.h
+++ b/src/server/game/Server/Packets/SpellPackets.h
@@ -28,36 +28,32 @@ namespace WorldPackets
{
namespace Spells
{
- class CancelCast final : public ClientPacket
+ class CancelAura final : public ClientPacket
{
public:
- CancelCast(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_CAST, std::move(packet)) { }
+ CancelAura(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_AURA, std::move(packet)) { }
void Read() override;
- uint8 CastID = 0;
uint32 SpellID = 0;
};
- class CancelAura final : public ClientPacket
+ class CancelAutoRepeatSpell final : public ClientPacket
{
public:
- CancelAura(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_AURA, std::move(packet)) { }
-
- void Read() override;
+ CancelAutoRepeatSpell(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_AUTO_REPEAT_SPELL, std::move(packet)) { }
- uint32 SpellID = 0;
+ void Read() override { }
};
- class PetCancelAura final : public ClientPacket
+ class CancelChannelling final : public ClientPacket
{
public:
- PetCancelAura(WorldPacket&& packet) : ClientPacket(CMSG_PET_CANCEL_AURA, std::move(packet)) { }
+ CancelChannelling(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_CHANNELLING, std::move(packet)) { }
void Read() override;
- ObjectGuid PetGUID;
- uint32 SpellID = 0;
+ uint32 ChannelSpell = 0;
};
class CancelGrowthAura final : public ClientPacket
@@ -76,22 +72,31 @@ namespace WorldPackets
void Read() override { }
};
- class CancelAutoRepeatSpell final : public ClientPacket
+ class PetCancelAura final : public ClientPacket
{
public:
- CancelAutoRepeatSpell(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_AUTO_REPEAT_SPELL, std::move(packet)) { }
+ PetCancelAura(WorldPacket&& packet) : ClientPacket(CMSG_PET_CANCEL_AURA, std::move(packet)) { }
- void Read() override { }
+ void Read() override;
+
+ ObjectGuid PetGUID;
+ uint32 SpellID = 0;
};
- class CancelChannelling final : public ClientPacket
+ struct TargetLocation
{
- public:
- CancelChannelling(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_CHANNELLING, std::move(packet)) { }
-
- void Read() override;
+ ObjectGuid Transport;
+ Position Location;
+ };
- uint32 ChannelSpell = 0;
+ struct SpellTargetData
+ {
+ uint32 Flags = 0;
+ Optional<ObjectGuid> Unit;
+ Optional<ObjectGuid> Item;
+ Optional<TargetLocation> SrcLocation;
+ Optional<TargetLocation> DstLocation;
+ Optional<std::string> Name;
};
struct SpellMissStatus
@@ -126,22 +131,6 @@ namespace WorldPackets
uint32 Value = 0;
};
- struct TargetLocation
- {
- ObjectGuid Transport;
- Position Location;
- };
-
- struct SpellTargetData
- {
- uint32 Flags = 0;
- Optional<ObjectGuid> Unit;
- Optional<ObjectGuid> Item;
- Optional<TargetLocation> SrcLocation;
- Optional<TargetLocation> DstLocation;
- Optional<std::string> Name;
- };
-
struct SpellCastData
{
ObjectGuid CasterGUID;
@@ -150,38 +139,62 @@ namespace WorldPackets
uint32 SpellID = 0;
uint32 CastFlags = 0;
uint32 CastTime = 0;
- mutable Optional<std::vector<ObjectGuid>> HitTargets;
- mutable Optional<std::vector<SpellMissStatus>> MissStatus;
+ Optional<std::vector<ObjectGuid>> HitTargets;
+ Optional<std::vector<SpellMissStatus>> MissStatus;
SpellTargetData Target;
Optional<uint32> RemainingPower;
Optional<RuneData> RemainingRunes;
Optional<MissileTrajectoryResult> MissileTrajectory;
Optional<SpellAmmo> Ammo;
+ Optional<uint8> DestLocSpellCastIndex;
+ Optional<std::vector<TargetLocation>> TargetPoints;
Optional<CreatureImmunities> Immunities;
};
+ class SpellStart final : public ServerPacket
+ {
+ public:
+ SpellStart() : ServerPacket(SMSG_SPELL_START) { }
+
+ WorldPacket const* Write() override;
+
+ SpellCastData Cast;
+ };
+
class SpellGo final : public ServerPacket
{
- public:
- SpellGo() : ServerPacket(SMSG_SPELL_GO)
- {
- Cast.HitTargets.emplace();
- Cast.MissStatus.emplace();
- }
+ public:
+ SpellGo() : ServerPacket(SMSG_SPELL_GO)
+ {
+ Cast.HitTargets.emplace();
+ Cast.MissStatus.emplace();
+ }
- WorldPacket const* Write() override;
+ WorldPacket const* Write() override;
- SpellCastData Cast;
+ SpellCastData Cast;
};
- class SpellStart final : public ServerPacket
+ class PlaySpellVisualKit final : public ServerPacket
{
- public:
- SpellStart() : ServerPacket(SMSG_SPELL_START) { }
+ public:
+ PlaySpellVisualKit(int32 kitType) : ServerPacket(kitType ? SMSG_PLAY_SPELL_IMPACT : SMSG_PLAY_SPELL_VISUAL, 8 + 4) { }
- WorldPacket const* Write() override;
+ WorldPacket const* Write() override;
- SpellCastData Cast;
+ ObjectGuid Unit;
+ int32 KitRecID = 0;
+ };
+
+ class CancelCast final : public ClientPacket
+ {
+ public:
+ CancelCast(WorldPacket&& packet) : ClientPacket(CMSG_CANCEL_CAST, std::move(packet)) { }
+
+ void Read() override;
+
+ uint8 CastID = 0;
+ uint32 SpellID = 0;
};
struct ResyncRune
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index f1a90646117..60fb89a4bf0 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -4372,10 +4372,13 @@ void Spell::SendSpellGo()
}
if (castFlags & CAST_FLAG_AMMO)
- {
- castData.Ammo.emplace();
- UpdateSpellCastDataAmmo(*castData.Ammo);
- }
+ UpdateSpellCastDataAmmo(castData.Ammo.emplace());
+
+ if (m_targets.GetTargetMask() & TARGET_FLAG_DEST_LOCATION)
+ castData.DestLocSpellCastIndex.emplace();
+
+ if (m_targets.GetTargetMask() & TARGET_FLAG_UNUSED20)
+ castData.TargetPoints.emplace();
// should be sent to self only
if (castFlags & CAST_FLAG_POWER_LEFT_SELF && m_caster->IsPlayer())
diff --git a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
index 60812545908..1255bfc4dbd 100644
--- a/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
+++ b/src/server/scripts/Outland/BlackTemple/boss_illidan.cpp
@@ -2062,7 +2062,7 @@ class spell_illidan_return_glaives : public SpellScript
void HandleScriptEffect(SpellEffIndex /*effIndex*/)
{
- GetHitUnit()->SendPlaySpellVisual(SPELL_GLAIVE_VISUAL_KIT);
+ GetHitUnit()->SendPlaySpellVisualKit(SPELL_GLAIVE_VISUAL_KIT, 0);
if (Creature* caster = GetCaster()->ToCreature())
caster->DespawnOrUnsummon();
}