/* * Copyright (C) 2008-2015 TrinityCore * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 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 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 . */ #include "SpellPackets.h" #include "SpellAuraEffects.h" #include "MovementPackets.h" void WorldPackets::Spells::CancelAura::Read() { _worldPacket >> SpellID; _worldPacket >> CasterGUID; } WorldPacket const* WorldPackets::Spells::CategoryCooldown::Write() { _worldPacket.reserve(4 + 8 * CategoryCooldowns.size()); _worldPacket << uint32(CategoryCooldowns.size()); for (CategoryCooldownInfo const& cooldown : CategoryCooldowns) { _worldPacket << uint32(cooldown.Category); _worldPacket << int32(cooldown.ModCooldown); } return &_worldPacket; } WorldPacket const* WorldPackets::Spells::SendKnownSpells::Write() { _worldPacket.reserve(1 + 4 * KnownSpells.size()); _worldPacket.WriteBit(InitialLogin); _worldPacket << uint32(KnownSpells.size()); for (uint32 spellId : KnownSpells) _worldPacket << uint32(spellId); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::UpdateActionButtons::Write() { for (uint32 i = 0; i < MAX_ACTION_BUTTONS; ++i) _worldPacket << ActionButtons[i]; _worldPacket << Reason; return &_worldPacket; } void WorldPackets::Spells::SetActionButton::Read() { _worldPacket >> Action; _worldPacket >> Index; } WorldPacket const* WorldPackets::Spells::SendUnlearnSpells::Write() { _worldPacket << uint32(Spells.size()); for (uint32 spellId : Spells) _worldPacket << uint32(spellId); return &_worldPacket; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastLogData const& spellCastLogData) { data << spellCastLogData.Health; data << spellCastLogData.AttackPower; data << spellCastLogData.SpellPower; data << int32(spellCastLogData.PowerData.size()); for (WorldPackets::Spells::SpellLogPowerData const& powerData : spellCastLogData.PowerData) { data << powerData.PowerType; data << powerData.Amount; } data.WriteBit(false); // data << float // Unk data if bit is true data.FlushBits(); return data; } WorldPacket const* WorldPackets::Spells::AuraUpdate::Write() { _worldPacket.WriteBit(UpdateAll); _worldPacket << UnitGUID; _worldPacket << uint32(Auras.size()); for (auto& aura : Auras) { _worldPacket << aura.Slot; if (_worldPacket.WriteBit(aura.AuraData.HasValue)) { AuraDataInfo const& data = aura.AuraData.Value; _worldPacket << uint32(data.SpellID); _worldPacket << uint8(data.Flags); _worldPacket << uint32(data.ActiveFlags); _worldPacket << uint16(data.CastLevel); _worldPacket << uint8(data.Applications); _worldPacket << uint32(data.Points.size()); _worldPacket << uint32(data.EstimatedPoints.size()); if (!data.Points.empty()) _worldPacket.append(data.Points.data(), data.Points.size()); if (!data.EstimatedPoints.empty()) _worldPacket.append(data.EstimatedPoints.data(), data.EstimatedPoints.size()); _worldPacket.WriteBit(data.CastUnit.HasValue); _worldPacket.WriteBit(data.Duration.HasValue); _worldPacket.WriteBit(data.Remaining.HasValue); if (data.CastUnit.HasValue) _worldPacket << data.CastUnit.Value; if (data.Duration.HasValue) _worldPacket << uint32(data.Duration.Value); if (data.Remaining.HasValue) _worldPacket << uint32(data.Remaining.Value); } _worldPacket.FlushBits(); } return &_worldPacket; } ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::TargetLocation& location) { buffer >> location.Transport; buffer >> location.Location.m_positionX; buffer >> location.Location.m_positionY; buffer >> location.Location.m_positionZ; return buffer; } ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellTargetData& targetData) { buffer.ResetBitPos(); targetData.Flags = buffer.ReadBits(23); targetData.SrcLocation.HasValue = buffer.ReadBit(); targetData.DstLocation.HasValue = buffer.ReadBit(); targetData.Orientation.HasValue = buffer.ReadBit(); uint32 nameLength = buffer.ReadBits(7); buffer >> targetData.Unit; buffer >> targetData.Item; if (targetData.SrcLocation.HasValue) buffer >> targetData.SrcLocation.Value; if (targetData.DstLocation.HasValue) buffer >> targetData.DstLocation.Value; if (targetData.Orientation.HasValue) buffer >> targetData.Orientation.Value; targetData.Name = buffer.ReadString(nameLength); return buffer; } ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::MissileTrajectoryRequest& trajectory) { buffer >> trajectory.Pitch; buffer >> trajectory.Speed; return buffer; } ByteBuffer& operator>>(ByteBuffer& buffer, WorldPackets::Spells::SpellCastRequest& request) { buffer >> request.CastID; buffer >> request.SpellID; buffer >> request.Misc; buffer >> request.Target; buffer >> request.MissileTrajectory; buffer >> request.Charmer; buffer.ResetBitPos(); request.SendCastFlags = buffer.ReadBits(5); request.MoveUpdate.HasValue = buffer.ReadBit(); request.Weight.resize(buffer.ReadBits(2)); if (request.MoveUpdate.HasValue) buffer >> request.MoveUpdate.Value; for (WorldPackets::Spells::SpellWeight& weight : request.Weight) { buffer.ResetBitPos(); weight.Type = buffer.ReadBits(2); buffer >> weight.ID; buffer >> weight.Quantity; } return buffer; } void WorldPackets::Spells::CastSpell::Read() { _worldPacket >> Cast; } void WorldPackets::Spells::PetCastSpell::Read() { _worldPacket >> PetGUID; _worldPacket >> Cast; } void WorldPackets::Spells::UseItem::Read() { _worldPacket >> PackSlot; _worldPacket >> Slot; _worldPacket >> CastItem; _worldPacket >> Cast; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::TargetLocation const& targetLocation) { data << targetLocation.Transport; data << float(targetLocation.Location.m_positionX); data << float(targetLocation.Location.m_positionY); data << float(targetLocation.Location.m_positionZ); return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellTargetData const& spellTargetData) { data.WriteBits(spellTargetData.Flags, 23); data.WriteBit(spellTargetData.SrcLocation.HasValue); data.WriteBit(spellTargetData.DstLocation.HasValue); data.WriteBit(spellTargetData.Orientation.HasValue); data.WriteBits(spellTargetData.Name.size(), 7); data.FlushBits(); data << spellTargetData.Unit; data << spellTargetData.Item; if (spellTargetData.SrcLocation.HasValue) data << spellTargetData.SrcLocation.Value; if (spellTargetData.DstLocation.HasValue) data << spellTargetData.DstLocation.Value; if (spellTargetData.Orientation.HasValue) data << spellTargetData.Orientation.Value; data.WriteString(spellTargetData.Name); return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellMissStatus const& spellMissStatus) { data.WriteBits(spellMissStatus.Reason, 4); data.WriteBits(spellMissStatus.ReflectStatus, 4); // No need to flush bits as we written exactly 8 bits (1 byte) return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellPowerData const& spellPowerData) { data << int32(spellPowerData.Cost); data << int8(spellPowerData.Type); return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::RuneData const& runeData) { data << uint8(runeData.Start); data << uint8(runeData.Count); data.WriteBits(runeData.Cooldowns.size(), 3); data.FlushBits(); for (uint8 cd : runeData.Cooldowns) data << cd; return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::MissileTrajectoryResult const& missileTrajectory) { data << uint32(missileTrajectory.TravelTime); data << float(missileTrajectory.Pitch); return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellAmmo const& spellAmmo) { data << int32(spellAmmo.DisplayID); data << int8(spellAmmo.InventoryType); return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::ProjectileVisualData const& projectileVisual) { data << int32(projectileVisual.ID[0]); data << int32(projectileVisual.ID[1]); return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::CreatureImmunities const& immunities) { data << int32(immunities.School); data << int32(immunities.Value); return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHealPrediction const& spellPred) { data << int32(spellPred.Points); data << uint8(spellPred.Type); data << spellPred.BeaconGUID; return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCastData const& spellCastData) { data << spellCastData.CasterGUID; data << spellCastData.CasterUnit; data << uint8(spellCastData.CastID); data << int32(spellCastData.SpellID); data << uint32(spellCastData.CastFlags); data << uint32(spellCastData.CastTime); data << uint32(spellCastData.HitTargets.size()); data << uint32(spellCastData.MissTargets.size()); data << uint32(spellCastData.MissStatus.size()); data << spellCastData.Target; data << uint32(spellCastData.RemainingPower.size()); data << spellCastData.MissileTrajectory; data << spellCastData.Ammo; data << uint8(spellCastData.DestLocSpellCastIndex); data << uint32(spellCastData.TargetPoints.size()); data << spellCastData.Immunities; data << spellCastData.Predict; for (ObjectGuid const& target : spellCastData.HitTargets) data << target; for (ObjectGuid const& target : spellCastData.MissTargets) data << target; for (WorldPackets::Spells::SpellMissStatus const& status : spellCastData.MissStatus) data << status; for (WorldPackets::Spells::SpellPowerData const& power : spellCastData.RemainingPower) data << power; for (WorldPackets::Spells::TargetLocation const& targetLoc : spellCastData.TargetPoints) data << targetLoc; data.WriteBits(spellCastData.CastFlagsEx, 18); data.WriteBit(spellCastData.RemainingRunes.HasValue); data.WriteBit(spellCastData.ProjectileVisual.HasValue); data.FlushBits(); if (spellCastData.RemainingRunes.HasValue) data << spellCastData.RemainingRunes.Value; if (spellCastData.ProjectileVisual.HasValue) data << spellCastData.ProjectileVisual.Value; return data; } WorldPacket const* WorldPackets::Spells::SpellStart::Write() { _worldPacket << Cast; return &_worldPacket; } WorldPacket const* WorldPackets::Spells::SpellGo::Write() { _worldPacket << Cast; _worldPacket.WriteBit(LogData.HasValue); _worldPacket.FlushBits(); if (LogData.HasValue) _worldPacket << LogData.Value; return &_worldPacket; } WorldPacket const* WorldPackets::Spells::LearnedSpells::Write() { _worldPacket << uint32(SpellID.size()); for (int32 spell : SpellID) _worldPacket << spell; _worldPacket.WriteBit(SuppressMessaging); _worldPacket.FlushBits(); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::SpellFailure::Write() { _worldPacket << CasterUnit; _worldPacket << uint8(CastID); _worldPacket << int32(SpellID); _worldPacket << uint16(Reason); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::SpellFailedOther::Write() { _worldPacket << CasterUnit; _worldPacket << uint8(CastID); _worldPacket << uint32(SpellID); _worldPacket << uint8(Reason); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::CastFailed::Write() { _worldPacket << int32(SpellID); _worldPacket << int32(Reason); _worldPacket << int32(FailedArg1); _worldPacket << int32(FailedArg2); _worldPacket << uint8(CastID); return &_worldPacket; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifierData const& spellModifierData) { data << float(spellModifierData.ModifierValue); data << uint8(spellModifierData.ClassIndex); return data; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellModifier const& spellModifier) { data << uint8(spellModifier.ModIndex); data << uint32(spellModifier.ModifierData.size()); for (WorldPackets::Spells::SpellModifierData const& modData : spellModifier.ModifierData) data << modData; return data; } WorldPacket const* WorldPackets::Spells::SetSpellModifier::Write() { _worldPacket << uint32(Modifiers.size()); for (WorldPackets::Spells::SpellModifier const& spellMod : Modifiers) _worldPacket << spellMod; return &_worldPacket; } WorldPacket const* WorldPackets::Spells::UnlearnedSpells::Write() { _worldPacket << uint32(SpellID.size()); for (uint32 spellId : SpellID) _worldPacket << uint32(spellId); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::CooldownEvent::Write() { _worldPacket << CasterGUID; _worldPacket << int32(SpellID); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::ClearCooldowns::Write() { _worldPacket << Guid; _worldPacket << uint32(SpellID.size()); if (!SpellID.empty()) _worldPacket.append(SpellID.data(), SpellID.size()); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::ClearCooldown::Write() { _worldPacket << CasterGUID; _worldPacket << uint32(SpellID); _worldPacket.WriteBit(ClearOnHold); _worldPacket.FlushBits(); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::ModifyCooldown::Write() { _worldPacket << int32(SpellID); _worldPacket << UnitGUID; _worldPacket << int32(DeltaTime); return &_worldPacket; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellCooldownStruct const& cooldown) { data << uint32(cooldown.SrecID); data << uint32(cooldown.ForcedCooldown); return data; } WorldPacket const* WorldPackets::Spells::SpellCooldown::Write() { _worldPacket << Caster; _worldPacket << uint8(Flags); _worldPacket << uint32(SpellCooldowns.size()); for (SpellCooldownStruct const& cooldown : SpellCooldowns) _worldPacket << cooldown; return &_worldPacket; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellHistoryEntry const& historyEntry) { data << uint32(historyEntry.SpellID); data << uint32(historyEntry.ItemID); data << uint32(historyEntry.Category); data << int32(historyEntry.RecoveryTime); data << int32(historyEntry.CategoryRecoveryTime); data.WriteBit(historyEntry.OnHold); data.FlushBits(); return data; } WorldPacket const* WorldPackets::Spells::SendSpellHistory::Write() { _worldPacket << uint32(Entries.size()); for (SpellHistoryEntry const& historyEntry : Entries) _worldPacket << historyEntry; return &_worldPacket; } WorldPacket const* WorldPackets::Spells::ClearAllSpellCharges::Write() { _worldPacket << Unit; return &_worldPacket; } WorldPacket const* WorldPackets::Spells::ClearSpellCharges::Write() { _worldPacket << Unit; _worldPacket << int32(Category); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::SetSpellCharges::Write() { _worldPacket << int32(Category); _worldPacket << float(Count); _worldPacket.WriteBit(IsPet); _worldPacket.FlushBits(); return &_worldPacket; } ByteBuffer& operator<<(ByteBuffer& data, WorldPackets::Spells::SpellChargeEntry const& chargeEntry) { data << uint32(chargeEntry.Category); data << uint32(chargeEntry.NextRecoveryTime); data << uint8(chargeEntry.ConsumedCharges); return data; } WorldPacket const* WorldPackets::Spells::SendSpellCharges::Write() { _worldPacket << uint32(Entries.size()); for (SpellChargeEntry const& chargeEntry : Entries) _worldPacket << chargeEntry; return &_worldPacket; } WorldPacket const* WorldPackets::Spells::ClearTarget::Write() { _worldPacket << Guid; return &_worldPacket; } WorldPacket const* WorldPackets::Spells::CancelOrphanSpellVisual::Write() { _worldPacket << int32(SpellVisualID); return &_worldPacket; } WorldPacket const* WorldPackets::Spells::CancelSpellVisual::Write() { _worldPacket << Source; _worldPacket << int32(SpellVisualID); return &_worldPacket; } void WorldPackets::Spells::CancelCast::Read() { _worldPacket >> SpellID; _worldPacket >> CastID; } void WorldPackets::Spells::OpenItem::Read() { _worldPacket >> Slot >> PackSlot; }