*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()
|
||||
{
|
||||
pos.Relocate(0,0,0,0);
|
||||
guid = 0;
|
||||
flags = 0;
|
||||
flags2 = 0;
|
||||
time = t_time = fallTime = 0;
|
||||
time = t_time = t_time2 = fallTime = 0;
|
||||
splineElevation = 0;
|
||||
pitch = j_zspeed = j_sinAngle = j_cosAngle = j_xyspeed = 0.0f;
|
||||
t_guid = 0;
|
||||
t_pos.Relocate(0,0,0,0);
|
||||
t_seat = -1;
|
||||
}
|
||||
|
||||
|
||||
@@ -973,7 +973,7 @@ void Unit::CastSpell(GameObject *go, uint32 spellId, bool triggered, Item *castI
|
||||
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()));
|
||||
return;
|
||||
|
||||
@@ -694,11 +694,10 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
|
||||
uint64 guid;
|
||||
uint32 spellid;
|
||||
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)
|
||||
if (!_player->GetGuardianPet() && !_player->GetCharm())
|
||||
|
||||
@@ -300,7 +300,6 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||
uint8 cast_count, unk_flags;
|
||||
recvPacket >> cast_count;
|
||||
recvPacket >> spellId;
|
||||
recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
|
||||
|
||||
// ignore for remote control state (for player case)
|
||||
Unit* mover = _player->m_mover;
|
||||
@@ -360,25 +359,6 @@ void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
|
||||
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)
|
||||
if (targets.getUnitTarget())
|
||||
{
|
||||
|
||||
@@ -191,75 +191,85 @@ bool SpellCastTargets::read (WorldPacket * data, Unit *caster)
|
||||
if (data->rpos() + 4 > data->size())
|
||||
return false;
|
||||
|
||||
//data->hexlike();
|
||||
|
||||
uint8 clientCastFlags;
|
||||
*data >> clientCastFlags;
|
||||
*data >> m_targetMask;
|
||||
//sLog.outDebug("Spell read, target mask = %u", m_targetMask);
|
||||
|
||||
if (m_targetMask == TARGET_FLAG_SELF)
|
||||
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))
|
||||
return false;
|
||||
break;
|
||||
case TARGET_FLAG_CORPSE:
|
||||
case TARGET_FLAG_PVP_CORPSE:
|
||||
if (!data->readPackGUID(m_CorpseTargetGUID))
|
||||
return false;
|
||||
break;
|
||||
case TARGET_FLAG_ITEM:
|
||||
case TARGET_FLAG_TRADE_ITEM:
|
||||
if (caster->GetTypeId() != TYPEID_PLAYER)
|
||||
}
|
||||
|
||||
if(m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM))
|
||||
{
|
||||
if(caster->GetTypeId() == TYPEID_PLAYER)
|
||||
return false;
|
||||
if (!data->readPackGUID(m_itemTargetGUID))
|
||||
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;
|
||||
if (!data->readPackGUID(relativePositionObjGUID))
|
||||
return false;
|
||||
*data >> m_srcPos.m_positionX >> m_srcPos.m_positionY >> m_srcPos.m_positionZ;
|
||||
m_srcPos.m_orientation = caster->GetOrientation();
|
||||
*data >> m_srcPos.PositionXYZStream();
|
||||
if (!m_srcPos.IsPositionValid())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case TARGET_FLAG_DEST_LOCATION:
|
||||
else
|
||||
m_srcPos.Relocate(caster);
|
||||
|
||||
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
|
||||
{
|
||||
uint64 relativePositionObjGUID;
|
||||
if (!data->readPackGUID(relativePositionObjGUID))
|
||||
return false;
|
||||
*data >> m_dstPos.m_positionX >> m_dstPos.m_positionY >> m_dstPos.m_positionZ;
|
||||
*data >> m_dstPos.PositionXYZStream();
|
||||
if (!m_dstPos.IsPositionValid())
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case TARGET_FLAG_STRING:
|
||||
else
|
||||
m_dstPos.Relocate(caster);
|
||||
|
||||
if(m_targetMask & TARGET_FLAG_STRING)
|
||||
{
|
||||
if (data->rpos() + 1 > data->size())
|
||||
return false;
|
||||
*data >> m_strTarget;
|
||||
break;
|
||||
}
|
||||
*data << m_strTarget;
|
||||
}
|
||||
|
||||
if (!(m_targetMask & TARGET_FLAG_SOURCE_LOCATION))
|
||||
m_srcPos.Relocate(caster);
|
||||
// some spell cast packet including more data (for projectiles?)
|
||||
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))
|
||||
m_dstPos.Relocate(caster);
|
||||
data->rpos(data->wpos()); // prevent spam at ignore packet
|
||||
//MovementInfo movementInfo;
|
||||
//ReadMovementInfo(*data, &movementInfo);
|
||||
}
|
||||
}
|
||||
|
||||
// find real units/GOs
|
||||
Update(caster);
|
||||
@@ -271,51 +281,50 @@ void SpellCastTargets::write (WorldPacket * data)
|
||||
*data << uint32(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)))
|
||||
continue;
|
||||
switch (1<<i)
|
||||
if (m_targetMask & TARGET_FLAG_UNIT)
|
||||
{
|
||||
case TARGET_FLAG_UNIT:
|
||||
if (m_unitTarget)
|
||||
data->append(m_unitTarget->GetPackGUID());
|
||||
else
|
||||
*data << uint8(0);
|
||||
break;
|
||||
case TARGET_FLAG_OBJECT:
|
||||
if (m_GOTarget)
|
||||
}
|
||||
else if (m_targetMask & TARGET_FLAG_OBJECT)
|
||||
{
|
||||
if(m_GOTarget)
|
||||
data->append(m_GOTarget->GetPackGUID());
|
||||
else
|
||||
*data << uint8(0);
|
||||
break;
|
||||
case TARGET_FLAG_CORPSE:
|
||||
case TARGET_FLAG_PVP_CORPSE:
|
||||
}
|
||||
else if (m_targetMask & ( TARGET_FLAG_CORPSE | TARGET_FLAG_PVP_CORPSE))
|
||||
data->appendPackGUID(m_CorpseTargetGUID);
|
||||
break;
|
||||
case TARGET_FLAG_UNK17:
|
||||
else
|
||||
*data << uint8(0);
|
||||
break;
|
||||
case TARGET_FLAG_ITEM:
|
||||
case TARGET_FLAG_TRADE_ITEM:
|
||||
if (m_itemTarget)
|
||||
}
|
||||
|
||||
if (m_targetMask & ( TARGET_FLAG_ITEM | TARGET_FLAG_TRADE_ITEM))
|
||||
{
|
||||
if(m_itemTarget)
|
||||
data->append(m_itemTarget->GetPackGUID());
|
||||
else
|
||||
*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 << m_srcPos.m_positionX << m_srcPos.m_positionY << m_srcPos.m_positionZ;
|
||||
break;
|
||||
case TARGET_FLAG_DEST_LOCATION:
|
||||
*data << m_srcPos.PositionXYZStream();
|
||||
}
|
||||
|
||||
if (m_targetMask & TARGET_FLAG_DEST_LOCATION)
|
||||
{
|
||||
*data << uint8(0); // relative position guid here - transport for example
|
||||
*data << m_dstPos.m_positionX << m_dstPos.m_positionY << m_dstPos.m_positionZ;
|
||||
break;
|
||||
case TARGET_FLAG_STRING:
|
||||
*data << m_dstPos.PositionXYZStream();
|
||||
}
|
||||
|
||||
if (m_targetMask & TARGET_FLAG_STRING)
|
||||
*data << m_strTarget;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
// 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;
|
||||
|
||||
if (target)
|
||||
|
||||
@@ -43,19 +43,19 @@ enum SpellCastTargetFlags
|
||||
TARGET_FLAG_ITEM = 0x00000010, // pguid
|
||||
TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // 3 float
|
||||
TARGET_FLAG_DEST_LOCATION = 0x00000040, // 3 float
|
||||
TARGET_FLAG_OBJECT_UNK = 0x00000080, // used in 7 spells only
|
||||
TARGET_FLAG_CASTER = 0x00000100, // looks like self target (480 spells)
|
||||
TARGET_FLAG_OBJECT_CASTER = 0x00000080, // used in 7 spells only
|
||||
TARGET_FLAG_UNIT_CASTER = 0x00000100, // looks like self target (480 spells)
|
||||
TARGET_FLAG_PVP_CORPSE = 0x00000200, // pguid
|
||||
TARGET_FLAG_UNIT_CORPSE = 0x00000400, // 10 spells (gathering professions)
|
||||
TARGET_FLAG_OBJECT = 0x00000800, // pguid, 2 spells
|
||||
TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid, 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_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_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
|
||||
|
||||
|
||||
@@ -3230,7 +3230,7 @@ bool CanSpellPierceImmuneAura(SpellEntry const * pierceSpell, SpellEntry const *
|
||||
// these spells (Cyclone for example) can pierce all...
|
||||
if ((pierceSpell->AttributesEx & SPELL_ATTR_EX_UNAFFECTED_BY_SCHOOL_IMMUNE)
|
||||
// ...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 false;
|
||||
@@ -3784,7 +3784,7 @@ void SpellMgr::LoadSpellCustomAttr()
|
||||
break;
|
||||
// some dummy spell only has dest, should push caster in this case
|
||||
case 62324: // Throw Passenger
|
||||
spellInfo->Targets |= TARGET_FLAG_CASTER;
|
||||
spellInfo->Targets |= TARGET_FLAG_UNIT_CASTER;
|
||||
count++;
|
||||
break;
|
||||
case 51735: // Ebon Plague
|
||||
|
||||
Reference in New Issue
Block a user