mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 04:37:00 +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,
|
||||
};
|
||||
|
||||
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:
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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<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)
|
||||
{
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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<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;
|
||||
}
|
||||
}
|
||||
targets.ReadAdditionalData(recvPacket, cast_flags);
|
||||
|
||||
// auto-selection buff level base at target level (in spellInfo)
|
||||
if (Unit* target = targets.getUnitTarget())
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "12091"
|
||||
#define REVISION_NR "0086"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue