From 6407b24a032dd8ea8f6fbf15569fb6439662a101 Mon Sep 17 00:00:00 2001 From: Yaki Khadafi Date: Tue, 14 Aug 2012 14:40:00 +0300 Subject: [PATCH] [0086] Updated CMSG_SPELL_CAST, CMSG_USE_ITEM, CMSG_PET_SPELL_CAST, SMSG_SPELL_START, SMSG_SPELL_GO and some other spell opcodes --- src/game/MovementStructures.h | 76 +++++++++++++++++++++ src/game/Opcodes.cpp | 16 ++--- src/game/Opcodes.h | 16 ++--- src/game/PetHandler.cpp | 8 ++- src/game/Spell.cpp | 120 ++++++++++++++++++++++++++-------- src/game/Spell.h | 17 ++++- src/game/SpellHandler.cpp | 39 ++++------- src/shared/revision_nr.h | 2 +- 8 files changed, 217 insertions(+), 77 deletions(-) diff --git a/src/game/MovementStructures.h b/src/game/MovementStructures.h index 2caadc241..73109b9c3 100644 --- a/src/game/MovementStructures.h +++ b/src/game/MovementStructures.h @@ -2109,10 +2109,86 @@ MovementStatusElements MovementSetCanFlyAckSequence[] = MSEEnd, }; +MovementStatusElements MovementCastSpellSequence[] = +{ + MSEPositionZ, + MSEPositionY, + MSEPositionX, + MSEHasFallData, + MSEHasTimestamp, + MSEHasOrientation, + MSEHasSpline, + MSEHasUnknownBit, + MSEGuidBit6, + MSEGuidBit4, + MSEHasMovementFlags2, + MSEGuidBit3, + MSEGuidBit5, + MSEHasSplineElevation, + MSEHasPitch, + MSEGuidBit7, + MSEHasTransportData, + MSEGuidBit2, + MSEHasMovementFlags, + MSEGuidBit1, + MSEGuidBit0, + MSETransportGuidBit6, + MSETransportGuidBit2, + MSETransportGuidBit5, + MSEHasTransportTime2, + MSETransportGuidBit7, + MSETransportGuidBit4, + MSEHasTransportTime3, + MSETransportGuidBit0, + MSETransportGuidBit1, + MSETransportGuidBit3, + MSEFlags2, + MSEFlags, + MSEHasFallDirection, + MSEGuidByte1, + MSEGuidByte4, + MSEGuidByte7, + MSEGuidByte3, + MSEGuidByte0, + MSEGuidByte2, + MSEGuidByte5, + MSEGuidByte6, + MSETransportSeat, + MSETransportPositionO, + MSETransportTime, + MSETransportGuidByte6, + MSETransportGuidByte5, + MSETransportTime3, + MSETransportPositionX, + MSETransportGuidByte4, + MSETransportPositionZ, + MSETransportGuidByte2, + MSETransportGuidByte0, + MSETransportTime2, + MSETransportGuidByte1, + MSETransportGuidByte3, + MSETransportPositionY, + MSETransportGuidByte7, + MSEPositionO, + MSESplineElevation, + MSEFallTime, + MSEFallHorizontalSpeed, + MSEFallCosAngle, + MSEFallSinAngle, + MSEFallVerticalSpeed, + MSETimestamp, + MSEPitch, + MSEEnd, +}; + MovementStatusElements* GetMovementStatusElementsSequence(uint16 opcode) { switch(opcode) { + case CMSG_CAST_SPELL: + case CMSG_PET_CAST_SPELL: + case CMSG_USE_ITEM: + return MovementCastSpellSequence; case CMSG_MOVE_CHNG_TRANSPORT: return MovementChngTransportSequence; case CMSG_MOVE_FALL_LAND: diff --git a/src/game/Opcodes.cpp b/src/game/Opcodes.cpp index bd530707a..937c481d8 100644 --- a/src/game/Opcodes.cpp +++ b/src/game/Opcodes.cpp @@ -234,7 +234,7 @@ void InitializeOpcodes() //OPCODE(CMSG_CHANNEL_MODERATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerateOpcode ); OPCODE(SMSG_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_DESTROY_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //OPCODE(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode ); + OPCODE(CMSG_USE_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleUseItemOpcode ); //OPCODE(CMSG_OPEN_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode ); //OPCODE(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItemOpcode ); //OPCODE(SMSG_READ_ITEM_OK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); @@ -374,15 +374,15 @@ void InitializeOpcodes() OPCODE(SMSG_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); OPCODE(SMSG_SUPERCEDED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(CMSG_NEW_SPELL_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //OPCODE(CMSG_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode ); - //OPCODE(CMSG_CANCEL_CAST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode ); - //OPCODE(SMSG_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //OPCODE(SMSG_SPELL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //OPCODE(SMSG_SPELL_GO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + OPCODE(CMSG_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode ); + OPCODE(CMSG_CANCEL_CAST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode ); + OPCODE(SMSG_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + OPCODE(SMSG_SPELL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); + OPCODE(SMSG_SPELL_GO, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_SPELL_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_SPELL_COOLDOWN, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_COOLDOWN_EVENT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); - //OPCODE(CMSG_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode ); + OPCODE(CMSG_CANCEL_AURA, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleCancelAuraOpcode ); //OPCODE(SMSG_EQUIPMENT_SET_ID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_PET_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(MSG_CHANNEL_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); @@ -565,7 +565,7 @@ void InitializeOpcodes() //OPCODE(SMSG_ITEM_TIME_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(SMSG_ITEM_ENCHANT_TIME_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); //OPCODE(MSG_GM_SHOWLABEL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL ); - //OPCODE(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCastSpellOpcode ); + OPCODE(CMSG_PET_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandlePetCastSpellOpcode ); //OPCODE(MSG_SAVE_GUILD_EMBLEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode ); //OPCODE(MSG_TABARDVENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode); OPCODE(SMSG_PLAY_SPELL_VISUAL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide ); diff --git a/src/game/Opcodes.h b/src/game/Opcodes.h index dd4ccd1dc..31ca1f95c 100644 --- a/src/game/Opcodes.h +++ b/src/game/Opcodes.h @@ -228,7 +228,7 @@ enum Opcodes CMSG_CHANNEL_MODERATE = 0x10A9, SMSG_UPDATE_OBJECT = 0x4715, // 4.3.4 15595 SMSG_DESTROY_OBJECT = 0x4724, // 4.3.4 15595 - CMSG_USE_ITEM = 0x10AC, + CMSG_USE_ITEM = 0x2C06, // 4.3.4 15595 CMSG_OPEN_ITEM = 0x10AD, CMSG_READ_ITEM = 0x10AE, SMSG_READ_ITEM_OK = 0x10AF, @@ -359,15 +359,15 @@ enum Opcodes SMSG_LEARNED_SPELL = 0x58A2, // 4.3.4 15595 SMSG_SUPERCEDED_SPELL = 0x35B0, // 4.3.4 15595 CMSG_NEW_SPELL_SLOT = 0x112E, - CMSG_CAST_SPELL = 0x112F, - CMSG_CANCEL_CAST = 0x1130, - SMSG_CAST_FAILED = 0x1131, - SMSG_SPELL_START = 0x1132, - SMSG_SPELL_GO = 0x1133, + CMSG_CAST_SPELL = 0x4C07, // 4.3.4 15595 + CMSG_CANCEL_CAST = 0x0115, // 4.3.4 15595 + SMSG_CAST_FAILED = 0x4D16, // 4.3.4 15595 + SMSG_SPELL_START = 0x6415, // 4.3.4 15595 + SMSG_SPELL_GO = 0x6E16, // 4.3.4 15595 SMSG_SPELL_FAILURE = 0x1134, SMSG_SPELL_COOLDOWN = 0x1135, SMSG_COOLDOWN_EVENT = 0x1136, - CMSG_CANCEL_AURA = 0x1137, + CMSG_CANCEL_AURA = 0x0E26, // 4.3.4 15595 SMSG_EQUIPMENT_SET_ID = 0x1138, SMSG_PET_CAST_FAILED = 0x1139, MSG_CHANNEL_START = 0x113A, @@ -550,7 +550,7 @@ enum Opcodes SMSG_ITEM_TIME_UPDATE = 0x11EB, SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x11EC, MSG_GM_SHOWLABEL = 0x11F0, - CMSG_PET_CAST_SPELL = 0x11F1, + CMSG_PET_CAST_SPELL = 0x6337, // 4.3.4 15595 MSG_SAVE_GUILD_EMBLEM = 0x11F2, MSG_TABARDVENDOR_ACTIVATE = 0x11F3, SMSG_PLAY_SPELL_VISUAL = 0x55A5, // 4.3.4 15595 diff --git a/src/game/PetHandler.cpp b/src/game/PetHandler.cpp index d3a50139f..f789a2e5d 100644 --- a/src/game/PetHandler.cpp +++ b/src/game/PetHandler.cpp @@ -633,11 +633,11 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) ObjectGuid guid; uint32 spellid; uint8 cast_count; - uint8 unk_flags; // flags (if 0x02 - some additional data are received) + uint8 cast_flags; // flags (if 0x02 - some additional data are received) - recvPacket >> guid >> cast_count >> spellid >> unk_flags; + recvPacket >> guid >> cast_count >> spellid >> cast_flags; - DEBUG_LOG("WORLD: CMSG_PET_CAST_SPELL, %s, cast_count: %u, spellid %u, unk_flags %u", guid.GetString().c_str(), cast_count, spellid, unk_flags); + DEBUG_LOG("WORLD: CMSG_PET_CAST_SPELL, %s, cast_count: %u, spellid %u, cast_flags %u", guid.GetString().c_str(), cast_count, spellid, cast_flags); Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid); @@ -666,6 +666,8 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) recvPacket >> targets.ReadForCaster(pet); + targets.ReadAdditionalData(recvPacket, cast_flags); + pet->clearUnitState(UNIT_STAT_MOVING); Spell* spell = new Spell(pet, spellInfo, false); diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp index 7a3d7f7c8..29bcdd6c5 100644 --- a/src/game/Spell.cpp +++ b/src/game/Spell.cpp @@ -314,6 +314,43 @@ void SpellCastTargets::write(ByteBuffer& data) const data << m_strTarget; } +void SpellCastTargets::ReadAdditionalData(WorldPacket& data, uint8& cast_flags) +{ + if (cast_flags & 0x02) // has trajectory data + { + data >> m_elevation >> m_speed; + + bool hasMovementData; + data >> hasMovementData; + if (hasMovementData) + { + MovementInfo mi; + data >> mi; + } + } + else if (cast_flags & 0x08) // has archaeology weight + { + uint32 count; + uint8 type; + data >> count; + for (uint32 i = 0; i < count; ++i) + { + data >> type; + switch (type) + { + case 1: // Fragments + data >> Unused(); // Currency entry + data >> Unused(); // Currency count + break; + case 2: // Keystones + data >> Unused(); // Item entry + data >> Unused(); // Item count + break; + } + } + } +} + Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid originalCasterGUID, SpellEntry const* triggeredBy) { MANGOS_ASSERT(caster != NULL && info != NULL); @@ -4046,12 +4083,14 @@ void Spell::SendSpellStart() DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id); uint32 castFlags = CAST_FLAG_UNKNOWN2; - if (IsRangedSpell()) - castFlags |= CAST_FLAG_AMMO; - if (m_spellInfo->runeCostID) castFlags |= CAST_FLAG_UNKNOWN19; + if ((m_caster->GetTypeId() == TYPEID_PLAYER || + m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->IsPet()) && + m_spellInfo->powerType != POWER_HEALTH) + castFlags |= CAST_FLAG_PREDICTED_POWER; + WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2)); if (m_CastItem) data << m_CastItem->GetPackGUID(); @@ -4063,24 +4102,30 @@ void Spell::SendSpellStart() data << uint32(m_spellInfo->Id); // spellId data << uint32(castFlags); // cast flags data << uint32(m_timer); // delay? + data << uint32(m_casttime); // m_casttime data << m_targets; if (castFlags & CAST_FLAG_PREDICTED_POWER) // predicted power - data << uint32(0); + data << uint32(m_caster->GetPower(Powers(m_spellInfo->powerType))); if (castFlags & CAST_FLAG_PREDICTED_RUNES) // predicted runes { - uint8 v1 = 0;// m_runesState; - uint8 v2 = 0;//((Player*)m_caster)->GetRunesState(); - data << uint8(v1); // runes state before - data << uint8(v2); // runes state after - for (uint8 i = 0; i < MAX_RUNES; ++i) + if (m_caster->GetTypeId() == TYPEID_PLAYER) { - uint8 m = (1 << i); - if (m & v1) // usable before... - if (!(m & v2)) // ...but on cooldown now... - data << uint8(0); // some unknown byte (time?) + Player* caster = (Player*)m_caster; + + data << uint8(m_runesState); + data << uint8(caster->GetRunesState()); + for (uint8 i = 0; i < MAX_RUNES; ++i) + data << uint8(255 - ((caster->GetRuneCooldown(i) / REGEN_TIME_FULL) * 51)); + } + else + { + data << uint8(0); + data << uint8(0); + for (uint8 i = 0; i < MAX_RUNES; ++i) + data << uint8(0); } } @@ -4093,6 +4138,15 @@ void Spell::SendSpellStart() data << uint32(0); // used for SetCastImmunities } + if (castFlags & CAST_FLAG_HEAL_PREDICTION) + { + uint8 unk = 0; + data << uint32(0); + data << uint8(unk); + if (unk == 2) + data << ObjectGuid().WriteAsPacked(); + } + m_caster->SendMessageToSet(&data, true); } @@ -4105,13 +4159,15 @@ void Spell::SendSpellGo() DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id); uint32 castFlags = CAST_FLAG_UNKNOWN9; - if (IsRangedSpell()) - castFlags |= CAST_FLAG_AMMO; // arrows/bullets visual - if ((m_caster->GetTypeId() == TYPEID_PLAYER) && (m_caster->getClass() == CLASS_DEATH_KNIGHT) && m_spellInfo->runeCostID) + if ((m_caster->GetTypeId() == TYPEID_PLAYER || + m_caster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_caster)->IsPet()) && + m_spellInfo->powerType != POWER_HEALTH) + castFlags |= CAST_FLAG_PREDICTED_POWER; + + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->getClass() == CLASS_DEATH_KNIGHT && m_spellInfo->runeCostID) { castFlags |= CAST_FLAG_UNKNOWN19; // same as in SMSG_SPELL_START - castFlags |= CAST_FLAG_PREDICTED_POWER; // makes cooldowns visible castFlags |= CAST_FLAG_PREDICTED_RUNES; // rune cooldowns list } @@ -4126,6 +4182,7 @@ void Spell::SendSpellGo() data << uint8(m_cast_count); // pending spell cast? data << uint32(m_spellInfo->Id); // spellId data << uint32(castFlags); // cast flags + data << uint32(m_timer); data << uint32(WorldTimer::getMSTime()); // timestamp WriteSpellGoTargets(&data); @@ -4133,27 +4190,32 @@ void Spell::SendSpellGo() data << m_targets; if (castFlags & CAST_FLAG_PREDICTED_POWER) // predicted power - data << uint32(0); + data << uint32(m_caster->GetPower(Powers(m_spellInfo->powerType))); if (castFlags & CAST_FLAG_PREDICTED_RUNES) // predicted runes { - uint8 v1 = m_runesState; - uint8 v2 = m_caster->getClass() == CLASS_DEATH_KNIGHT ? ((Player*)m_caster)->GetRunesState() : 0; - data << uint8(v1); // runes state before - data << uint8(v2); // runes state after - for (uint8 i = 0; i < MAX_RUNES; ++i) + if (m_caster->GetTypeId() == TYPEID_PLAYER) { - uint8 m = (1 << i); - if (m & v1) // usable before... - if (!(m & v2)) // ...but on cooldown now... - data << uint8(0); // some unknown byte (time?) + Player* caster = (Player*)m_caster; + + data << uint8(m_runesState); + data << uint8(caster->GetRunesState()); + for (uint8 i = 0; i < MAX_RUNES; ++i) + data << uint8(255 - ((caster->GetRuneCooldown(i) / REGEN_TIME_FULL) * 51)); + } + else + { + data << uint8(0); + data << uint8(0); + for (uint8 i = 0; i < MAX_RUNES; ++i) + data << uint8(0); } } if (castFlags & CAST_FLAG_ADJUST_MISSILE) // adjust missile trajectory duration { - data << float(0); - data << uint32(0); + data << float(m_targets.GetElevation()); + data << uint32(m_delayMoment); } if (castFlags & CAST_FLAG_AMMO) // projectile info diff --git a/src/game/Spell.h b/src/game/Spell.h index 37e33c6ef..f84255618 100644 --- a/src/game/Spell.h +++ b/src/game/Spell.h @@ -61,7 +61,12 @@ enum SpellCastFlags CAST_FLAG_VISUAL_CHAIN = 0x00080000, // wotlk CAST_FLAG_UNKNOWN21 = 0x00100000, CAST_FLAG_PREDICTED_RUNES = 0x00200000, // wotlk, rune cooldown list - CAST_FLAG_IMMUNITY = 0x04000000 // spell cast school imminity info + CAST_FLAG_IMMUNITY = 0x04000000, // spell cast school imminity info + CAST_FLAG_UNKNOWN24 = 0x08000000, + CAST_FLAG_UNKNOWN25 = 0x10000000, + CAST_FLAG_UNKNOWN26 = 0x20000000, + CAST_FLAG_HEAL_PREDICTION = 0x40000000, // heal prediction + CAST_FLAG_UNKNOWN28 = 0x80000000, }; enum SpellFlags @@ -111,6 +116,7 @@ class SpellCastTargets void write(ByteBuffer& data) const; SpellCastTargetsReader ReadForCaster(Unit* caster) { return SpellCastTargetsReader(*this, caster); } + void ReadAdditionalData(WorldPacket& data, uint8& cast_flags); SpellCastTargets& operator=(const SpellCastTargets& target) { @@ -139,6 +145,9 @@ class SpellCastTargets m_targetMask = target.m_targetMask; + m_elevation = target.m_elevation; + m_speed = target.m_speed; + return *this; } @@ -177,6 +186,9 @@ class SpellCastTargets float m_destX, m_destY, m_destZ; std::string m_strTarget; + float GetElevation() const { return m_elevation; } + float GetSpeed() const { return m_speed; } + uint32 m_targetMask; private: // objects (can be used at spell creating and after Update at casting @@ -192,6 +204,9 @@ class SpellCastTargets ObjectGuid m_srcTransportGUID; ObjectGuid m_destTransportGUID; uint32 m_itemTargetEntry; + + float m_elevation; + float m_speed; }; inline ByteBuffer& operator<< (ByteBuffer& buf, SpellCastTargets const& targets) diff --git a/src/game/SpellHandler.cpp b/src/game/SpellHandler.cpp index 9e30bcf6b..f59400fdd 100644 --- a/src/game/SpellHandler.cpp +++ b/src/game/SpellHandler.cpp @@ -32,13 +32,13 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { uint8 bagIndex, slot; - uint8 unk_flags; // flags (if 0x02 - some additional data are received) + uint8 cast_flags; // flags (if 0x02 - some additional data are received) uint8 cast_count; // next cast if exists (single or not) ObjectGuid itemGuid; uint32 glyphIndex; // something to do with glyphs? uint32 spellid; // casted spell id - recvPacket >> bagIndex >> slot >> cast_count >> spellid >> itemGuid >> glyphIndex >> unk_flags; + recvPacket >> bagIndex >> slot >> cast_count >> spellid >> itemGuid >> glyphIndex >> cast_flags; // TODO: add targets.read() check Player* pUser = _player; @@ -73,7 +73,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) return; } - DETAIL_LOG("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, unk_flags, (uint32)recvPacket.size()); + DETAIL_LOG("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, cast_count: %u, spellid: %u, Item: %u, glyphIndex: %u, unk_flags: %u, data length = %i", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, cast_flags, (uint32)recvPacket.size()); ItemPrototype const* proto = pItem->GetProto(); if (!proto) @@ -157,6 +157,8 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) targets.Update(pUser); + targets.ReadAdditionalData(recvPacket, cast_flags); + if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget())) { // free gray item after use fail @@ -336,11 +338,11 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket) void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) { - uint32 spellId; - uint8 cast_count, unk_flags; + uint32 spellId, glyphIndex; + uint8 cast_count, cast_flags; recvPacket >> cast_count; - recvPacket >> spellId; - recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received) + recvPacket >> spellId >> glyphIndex; + recvPacket >> cast_flags; // flags (if 0x02 - some additional data are received) // ignore for remote control state (for player case) Unit* mover = _player->GetMover(); @@ -350,8 +352,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) return; } - DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i", - spellId, cast_count, unk_flags, (uint32)recvPacket.size()); + DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, cast_flags %u, data length = %i", + spellId, cast_count, cast_flags, (uint32)recvPacket.size()); SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId); @@ -389,24 +391,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) recvPacket >> targets.ReadForCaster(mover); - // some spell cast packet including more data (for projectiles?) - if (unk_flags & 0x02) - { - uint8 unk1; - - recvPacket >> Unused(); // unk1, coords? - recvPacket >> Unused(); // unk1, coords? - recvPacket >> unk1; // >> 1 or 0 - if (unk1) - { - ObjectGuid guid; // guid - unused - MovementInfo movementInfo; - - recvPacket >> Unused(); // >> CMSG_MOVE_STOP - recvPacket >> guid.ReadAsPacked(); - recvPacket >> movementInfo; - } - } + targets.ReadAdditionalData(recvPacket, cast_flags); // auto-selection buff level base at target level (in spellInfo) if (Unit* target = targets.getUnitTarget()) diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 59815a3a2..9e2271a09 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "12091" + #define REVISION_NR "0086" #endif // __REVISION_NR_H__