本文整理汇总了C++中SpellCastTargets::ReadAdditionalData方法的典型用法代码示例。如果您正苦于以下问题:C++ SpellCastTargets::ReadAdditionalData方法的具体用法?C++ SpellCastTargets::ReadAdditionalData怎么用?C++ SpellCastTargets::ReadAdditionalData使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SpellCastTargets
的用法示例。
在下文中一共展示了SpellCastTargets::ReadAdditionalData方法的9个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
DETAIL_LOG("WORLD: CMSG_PET_CAST_SPELL");
ObjectGuid guid;
uint32 spellid;
uint8 cast_count;
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
recvPacket >> guid >> cast_count >> spellid >> unk_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);
Creature* pet = GetPlayer()->GetMap()->GetAnyTypeCreature(guid);
if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
{
sLog.outError("HandlePetCastSpellOpcode: %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str());
return;
}
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(pet);
// some spell cast packet including more data (for projectiles?)
if (unk_flags & 0x02)
targets.ReadAdditionalData(recvPacket);
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
if (!spellInfo)
{
sLog.outError("WORLD: unknown PET spell id %i", spellid);
return;
}
if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
return;
bool triggered = bool(pet->GetTriggeredByClientAura(spellid));
// do not cast not learned spells
if ((!pet->HasSpell(spellid) && !triggered)
|| IsPassiveSpell(spellInfo))
return;
if (pet->IsNonMeleeSpellCasted(false) && !triggered)
pet->InterruptNonMeleeSpells(false);
if (pet->IsPet() || pet->isCharmed())
GetPlayer()->CallForAllControlledUnits(DoPetCastWithHelper(GetPlayer(), cast_count, &targets, spellInfo ),CONTROLLED_PET|CONTROLLED_GUARDIANS|CONTROLLED_CHARM);
}
示例2: HandleCastSpellOpcode
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
uint32 spellId, glyphIndex;
uint8 cast_count, cast_flags;
recvPacket >> cast_count;
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();
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, cast_flags %u, data length = " SIZEFMTD,
spellId, cast_count, cast_flags, recvPacket.size());
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
if (!spellInfo)
{
sLog.outError("WORLD: unknown spell id %u", spellId);
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
if (mover->GetTypeId() == TYPEID_PLAYER)
{
// not have spell in spellbook or spell passive and not casted by client
if (!((Player*)mover)->HasActiveSpell(spellId) || IsPassiveSpell(spellInfo))
{
sLog.outError("World: Player %u casts spell %u which he shouldn't have", mover->GetGUIDLow(), spellId);
// cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
else
{
// not have spell in spellbook or spell passive and not casted by client
if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellInfo))
{
// cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
// client provided targets
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(mover);
targets.ReadAdditionalData(recvPacket, cast_flags);
// auto-selection buff level base at target level (in spellInfo)
if (Unit* target = targets.getUnitTarget())
{
// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
if (SpellEntry const* actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
spellInfo = actualSpellInfo;
}
Spell* spell = new Spell(mover, spellInfo, false);
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex;
spell->prepare(&targets);
}
示例3: HandleUseItemOpcode
//.........这里部分代码省略.........
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL);
return;
}
InventoryResult msg = pUser->CanUseItem(pItem);
if (msg != EQUIP_ERR_OK)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(msg, pItem, NULL);
return;
}
// not allow use item from trade (cheat way only)
if (pItem->IsInTrade())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL);
return;
}
// only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB)
if (proto->Class == ITEM_CLASS_CONSUMABLE &&
!(proto->Flags & ITEM_FLAG_USEABLE_IN_ARENA) &&
pUser->InArena())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, NULL);
return;
}
if (pUser->isInCombat())
{
for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(proto->Spells[i].SpellId))
{
if (IsNonCombatSpell(spellInfo))
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, NULL);
return;
}
}
}
// Prevent potion drink if another potion in processing (client have potions disabled in like case)
if (pItem->IsPotion() && pUser->GetLastPotionId())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_OBJECT_IS_BUSY, pItem, NULL);
return;
}
}
// check also BIND_WHEN_PICKED_UP and BIND_QUEST_ITEM for .additem or .additemset case by GM (not binded at adding to inventory)
if (pItem->GetProto()->Bonding == BIND_WHEN_USE || pItem->GetProto()->Bonding == BIND_WHEN_PICKED_UP || pItem->GetProto()->Bonding == BIND_QUEST_ITEM)
{
if (!pItem->IsSoulBound())
{
pItem->SetState(ITEM_CHANGED, pUser);
pItem->SetBinding(true);
}
}
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(pUser);
targets.Update(pUser);
targets.ReadAdditionalData(recvPacket, cast_flags);
if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget()))
{
// free gray item after use fail
pUser->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);
// send spell error
if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid))
{
SpellEffectEntry const* spellEffect = spellInfo->GetSpellEffect(EFFECT_INDEX_0);
// for implicit area/coord target spells
if (spellEffect && (IsPointEffectTarget(Targets(spellEffect->EffectImplicitTargetA)) ||
IsAreaEffectTarget(Targets(spellEffect->EffectImplicitTargetA))))
Spell::SendCastResult(_player,spellInfo,cast_count,SPELL_FAILED_NO_VALID_TARGETS);
// for explicit target spells
else
Spell::SendCastResult(_player, spellInfo, cast_count, SPELL_FAILED_BAD_TARGETS);
}
return;
}
// Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
if (!sScriptMgr.OnItemUse(pUser, pItem, targets))
{
// no script or script not process request by self
pUser->CastItemUseSpell(pItem, targets, cast_count, glyphIndex);
}
}
示例4: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
DETAIL_LOG("WORLD: CMSG_PET_CAST_SPELL");
ObjectGuid guid;
uint32 spellid;
uint8 cast_count;
uint8 cast_flags; // flags (if 0x02 - some additional data are received)
recvPacket >> guid >> cast_count >> spellid >> cast_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);
if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
{
sLog.outError("HandlePetCastSpellOpcode: %s isn't pet of %s .", guid.GetString().c_str(), _player->GetGuidStr().c_str());
return;
}
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
if (!spellInfo)
{
sLog.outError("WORLD: unknown PET spell id %i", spellid);
return;
}
if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
return;
Aura* triggeredByAura = pet->GetTriggeredByClientAura(spellid);
// do not cast not learned spells
if ((!triggeredByAura && !pet->HasSpell(spellid)) || IsPassiveSpell(spellInfo))
return;
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(pet);
targets.ReadAdditionalData(recvPacket, cast_flags);
pet->clearUnitState(UNIT_STAT_MOVING);
Spell* spell = new Spell(pet, spellInfo, triggeredByAura ? true : false, pet->GetObjectGuid(), triggeredByAura ? triggeredByAura->GetSpellProto() : nullptr);
spell->m_cast_count = cast_count; // probably pending spell cast
spell->m_targets = targets;
SpellCastResult result = triggeredByAura ? SPELL_CAST_OK : spell->CheckPetCast(nullptr);
if (result == SPELL_CAST_OK)
{
pet->AddCreatureSpellCooldown(spellid);
spell->SpellStart(&(spell->m_targets), triggeredByAura);
}
else
{
Unit* owner = pet->GetCharmerOrOwner();
if (owner && owner->GetTypeId() == TYPEID_PLAYER && !triggeredByAura)
Spell::SendCastResult((Player*)owner, spellInfo, 0, result, true);
if (!pet->HasSpellCooldown(spellid) && !triggeredByAura)
GetPlayer()->SendClearCooldown(spellid, pet);
spell->finish(false);
delete spell;
}
}
示例5: HandleCastSpellOpcode
//.........这里部分代码省略.........
}
Unit::AuraList const& m363auras = mover->GetAurasByType(SPELL_AURA_363);
for (Unit::AuraList::const_iterator itr = m363auras.begin(); itr != m363auras.end(); ++itr)
{
if ((*itr)->GetSpellEffect()->EffectTriggerSpell == spellId)
{
triggered = true;
mover->RemoveSpellAuraHolder((*itr)->GetHolder());
break;
}
}
if (!spellInfo->HasAttribute(SPELL_ATTR_EX8_RAID_MARKER))
{
if (mover->GetTypeId()==TYPEID_PLAYER)
{
// not have spell in spellbook or spell passive and not casted by client
if ((!((Player*)mover)->HasActiveSpell(spellId) && !triggered || IsPassiveSpell(spellInfo)) && !sSpellMgr.IsAbilityOfSkillType(spellInfo, SKILL_ARCHAEOLOGY))
{
sLog.outError("WorldSession::HandleCastSpellOpcode: %s casts spell %u which he shouldn't have", mover->GetObjectGuid().GetString().c_str(), spellId);
//cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
else
{
// not have spell in spellbook or spell passive and not casted by client
if (!((Creature*)mover)->HasSpell(spellId) && !triggered || IsPassiveSpell(spellInfo))
{
sLog.outError("World: Player %u casts spell %u which he shouldn't have", mover->GetGUIDLow(), spellId);
//cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
}
Unit::AuraList swaps = _mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
Unit::AuraList const& swaps2 = _mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2);
if (!swaps2.empty())
swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());
for (Unit::AuraList::const_iterator itr = swaps.begin(); itr != swaps.end(); ++itr)
{
if ((*itr)->isAffectedOnSpell(spellInfo))
{
if (SpellEntry const* newInfo = sSpellStore.LookupEntry((*itr)->GetModifier()->m_amount))
{
spellInfo = newInfo;
spellId = newInfo->Id;
// Force triggered to spells mirrored by Dark Simulacrum
if ((*itr)->GetId() == 77616)
triggered = true;
}
break;
}
}
// Lifebloom
if (spellId == 33763)
{
// search Tree of Life (Passive)
if (Aura* aura = _mover->GetAura(81098, EFFECT_INDEX_1))
{
if (SpellEntry const* newInfo = sSpellStore.LookupEntry(aura->GetModifier()->m_amount))
{
spellInfo = newInfo;
spellId = newInfo->Id;
}
}
}
// client provided targets
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(mover);
targets.ReadAdditionalData(recvPacket, cast_flags);
// Multi-Shot hack
if (!targets.getUnitTarget() && spellId == 2643)
{
if (Unit* target = _player->GetMap()->GetUnit(_player->GetSelectionGuid()))
targets.setUnitTarget(target);
}
// auto-selection buff level base at target level (in spellInfo)
if (Unit* target = targets.getUnitTarget())
{
// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
spellInfo = actualSpellInfo;
}
Spell *spell = new Spell(mover, spellInfo, triggered, mover->GetObjectGuid(), triggeredBy);
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex;
spell->prepare(&targets, triggeredByAura);
}
示例6: HandleCastSpellOpcode
//.........这里部分代码省略.........
if(!spellInfo)
{
sLog.outError("WORLD: unknown spell id %u", spellId);
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
// Players on vehicles may cast many simple spells (like knock) from self
Unit* mover = NULL;
if (spellInfo->HasAttribute(SPELL_ATTR_EX6_CASTABLE_ON_VEHICLE) && _mover->IsCharmerOrOwnerPlayerOrPlayerItself())
mover = _mover->GetCharmerOrOwnerPlayerOrPlayerItself();
else
mover = _mover;
// casting own spells on some vehicles
if (mover->IsVehicle() && mover->GetCharmerOrOwnerPlayerOrPlayerItself())
{
Player *plr = mover->GetCharmerOrOwnerPlayerOrPlayerItself();
if (mover->GetVehicleKit()->GetSeatInfo(plr) &&
((mover->GetVehicleKit()->GetSeatInfo(plr)->m_flags & SEAT_FLAG_CAN_ATTACK) ||
(mover->GetVehicleKit()->GetSeatInfo(plr)->m_flags & SEAT_FLAG_CAN_CAST) ))
mover = plr;
}
bool triggered = false;
SpellEntry const* triggeredBy = NULL;
Aura const* triggeredByAura = mover->GetTriggeredByClientAura(spellId);
if (triggeredByAura)
{
triggered = true;
triggeredBy = triggeredByAura->GetSpellProto();
cast_count = 0;
}
if (mover->GetTypeId()==TYPEID_PLAYER)
{
// not have spell in spellbook or spell passive and not casted by client
if (((((Player*)mover)->GetUInt16Value(PLAYER_FIELD_BYTES2, 0) == 0 &&
(!((Player*)mover)->HasActiveSpell(spellId) && !triggered))
|| IsPassiveSpell(spellInfo)) && spellId != 1843)
{
sLog.outError("WorldSession::HandleCastSpellOpcode: %s casts spell %u which he shouldn't have", mover->GetObjectGuid().GetString().c_str(), spellId);
//cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
else
{
// not have spell in spellbook or spell passive and not casted by client
if ((!((Creature*)mover)->HasSpell(spellId) && !triggered)
|| IsPassiveSpell(spellInfo))
{
sLog.outError("WorldSession::HandleCastSpellOpcode: %s try casts spell %u which he shouldn't have", mover->GetObjectGuid().GetString().c_str(), spellId);
//cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
Unit::AuraList swaps = mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
Unit::AuraList const& swaps2 = mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2);
if (!swaps2.empty())
swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());
for (Unit::AuraList::const_iterator itr = swaps.begin(); itr != swaps.end(); ++itr)
{
if ((*itr)->isAffectedOnSpell(spellInfo))
{
if (SpellEntry const* newInfo = sSpellStore.LookupEntry((*itr)->GetModifier()->m_amount))
{
spellInfo = newInfo;
spellId = newInfo->Id;
}
break;
}
}
// client provided targets
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(mover);
targets.ReadAdditionalData(recvPacket, cast_flags);
// auto-selection buff level base at target level (in spellInfo)
if (Unit* target = targets.getUnitTarget())
{
// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
spellInfo = actualSpellInfo;
}
Spell *spell = new Spell(mover, spellInfo, triggered, mover->GetObjectGuid(), triggeredBy);
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex;
spell->prepare(&targets, triggeredByAura);
}
示例7: HandleCastSpellOpcode
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
uint32 spellId, glyphIndex;
uint8 cast_count, cast_flags;
recvPacket >> cast_count;
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();
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u, cast_flags %u, data length = " SIZEFMTD,
spellId, cast_count, cast_flags, recvPacket.size());
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellId);
if (!spellInfo)
{
sLog.outError("WORLD: unknown spell id %u", spellId);
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
Aura* triggeredByAura = mover->GetTriggeredByClientAura(spellId);
if (mover->GetTypeId() == TYPEID_PLAYER)
{
// not have spell in spellbook or spell passive and not casted by client
if ((!((Player*)mover)->HasActiveSpell(spellId) && !triggeredByAura) || IsPassiveSpell(spellInfo))
{
sLog.outError("World: %s casts spell %u which he shouldn't have", mover->GetGuidStr().c_str(), spellId);
// cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
else
{
// not have spell in spellbook or spell passive and not casted by client
if (!((Creature*)mover)->HasSpell(spellId) || IsPassiveSpell(spellInfo))
{
// cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
Unit::AuraList swaps = mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS);
Unit::AuraList const& swaps2 = mover->GetAurasByType(SPELL_AURA_OVERRIDE_ACTIONBAR_SPELLS_2);
if (!swaps2.empty())
swaps.insert(swaps.end(), swaps2.begin(), swaps2.end());
for (Unit::AuraList::const_iterator itr = swaps.begin(); itr != swaps.end(); ++itr)
{
if ((*itr)->isAffectedOnSpell(spellInfo))
{
if (SpellEntry const* newInfo = sSpellStore.LookupEntry((*itr)->GetModifier()->m_amount))
{
spellInfo = newInfo;
spellId = newInfo->Id;
}
break;
}
}
// client provided targets
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(mover);
targets.ReadAdditionalData(recvPacket, cast_flags);
// auto-selection buff level base at target level (in spellInfo)
if (Unit* target = targets.getUnitTarget())
{
// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
if (SpellEntry const* actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
spellInfo = actualSpellInfo;
}
Spell* spell = new Spell(mover, spellInfo, triggeredByAura ? true : false, mover->GetObjectGuid(), triggeredByAura ? triggeredByAura->GetSpellProto() : NULL);
spell->m_cast_count = cast_count; // set count of casts
spell->m_glyphIndex = glyphIndex;
spell->prepare(&targets, triggeredByAura);
}
示例8: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
DETAIL_LOG("WORLD: CMSG_PET_CAST_SPELL");
ObjectGuid guid;
uint32 spellid;
uint8 cast_count;
uint8 cast_flags; // flags (if 0x02 - some additional data are received)
recvPacket >> guid >> cast_count >> spellid >> cast_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);
if (!pet || (guid != _player->GetPetGuid() && guid != _player->GetCharmGuid()))
{
sLog.outError("HandlePetCastSpellOpcode: %s isn't pet of %s .", guid.GetString().c_str(), GetPlayer()->GetGuidStr().c_str());
return;
}
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid);
if (!spellInfo)
{
sLog.outError("WORLD: unknown PET spell id %i", spellid);
return;
}
if (pet->GetCharmInfo() && pet->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
return;
Aura* triggeredByAura = pet->GetTriggeredByClientAura(spellid);
// do not cast not learned spells
if ((!triggeredByAura && !pet->HasSpell(spellid)) || IsPassiveSpell(spellInfo))
return;
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(pet);
targets.ReadAdditionalData(recvPacket, cast_flags);
pet->clearUnitState(UNIT_STAT_MOVING);
Spell* spell = new Spell(pet, spellInfo, triggeredByAura ? true : false, pet->GetObjectGuid(), triggeredByAura ? triggeredByAura->GetSpellProto() : NULL);
spell->m_cast_count = cast_count; // probably pending spell cast
spell->m_targets = targets;
SpellCastResult result = triggeredByAura ? SPELL_CAST_OK : spell->CheckPetCast(NULL);
if (result == SPELL_CAST_OK)
{
pet->AddCreatureSpellCooldown(spellid);
if (pet->IsPet())
{
// 10% chance to play special pet attack talk, else growl
// actually this only seems to happen on special spells, fire shield for imp, torment for voidwalker, but it's stupid to check every spell
if (((Pet*)pet)->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction();
}
spell->prepare(&(spell->m_targets), triggeredByAura);
}
else
{
Unit* owner = pet->GetCharmerOrOwner();
if (owner && owner->GetTypeId() == TYPEID_PLAYER && !triggeredByAura)
Spell::SendCastResult((Player*)owner, spellInfo, 0, result, true);
if (!pet->HasSpellCooldown(spellid) && !triggeredByAura)
GetPlayer()->SendClearCooldown(spellid, pet);
spell->finish(false);
delete spell;
}
}
示例9: HandleCastSpellOpcode
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
uint32 spellId;
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 = GetPlayer()->GetMover();
if (_mover != GetPlayer() && _mover->GetTypeId()==TYPEID_PLAYER)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
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());
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
{
sLog.outError("WORLD: unknown spell id %u", spellId);
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
// Players on vehicles may cast many simple spells (like knock) from self
Unit* mover = NULL;
if (spellInfo->AttributesEx6 & SPELL_ATTR_EX6_CASTABLE_ON_VEHICLE && _mover->IsCharmerOrOwnerPlayerOrPlayerItself())
mover = _mover->GetCharmerOrOwnerPlayerOrPlayerItself();
else
mover = _mover;
// casting own spells on some vehicles
if (mover->GetObjectGuid().IsVehicle() && mover->GetCharmerOrOwnerPlayerOrPlayerItself())
{
Player *plr = mover->GetCharmerOrOwnerPlayerOrPlayerItself();
if (mover->GetVehicleKit()->GetSeatInfo(plr) &&
(mover->GetVehicleKit()->GetSeatInfo(plr)->m_flags & SEAT_FLAG_CAN_ATTACK ||
mover->GetVehicleKit()->GetSeatInfo(plr)->m_flags & SEAT_FLAG_CAN_CAST ))
mover = plr;
}
bool triggered = false;
SpellEntry const* triggeredBy = NULL;
Aura* triggeredByAura = mover->GetTriggeredByClientAura(spellId);
if (triggeredByAura)
{
triggered = true;
triggeredBy = triggeredByAura->GetSpellProto();
cast_count = 0;
}
if (mover->GetTypeId()==TYPEID_PLAYER)
{
// not have spell in spellbook or spell passive and not casted by client
if (((((Player*)mover)->GetUInt16Value(PLAYER_FIELD_BYTES2, 0) == 0 &&
(!((Player*)mover)->HasActiveSpell(spellId) && !triggered))
|| IsPassiveSpell(spellInfo)) && spellId != 1843)
{
sLog.outError("WorldSession::HandleCastSpellOpcode: %s casts spell %u which he shouldn't have", mover->GetObjectGuid().GetString().c_str(), spellId);
//cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
else
{
// not have spell in spellbook or spell passive and not casted by client
if ((!((Creature*)mover)->HasSpell(spellId) && !triggered)
|| IsPassiveSpell(spellInfo))
{
sLog.outError("WorldSession::HandleCastSpellOpcode: %s try casts spell %u which he shouldn't have", mover->GetObjectGuid().GetString().c_str(), spellId);
//cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
// client provided targets
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(mover);
// some spell cast packet including more data (for projectiles?)
if (unk_flags & 0x02)
targets.ReadAdditionalData(recvPacket);
// auto-selection buff level base at target level (in spellInfo)
if (Unit* target = targets.getUnitTarget())
{
// if rank not found then function return NULL but in explicit cast case original spell can be casted and later failed with appropriate error message
if (SpellEntry const *actualSpellInfo = sSpellMgr.SelectAuraRankForLevel(spellInfo, target->getLevel()))
spellInfo = actualSpellInfo;
}
//.........这里部分代码省略.........