mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[0086] Updated CMSG_SPELL_CAST, CMSG_USE_ITEM, CMSG_PET_SPELL_CAST, SMSG_SPELL_START, SMSG_SPELL_GO and some other spell opcodes
This commit is contained in:
parent
5d91e6f24c
commit
6407b24a03
8 changed files with 217 additions and 77 deletions
|
|
@ -2109,10 +2109,86 @@ MovementStatusElements MovementSetCanFlyAckSequence[] =
|
||||||
MSEEnd,
|
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)
|
MovementStatusElements* GetMovementStatusElementsSequence(uint16 opcode)
|
||||||
{
|
{
|
||||||
switch(opcode)
|
switch(opcode)
|
||||||
{
|
{
|
||||||
|
case CMSG_CAST_SPELL:
|
||||||
|
case CMSG_PET_CAST_SPELL:
|
||||||
|
case CMSG_USE_ITEM:
|
||||||
|
return MovementCastSpellSequence;
|
||||||
case CMSG_MOVE_CHNG_TRANSPORT:
|
case CMSG_MOVE_CHNG_TRANSPORT:
|
||||||
return MovementChngTransportSequence;
|
return MovementChngTransportSequence;
|
||||||
case CMSG_MOVE_FALL_LAND:
|
case CMSG_MOVE_FALL_LAND:
|
||||||
|
|
|
||||||
|
|
@ -234,7 +234,7 @@ void InitializeOpcodes()
|
||||||
//OPCODE(CMSG_CHANNEL_MODERATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerateOpcode );
|
//OPCODE(CMSG_CHANNEL_MODERATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleChannelModerateOpcode );
|
||||||
OPCODE(SMSG_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_UPDATE_OBJECT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_DESTROY_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_OPEN_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleOpenItemOpcode );
|
||||||
//OPCODE(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItemOpcode );
|
//OPCODE(CMSG_READ_ITEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleReadItemOpcode );
|
||||||
//OPCODE(SMSG_READ_ITEM_OK, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
//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_LEARNED_SPELL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
OPCODE(SMSG_SUPERCEDED_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_NEW_SPELL_SLOT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_NULL );
|
||||||
//OPCODE(CMSG_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode );
|
OPCODE(CMSG_CAST_SPELL, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCastSpellOpcode );
|
||||||
//OPCODE(CMSG_CANCEL_CAST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode );
|
OPCODE(CMSG_CANCEL_CAST, STATUS_LOGGEDIN, PROCESS_THREADSAFE, &WorldSession::HandleCancelCastOpcode );
|
||||||
//OPCODE(SMSG_CAST_FAILED, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
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_START, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_SPELL_GO, 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_FAILURE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_SPELL_COOLDOWN, 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(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_EQUIPMENT_SET_ID, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_PET_CAST_FAILED, 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 );
|
//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_TIME_UPDATE, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
//OPCODE(SMSG_ITEM_ENCHANT_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(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_SAVE_GUILD_EMBLEM, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleSaveGuildEmblemOpcode );
|
||||||
//OPCODE(MSG_TABARDVENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode);
|
//OPCODE(MSG_TABARDVENDOR_ACTIVATE, STATUS_LOGGEDIN, PROCESS_THREADUNSAFE, &WorldSession::HandleTabardVendorActivateOpcode);
|
||||||
OPCODE(SMSG_PLAY_SPELL_VISUAL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
OPCODE(SMSG_PLAY_SPELL_VISUAL, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
|
||||||
|
|
|
||||||
|
|
@ -228,7 +228,7 @@ enum Opcodes
|
||||||
CMSG_CHANNEL_MODERATE = 0x10A9,
|
CMSG_CHANNEL_MODERATE = 0x10A9,
|
||||||
SMSG_UPDATE_OBJECT = 0x4715, // 4.3.4 15595
|
SMSG_UPDATE_OBJECT = 0x4715, // 4.3.4 15595
|
||||||
SMSG_DESTROY_OBJECT = 0x4724, // 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_OPEN_ITEM = 0x10AD,
|
||||||
CMSG_READ_ITEM = 0x10AE,
|
CMSG_READ_ITEM = 0x10AE,
|
||||||
SMSG_READ_ITEM_OK = 0x10AF,
|
SMSG_READ_ITEM_OK = 0x10AF,
|
||||||
|
|
@ -359,15 +359,15 @@ enum Opcodes
|
||||||
SMSG_LEARNED_SPELL = 0x58A2, // 4.3.4 15595
|
SMSG_LEARNED_SPELL = 0x58A2, // 4.3.4 15595
|
||||||
SMSG_SUPERCEDED_SPELL = 0x35B0, // 4.3.4 15595
|
SMSG_SUPERCEDED_SPELL = 0x35B0, // 4.3.4 15595
|
||||||
CMSG_NEW_SPELL_SLOT = 0x112E,
|
CMSG_NEW_SPELL_SLOT = 0x112E,
|
||||||
CMSG_CAST_SPELL = 0x112F,
|
CMSG_CAST_SPELL = 0x4C07, // 4.3.4 15595
|
||||||
CMSG_CANCEL_CAST = 0x1130,
|
CMSG_CANCEL_CAST = 0x0115, // 4.3.4 15595
|
||||||
SMSG_CAST_FAILED = 0x1131,
|
SMSG_CAST_FAILED = 0x4D16, // 4.3.4 15595
|
||||||
SMSG_SPELL_START = 0x1132,
|
SMSG_SPELL_START = 0x6415, // 4.3.4 15595
|
||||||
SMSG_SPELL_GO = 0x1133,
|
SMSG_SPELL_GO = 0x6E16, // 4.3.4 15595
|
||||||
SMSG_SPELL_FAILURE = 0x1134,
|
SMSG_SPELL_FAILURE = 0x1134,
|
||||||
SMSG_SPELL_COOLDOWN = 0x1135,
|
SMSG_SPELL_COOLDOWN = 0x1135,
|
||||||
SMSG_COOLDOWN_EVENT = 0x1136,
|
SMSG_COOLDOWN_EVENT = 0x1136,
|
||||||
CMSG_CANCEL_AURA = 0x1137,
|
CMSG_CANCEL_AURA = 0x0E26, // 4.3.4 15595
|
||||||
SMSG_EQUIPMENT_SET_ID = 0x1138,
|
SMSG_EQUIPMENT_SET_ID = 0x1138,
|
||||||
SMSG_PET_CAST_FAILED = 0x1139,
|
SMSG_PET_CAST_FAILED = 0x1139,
|
||||||
MSG_CHANNEL_START = 0x113A,
|
MSG_CHANNEL_START = 0x113A,
|
||||||
|
|
@ -550,7 +550,7 @@ enum Opcodes
|
||||||
SMSG_ITEM_TIME_UPDATE = 0x11EB,
|
SMSG_ITEM_TIME_UPDATE = 0x11EB,
|
||||||
SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x11EC,
|
SMSG_ITEM_ENCHANT_TIME_UPDATE = 0x11EC,
|
||||||
MSG_GM_SHOWLABEL = 0x11F0,
|
MSG_GM_SHOWLABEL = 0x11F0,
|
||||||
CMSG_PET_CAST_SPELL = 0x11F1,
|
CMSG_PET_CAST_SPELL = 0x6337, // 4.3.4 15595
|
||||||
MSG_SAVE_GUILD_EMBLEM = 0x11F2,
|
MSG_SAVE_GUILD_EMBLEM = 0x11F2,
|
||||||
MSG_TABARDVENDOR_ACTIVATE = 0x11F3,
|
MSG_TABARDVENDOR_ACTIVATE = 0x11F3,
|
||||||
SMSG_PLAY_SPELL_VISUAL = 0x55A5, // 4.3.4 15595
|
SMSG_PLAY_SPELL_VISUAL = 0x55A5, // 4.3.4 15595
|
||||||
|
|
|
||||||
|
|
@ -633,11 +633,11 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
ObjectGuid guid;
|
ObjectGuid guid;
|
||||||
uint32 spellid;
|
uint32 spellid;
|
||||||
uint8 cast_count;
|
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);
|
Creature* pet = _player->GetMap()->GetAnyTypeCreature(guid);
|
||||||
|
|
||||||
|
|
@ -666,6 +666,8 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
|
|
||||||
recvPacket >> targets.ReadForCaster(pet);
|
recvPacket >> targets.ReadForCaster(pet);
|
||||||
|
|
||||||
|
targets.ReadAdditionalData(recvPacket, cast_flags);
|
||||||
|
|
||||||
pet->clearUnitState(UNIT_STAT_MOVING);
|
pet->clearUnitState(UNIT_STAT_MOVING);
|
||||||
|
|
||||||
Spell* spell = new Spell(pet, spellInfo, false);
|
Spell* spell = new Spell(pet, spellInfo, false);
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,43 @@ void SpellCastTargets::write(ByteBuffer& data) const
|
||||||
data << m_strTarget;
|
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<uint32>(); // Currency entry
|
||||||
|
data >> Unused<uint32>(); // Currency count
|
||||||
|
break;
|
||||||
|
case 2: // Keystones
|
||||||
|
data >> Unused<uint32>(); // Item entry
|
||||||
|
data >> Unused<uint32>(); // Item count
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid originalCasterGUID, SpellEntry const* triggeredBy)
|
Spell::Spell(Unit* caster, SpellEntry const* info, bool triggered, ObjectGuid originalCasterGUID, SpellEntry const* triggeredBy)
|
||||||
{
|
{
|
||||||
MANGOS_ASSERT(caster != NULL && info != NULL);
|
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);
|
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
|
||||||
|
|
||||||
uint32 castFlags = CAST_FLAG_UNKNOWN2;
|
uint32 castFlags = CAST_FLAG_UNKNOWN2;
|
||||||
if (IsRangedSpell())
|
|
||||||
castFlags |= CAST_FLAG_AMMO;
|
|
||||||
|
|
||||||
if (m_spellInfo->runeCostID)
|
if (m_spellInfo->runeCostID)
|
||||||
castFlags |= CAST_FLAG_UNKNOWN19;
|
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));
|
WorldPacket data(SMSG_SPELL_START, (8 + 8 + 4 + 4 + 2));
|
||||||
if (m_CastItem)
|
if (m_CastItem)
|
||||||
data << m_CastItem->GetPackGUID();
|
data << m_CastItem->GetPackGUID();
|
||||||
|
|
@ -4063,24 +4102,30 @@ void Spell::SendSpellStart()
|
||||||
data << uint32(m_spellInfo->Id); // spellId
|
data << uint32(m_spellInfo->Id); // spellId
|
||||||
data << uint32(castFlags); // cast flags
|
data << uint32(castFlags); // cast flags
|
||||||
data << uint32(m_timer); // delay?
|
data << uint32(m_timer); // delay?
|
||||||
|
data << uint32(m_casttime); // m_casttime
|
||||||
|
|
||||||
data << m_targets;
|
data << m_targets;
|
||||||
|
|
||||||
if (castFlags & CAST_FLAG_PREDICTED_POWER) // predicted power
|
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
|
if (castFlags & CAST_FLAG_PREDICTED_RUNES) // predicted runes
|
||||||
{
|
{
|
||||||
uint8 v1 = 0;// m_runesState;
|
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
uint8 m = (1 << i);
|
Player* caster = (Player*)m_caster;
|
||||||
if (m & v1) // usable before...
|
|
||||||
if (!(m & v2)) // ...but on cooldown now...
|
data << uint8(m_runesState);
|
||||||
data << uint8(0); // some unknown byte (time?)
|
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
|
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);
|
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);
|
DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Sending SMSG_SPELL_GO id=%u", m_spellInfo->Id);
|
||||||
|
|
||||||
uint32 castFlags = CAST_FLAG_UNKNOWN9;
|
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_UNKNOWN19; // same as in SMSG_SPELL_START
|
||||||
castFlags |= CAST_FLAG_PREDICTED_POWER; // makes cooldowns visible
|
|
||||||
castFlags |= CAST_FLAG_PREDICTED_RUNES; // rune cooldowns list
|
castFlags |= CAST_FLAG_PREDICTED_RUNES; // rune cooldowns list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4126,6 +4182,7 @@ void Spell::SendSpellGo()
|
||||||
data << uint8(m_cast_count); // pending spell cast?
|
data << uint8(m_cast_count); // pending spell cast?
|
||||||
data << uint32(m_spellInfo->Id); // spellId
|
data << uint32(m_spellInfo->Id); // spellId
|
||||||
data << uint32(castFlags); // cast flags
|
data << uint32(castFlags); // cast flags
|
||||||
|
data << uint32(m_timer);
|
||||||
data << uint32(WorldTimer::getMSTime()); // timestamp
|
data << uint32(WorldTimer::getMSTime()); // timestamp
|
||||||
|
|
||||||
WriteSpellGoTargets(&data);
|
WriteSpellGoTargets(&data);
|
||||||
|
|
@ -4133,27 +4190,32 @@ void Spell::SendSpellGo()
|
||||||
data << m_targets;
|
data << m_targets;
|
||||||
|
|
||||||
if (castFlags & CAST_FLAG_PREDICTED_POWER) // predicted power
|
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
|
if (castFlags & CAST_FLAG_PREDICTED_RUNES) // predicted runes
|
||||||
{
|
{
|
||||||
uint8 v1 = m_runesState;
|
if (m_caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
uint8 m = (1 << i);
|
Player* caster = (Player*)m_caster;
|
||||||
if (m & v1) // usable before...
|
|
||||||
if (!(m & v2)) // ...but on cooldown now...
|
data << uint8(m_runesState);
|
||||||
data << uint8(0); // some unknown byte (time?)
|
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
|
if (castFlags & CAST_FLAG_ADJUST_MISSILE) // adjust missile trajectory duration
|
||||||
{
|
{
|
||||||
data << float(0);
|
data << float(m_targets.GetElevation());
|
||||||
data << uint32(0);
|
data << uint32(m_delayMoment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (castFlags & CAST_FLAG_AMMO) // projectile info
|
if (castFlags & CAST_FLAG_AMMO) // projectile info
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,12 @@ enum SpellCastFlags
|
||||||
CAST_FLAG_VISUAL_CHAIN = 0x00080000, // wotlk
|
CAST_FLAG_VISUAL_CHAIN = 0x00080000, // wotlk
|
||||||
CAST_FLAG_UNKNOWN21 = 0x00100000,
|
CAST_FLAG_UNKNOWN21 = 0x00100000,
|
||||||
CAST_FLAG_PREDICTED_RUNES = 0x00200000, // wotlk, rune cooldown list
|
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
|
enum SpellFlags
|
||||||
|
|
@ -111,6 +116,7 @@ class SpellCastTargets
|
||||||
void write(ByteBuffer& data) const;
|
void write(ByteBuffer& data) const;
|
||||||
|
|
||||||
SpellCastTargetsReader ReadForCaster(Unit* caster) { return SpellCastTargetsReader(*this, caster); }
|
SpellCastTargetsReader ReadForCaster(Unit* caster) { return SpellCastTargetsReader(*this, caster); }
|
||||||
|
void ReadAdditionalData(WorldPacket& data, uint8& cast_flags);
|
||||||
|
|
||||||
SpellCastTargets& operator=(const SpellCastTargets& target)
|
SpellCastTargets& operator=(const SpellCastTargets& target)
|
||||||
{
|
{
|
||||||
|
|
@ -139,6 +145,9 @@ class SpellCastTargets
|
||||||
|
|
||||||
m_targetMask = target.m_targetMask;
|
m_targetMask = target.m_targetMask;
|
||||||
|
|
||||||
|
m_elevation = target.m_elevation;
|
||||||
|
m_speed = target.m_speed;
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -177,6 +186,9 @@ class SpellCastTargets
|
||||||
float m_destX, m_destY, m_destZ;
|
float m_destX, m_destY, m_destZ;
|
||||||
std::string m_strTarget;
|
std::string m_strTarget;
|
||||||
|
|
||||||
|
float GetElevation() const { return m_elevation; }
|
||||||
|
float GetSpeed() const { return m_speed; }
|
||||||
|
|
||||||
uint32 m_targetMask;
|
uint32 m_targetMask;
|
||||||
private:
|
private:
|
||||||
// objects (can be used at spell creating and after Update at casting
|
// objects (can be used at spell creating and after Update at casting
|
||||||
|
|
@ -192,6 +204,9 @@ class SpellCastTargets
|
||||||
ObjectGuid m_srcTransportGUID;
|
ObjectGuid m_srcTransportGUID;
|
||||||
ObjectGuid m_destTransportGUID;
|
ObjectGuid m_destTransportGUID;
|
||||||
uint32 m_itemTargetEntry;
|
uint32 m_itemTargetEntry;
|
||||||
|
|
||||||
|
float m_elevation;
|
||||||
|
float m_speed;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ByteBuffer& operator<< (ByteBuffer& buf, SpellCastTargets const& targets)
|
inline ByteBuffer& operator<< (ByteBuffer& buf, SpellCastTargets const& targets)
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,13 @@
|
||||||
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
uint8 bagIndex, slot;
|
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)
|
uint8 cast_count; // next cast if exists (single or not)
|
||||||
ObjectGuid itemGuid;
|
ObjectGuid itemGuid;
|
||||||
uint32 glyphIndex; // something to do with glyphs?
|
uint32 glyphIndex; // something to do with glyphs?
|
||||||
uint32 spellid; // casted spell id
|
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
|
// TODO: add targets.read() check
|
||||||
Player* pUser = _player;
|
Player* pUser = _player;
|
||||||
|
|
@ -73,7 +73,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
return;
|
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();
|
ItemPrototype const* proto = pItem->GetProto();
|
||||||
if (!proto)
|
if (!proto)
|
||||||
|
|
@ -157,6 +157,8 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
|
||||||
|
|
||||||
targets.Update(pUser);
|
targets.Update(pUser);
|
||||||
|
|
||||||
|
targets.ReadAdditionalData(recvPacket, cast_flags);
|
||||||
|
|
||||||
if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget()))
|
if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget()))
|
||||||
{
|
{
|
||||||
// free gray item after use fail
|
// free gray item after use fail
|
||||||
|
|
@ -336,11 +338,11 @@ void WorldSession::HandleGameobjectReportUse(WorldPacket& recvPacket)
|
||||||
|
|
||||||
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
uint32 spellId;
|
uint32 spellId, glyphIndex;
|
||||||
uint8 cast_count, unk_flags;
|
uint8 cast_count, cast_flags;
|
||||||
recvPacket >> cast_count;
|
recvPacket >> cast_count;
|
||||||
recvPacket >> spellId;
|
recvPacket >> spellId >> glyphIndex;
|
||||||
recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
|
recvPacket >> cast_flags; // flags (if 0x02 - some additional data are received)
|
||||||
|
|
||||||
// ignore for remote control state (for player case)
|
// ignore for remote control state (for player case)
|
||||||
Unit* mover = _player->GetMover();
|
Unit* mover = _player->GetMover();
|
||||||
|
|
@ -350,8 +352,8 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
|
DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, cast_flags %u, data length = %i",
|
||||||
spellId, cast_count, unk_flags, (uint32)recvPacket.size());
|
spellId, cast_count, cast_flags, (uint32)recvPacket.size());
|
||||||
|
|
||||||
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
|
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
|
||||||
|
|
||||||
|
|
@ -389,24 +391,7 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||||
|
|
||||||
recvPacket >> targets.ReadForCaster(mover);
|
recvPacket >> targets.ReadForCaster(mover);
|
||||||
|
|
||||||
// some spell cast packet including more data (for projectiles?)
|
targets.ReadAdditionalData(recvPacket, cast_flags);
|
||||||
if (unk_flags & 0x02)
|
|
||||||
{
|
|
||||||
uint8 unk1;
|
|
||||||
|
|
||||||
recvPacket >> Unused<float>(); // unk1, coords?
|
|
||||||
recvPacket >> Unused<float>(); // unk1, coords?
|
|
||||||
recvPacket >> unk1; // >> 1 or 0
|
|
||||||
if (unk1)
|
|
||||||
{
|
|
||||||
ObjectGuid guid; // guid - unused
|
|
||||||
MovementInfo movementInfo;
|
|
||||||
|
|
||||||
recvPacket >> Unused<uint32>(); // >> CMSG_MOVE_STOP
|
|
||||||
recvPacket >> guid.ReadAsPacked();
|
|
||||||
recvPacket >> movementInfo;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// auto-selection buff level base at target level (in spellInfo)
|
// auto-selection buff level base at target level (in spellInfo)
|
||||||
if (Unit* target = targets.getUnitTarget())
|
if (Unit* target = targets.getUnitTarget())
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "12091"
|
#define REVISION_NR "0086"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue