*Some more research about spell target flags - thanks to Zor for info.
--HG-- branch : trunk
This commit is contained in:
@@ -493,13 +493,15 @@ struct MovementInfo
|
|||||||
|
|
||||||
MovementInfo()
|
MovementInfo()
|
||||||
{
|
{
|
||||||
|
pos.Relocate(0,0,0,0);
|
||||||
guid = 0;
|
guid = 0;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
flags2 = 0;
|
flags2 = 0;
|
||||||
time = t_time = fallTime = 0;
|
time = t_time = t_time2 = fallTime = 0;
|
||||||
splineElevation = 0;
|
splineElevation = 0;
|
||||||
pitch = j_zspeed = j_sinAngle = j_cosAngle = j_xyspeed = 0.0f;
|
pitch = j_zspeed = j_sinAngle = j_cosAngle = j_xyspeed = 0.0f;
|
||||||
t_guid = 0;
|
t_guid = 0;
|
||||||
|
t_pos.Relocate(0,0,0,0);
|
||||||
t_seat = -1;
|
t_seat = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -973,7 +973,7 @@ void Unit::CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(spellInfo->Targets & (TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_UNK)))
|
if (!(spellInfo->Targets & (TARGET_FLAG_OBJECT | TARGET_FLAG_OBJECT_CASTER)))
|
||||||
{
|
{
|
||||||
sLog.outError("CastSpell: spell id %i by caster: %s %u) is not gameobject spell", spellId,(GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry()));
|
sLog.outError("CastSpell: spell id %i by caster: %s %u) is not gameobject spell", spellId,(GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry()));
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -694,11 +694,10 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
|
|||||||
uint64 guid;
|
uint64 guid;
|
||||||
uint32 spellid;
|
uint32 spellid;
|
||||||
uint8 cast_count;
|
uint8 cast_count;
|
||||||
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
|
|
||||||
|
|
||||||
recvPacket >> guid >> cast_count >> spellid >> unk_flags;
|
recvPacket >> guid >> cast_count >> spellid;
|
||||||
|
|
||||||
sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags);
|
sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u", cast_count, spellid);
|
||||||
|
|
||||||
// This opcode is also sent from charmed and possessed units (players and creatures)
|
// This opcode is also sent from charmed and possessed units (players and creatures)
|
||||||
if (!_player->GetGuardianPet() && !_player->GetCharm())
|
if (!_player->GetGuardianPet() && !_player->GetCharm())
|
||||||
|
|||||||
@@ -300,7 +300,6 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
|||||||
uint8 cast_count, unk_flags;
|
uint8 cast_count, unk_flags;
|
||||||
recvPacket >> cast_count;
|
recvPacket >> cast_count;
|
||||||
recvPacket >> spellId;
|
recvPacket >> spellId;
|
||||||
recvPacket >> unk_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->m_mover;
|
Unit* mover = _player->m_mover;
|
||||||
@@ -360,25 +359,6 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// some spell cast packet including more data (for projectiles?)
|
|
||||||
if (unk_flags & 0x02)
|
|
||||||
{
|
|
||||||
//recvPacket.read_skip<float>(); // unk1, coords?
|
|
||||||
//recvPacket.read_skip<float>(); // unk1, coords?
|
|
||||||
uint8 unk1;
|
|
||||||
recvPacket >> unk1; // >> 1 or 0
|
|
||||||
if (unk1)
|
|
||||||
{
|
|
||||||
recvPacket.read_skip<uint32>(); // >> MSG_MOVE_STOP
|
|
||||||
uint64 guid; // guid - unused
|
|
||||||
if (!recvPacket.readPackGUID(guid))
|
|
||||||
return;
|
|
||||||
|
|
||||||
MovementInfo movementInfo;
|
|
||||||
ReadMovementInfo(recvPacket, &movementInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// auto-selection buff level base at target level (in spellInfo)
|
// auto-selection buff level base at target level (in spellInfo)
|
||||||
if (targets.getUnitTarget())
|
if (targets.getUnitTarget())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -191,75 +191,85 @@ bool SpellCastTargets::read (WorldPacket * data, Unit *caster)
|
|||||||
if (data->rpos() + 4 > data->size())
|
if (data->rpos() + 4 > data->size())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//data->hexlike();
|
uint8 clientCastFlags;
|
||||||
|
*data >> clientCastFlags;
|
||||||
*data >> m_targetMask;
|
*data >> m_targetMask;
|
||||||
//sLog.outDebug("Spell read, target mask = %u", m_targetMask);
|
//sLog.outDebug("Spell read, target mask = %u", m_targetMask);
|
||||||
|
|
||||||
if (m_targetMask == TARGET_FLAG_SELF)
|
if (m_targetMask == TARGET_FLAG_SELF)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
for (uint8 i = 0; i < MAX_TARGET_FLAGS;++i)
|
if(m_targetMask & ( TARGET_FLAG_OBJECT))
|
||||||
{
|
{
|
||||||
if (!(m_targetMask & (1<<i)))
|
|
||||||
continue;
|
|
||||||
switch (1<<i)
|
|
||||||
{
|
|
||||||
case TARGET_FLAG_UNIT:
|
|
||||||
case TARGET_FLAG_UNK17: // used for non-combat pets, maybe other?
|
|
||||||
if (!data->readPackGUID(m_unitTargetGUID))
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case TARGET_FLAG_OBJECT:
|
|
||||||
if (!data->readPackGUID(m_GOTargetGUID))
|
if (!data->readPackGUID(m_GOTargetGUID))
|
||||||
return false;
|
return false;
|
||||||
break;
|
}
|
||||||
case TARGET_FLAG_CORPSE:
|
|
||||||
case TARGET_FLAG_PVP_CORPSE:
|
if(m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM))
|
||||||
if (!data->readPackGUID(m_CorpseTargetGUID))
|
{
|
||||||
return false;
|
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||||
break;
|
|
||||||
case TARGET_FLAG_ITEM:
|
|
||||||
case TARGET_FLAG_TRADE_ITEM:
|
|
||||||
if (caster->GetTypeId() != TYPEID_PLAYER)
|
|
||||||
return false;
|
return false;
|
||||||
if (!data->readPackGUID(m_itemTargetGUID))
|
if (!data->readPackGUID(m_itemTargetGUID))
|
||||||
return false;
|
return false;
|
||||||
break;
|
}
|
||||||
case TARGET_FLAG_SOURCE_LOCATION:
|
|
||||||
|
if(m_targetMask & (TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE))
|
||||||
|
{
|
||||||
|
if (!data->readPackGUID(m_CorpseTargetGUID))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
|
||||||
{
|
{
|
||||||
uint64 relativePositionObjGUID;
|
uint64 relativePositionObjGUID;
|
||||||
if (!data->readPackGUID(relativePositionObjGUID))
|
if (!data->readPackGUID(relativePositionObjGUID))
|
||||||
return false;
|
return false;
|
||||||
*data >> m_srcPos.m_positionX >> m_srcPos.m_positionY >> m_srcPos.m_positionZ;
|
*data >> m_srcPos.PositionXYZStream();
|
||||||
m_srcPos.m_orientation = caster->GetOrientation();
|
|
||||||
if (!m_srcPos.IsPositionValid())
|
if (!m_srcPos.IsPositionValid())
|
||||||
return false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case TARGET_FLAG_DEST_LOCATION:
|
else
|
||||||
|
m_srcPos.Relocate(caster);
|
||||||
|
|
||||||
|
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
|
||||||
{
|
{
|
||||||
uint64 relativePositionObjGUID;
|
uint64 relativePositionObjGUID;
|
||||||
if (!data->readPackGUID(relativePositionObjGUID))
|
if (!data->readPackGUID(relativePositionObjGUID))
|
||||||
return false;
|
return false;
|
||||||
*data >> m_dstPos.m_positionX >> m_dstPos.m_positionY >> m_dstPos.m_positionZ;
|
*data >> m_dstPos.PositionXYZStream();
|
||||||
if (!m_dstPos.IsPositionValid())
|
if (!m_dstPos.IsPositionValid())
|
||||||
return false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case TARGET_FLAG_STRING:
|
else
|
||||||
|
m_dstPos.Relocate(caster);
|
||||||
|
|
||||||
|
if(m_targetMask & TARGET_FLAG_STRING)
|
||||||
|
{
|
||||||
if (data->rpos() + 1 > data->size())
|
if (data->rpos() + 1 > data->size())
|
||||||
return false;
|
return false;
|
||||||
*data >> m_strTarget;
|
*data << m_strTarget;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(m_targetMask & TARGET_FLAG_SOURCE_LOCATION))
|
// some spell cast packet including more data (for projectiles?)
|
||||||
m_srcPos.Relocate(caster);
|
if (clientCastFlags & 0x02)
|
||||||
|
{
|
||||||
|
// not sure about these two
|
||||||
|
*data >> m_elevation;
|
||||||
|
*data >> m_speed;
|
||||||
|
uint8 hasMovementInfo;
|
||||||
|
*data >> hasMovementInfo; // bool
|
||||||
|
if (hasMovementInfo)
|
||||||
|
{
|
||||||
|
data->read_skip<uint32>(); // MSG_MOVE_STOP - hardcoded in client
|
||||||
|
uint64 guid; // guid - unused
|
||||||
|
if (!data->readPackGUID(guid))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (!(m_targetMask & TARGET_FLAG_DEST_LOCATION))
|
data->rpos(data->wpos()); // prevent spam at ignore packet
|
||||||
m_dstPos.Relocate(caster);
|
//MovementInfo movementInfo;
|
||||||
|
//ReadMovementInfo(*data, &movementInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// find real units/GOs
|
// find real units/GOs
|
||||||
Update(caster);
|
Update(caster);
|
||||||
@@ -271,51 +281,50 @@ void SpellCastTargets::write (WorldPacket * data)
|
|||||||
*data << uint32(m_targetMask);
|
*data << uint32(m_targetMask);
|
||||||
//sLog.outDebug("Spell write, target mask = %u", m_targetMask);
|
//sLog.outDebug("Spell write, target mask = %u", m_targetMask);
|
||||||
|
|
||||||
for (uint8 i = 0; i < MAX_TARGET_FLAGS;++i)
|
if (m_targetMask & (TARGET_FLAG_UNIT | TARGET_FLAG_PVP_CORPSE | TARGET_FLAG_OBJECT | TARGET_FLAG_CORPSE | TARGET_FLAG_UNK17))
|
||||||
{
|
{
|
||||||
if (!(m_targetMask & (1<<i)))
|
if (m_targetMask & TARGET_FLAG_UNIT)
|
||||||
continue;
|
|
||||||
switch (1<<i)
|
|
||||||
{
|
{
|
||||||
case TARGET_FLAG_UNIT:
|
|
||||||
if (m_unitTarget)
|
if (m_unitTarget)
|
||||||
data->append(m_unitTarget->GetPackGUID());
|
data->append(m_unitTarget->GetPackGUID());
|
||||||
else
|
else
|
||||||
*data << uint8(0);
|
*data << uint8(0);
|
||||||
break;
|
}
|
||||||
case TARGET_FLAG_OBJECT:
|
else if (m_targetMask & TARGET_FLAG_OBJECT)
|
||||||
|
{
|
||||||
if(m_GOTarget)
|
if(m_GOTarget)
|
||||||
data->append(m_GOTarget->GetPackGUID());
|
data->append(m_GOTarget->GetPackGUID());
|
||||||
else
|
else
|
||||||
*data << uint8(0);
|
*data << uint8(0);
|
||||||
break;
|
}
|
||||||
case TARGET_FLAG_CORPSE:
|
else if (m_targetMask & ( TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE))
|
||||||
case TARGET_FLAG_PVP_CORPSE:
|
|
||||||
data->appendPackGUID(m_CorpseTargetGUID);
|
data->appendPackGUID(m_CorpseTargetGUID);
|
||||||
break;
|
else
|
||||||
case TARGET_FLAG_UNK17:
|
|
||||||
*data << uint8(0);
|
*data << uint8(0);
|
||||||
break;
|
}
|
||||||
case TARGET_FLAG_ITEM:
|
|
||||||
case TARGET_FLAG_TRADE_ITEM:
|
if (m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM))
|
||||||
|
{
|
||||||
if(m_itemTarget)
|
if(m_itemTarget)
|
||||||
data->append(m_itemTarget->GetPackGUID());
|
data->append(m_itemTarget->GetPackGUID());
|
||||||
else
|
else
|
||||||
*data << uint8(0);
|
*data << uint8(0);
|
||||||
break;
|
}
|
||||||
case TARGET_FLAG_SOURCE_LOCATION:
|
|
||||||
|
if (m_targetMask & TARGET_FLAG_SOURCE_LOCATION)
|
||||||
|
{
|
||||||
*data << uint8(0); // relative position guid here - transport for example
|
*data << uint8(0); // relative position guid here - transport for example
|
||||||
*data << m_srcPos.m_positionX << m_srcPos.m_positionY << m_srcPos.m_positionZ;
|
*data << m_srcPos.PositionXYZStream();
|
||||||
break;
|
}
|
||||||
case TARGET_FLAG_DEST_LOCATION:
|
|
||||||
|
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
|
||||||
|
{
|
||||||
*data << uint8(0); // relative position guid here - transport for example
|
*data << uint8(0); // relative position guid here - transport for example
|
||||||
*data << m_dstPos.m_positionX << m_dstPos.m_positionY << m_dstPos.m_positionZ;
|
*data << m_dstPos.PositionXYZStream();
|
||||||
break;
|
}
|
||||||
case TARGET_FLAG_STRING:
|
|
||||||
|
if (m_targetMask & TARGET_FLAG_STRING)
|
||||||
*data << m_strTarget;
|
*data << m_strTarget;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spell::Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID, Spell** triggeringContainer, bool skipCheck)
|
Spell::Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID, Spell** triggeringContainer, bool skipCheck)
|
||||||
@@ -4689,7 +4698,7 @@ SpellCastResult Spell::CheckCast(bool strict)
|
|||||||
Unit *target = m_targets.getUnitTarget();
|
Unit *target = m_targets.getUnitTarget();
|
||||||
|
|
||||||
// In pure self-cast spells, the client won't send any unit target
|
// In pure self-cast spells, the client won't send any unit target
|
||||||
if (!target && (m_targets.getTargetMask() == TARGET_FLAG_SELF || m_targets.getTargetMask() & TARGET_FLAG_CASTER)) // TARGET_FLAG_SELF == 0, remember!
|
if (!target && (m_targets.getTargetMask() == TARGET_FLAG_SELF || m_targets.getTargetMask() & TARGET_FLAG_UNIT_CASTER)) // TARGET_FLAG_SELF == 0, remember!
|
||||||
target = m_caster;
|
target = m_caster;
|
||||||
|
|
||||||
if (target)
|
if (target)
|
||||||
|
|||||||
@@ -43,19 +43,19 @@ enum SpellCastTargetFlags
|
|||||||
TARGET_FLAG_ITEM = 0x00000010, // pguid
|
TARGET_FLAG_ITEM = 0x00000010, // pguid
|
||||||
TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // 3 float
|
TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // 3 float
|
||||||
TARGET_FLAG_DEST_LOCATION = 0x00000040, // 3 float
|
TARGET_FLAG_DEST_LOCATION = 0x00000040, // 3 float
|
||||||
TARGET_FLAG_OBJECT_UNK = 0x00000080, // used in 7 spells only
|
TARGET_FLAG_OBJECT_CASTER = 0x00000080, // used in 7 spells only
|
||||||
TARGET_FLAG_CASTER = 0x00000100, // looks like self target (480 spells)
|
TARGET_FLAG_UNIT_CASTER = 0x00000100, // looks like self target (480 spells)
|
||||||
TARGET_FLAG_PVP_CORPSE = 0x00000200, // pguid
|
TARGET_FLAG_PVP_CORPSE = 0x00000200, // pguid
|
||||||
TARGET_FLAG_UNIT_CORPSE = 0x00000400, // 10 spells (gathering professions)
|
TARGET_FLAG_UNIT_CORPSE = 0x00000400, // 10 spells (gathering professions)
|
||||||
TARGET_FLAG_OBJECT = 0x00000800, // pguid, 2 spells
|
TARGET_FLAG_OBJECT = 0x00000800, // pguid, 2 spells
|
||||||
TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid, 0 spells
|
TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid, 0 spells
|
||||||
TARGET_FLAG_STRING = 0x00002000, // string, 0 spells
|
TARGET_FLAG_STRING = 0x00002000, // string, 0 spells
|
||||||
TARGET_FLAG_UNK15 = 0x00004000, // 199 spells, opening object/lock
|
TARGET_FLAG_OPEN_LOCK = 0x00004000, // 199 spells, opening object/lock
|
||||||
TARGET_FLAG_CORPSE = 0x00008000, // pguid, resurrection spells
|
TARGET_FLAG_CORPSE = 0x00008000, // pguid, resurrection spells
|
||||||
TARGET_FLAG_UNK17 = 0x00010000, // pguid, not used in any spells as of 3.2.2a (can be set dynamically)
|
TARGET_FLAG_UNK17 = 0x00010000, // pguid, not used in any spells as of 3.2.2a (can be set dynamically)
|
||||||
TARGET_FLAG_GLYPH = 0x00020000, // used in glyph spells
|
TARGET_FLAG_GLYPH = 0x00020000, // used in glyph spells
|
||||||
TARGET_FLAG_UNK19 = 0x00040000, //
|
TARGET_FLAG_UNK19 = 0x00040000, //
|
||||||
TARGET_FLAG_UNK20 = 0x00080000 // uint32, loop { vec3, guid -> if guid == 0 break }
|
TARGET_FLAG_UNUSED20 = 0x00080000 // uint32 counter, loop { vec3 - screen position (?), guid }, not used so far
|
||||||
};
|
};
|
||||||
#define MAX_TARGET_FLAGS 21
|
#define MAX_TARGET_FLAGS 21
|
||||||
|
|
||||||
|
|||||||
@@ -3230,7 +3230,7 @@ bool CanSpellPierceImmuneAura(SpellEntry const * pierceSpell, SpellEntry const *
|
|||||||
// these spells (Cyclone for example) can pierce all...
|
// these spells (Cyclone for example) can pierce all...
|
||||||
if ((pierceSpell->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE)
|
if ((pierceSpell->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE)
|
||||||
// ...but not these (Divine shield for example)
|
// ...but not these (Divine shield for example)
|
||||||
&& !(aura && aura->AttributesEx & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY))
|
&& !(aura && (aura->AttributesEx & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -3784,7 +3784,7 @@ void SpellMgr::LoadSpellCustomAttr()
|
|||||||
break;
|
break;
|
||||||
// some dummy spell only has dest, should push caster in this case
|
// some dummy spell only has dest, should push caster in this case
|
||||||
case 62324: // Throw Passenger
|
case 62324: // Throw Passenger
|
||||||
spellInfo->Targets |= TARGET_FLAG_CASTER;
|
spellInfo->Targets |= TARGET_FLAG_UNIT_CASTER;
|
||||||
count++;
|
count++;
|
||||||
break;
|
break;
|
||||||
case 51735: // Ebon Plague
|
case 51735: // Ebon Plague
|
||||||
|
|||||||
Reference in New Issue
Block a user