本文整理汇总了C++中SpellCastTargets::read方法的典型用法代码示例。如果您正苦于以下问题:C++ SpellCastTargets::read方法的具体用法?C++ SpellCastTargets::read怎么用?C++ SpellCastTargets::read使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类SpellCastTargets
的用法示例。
在下文中一共展示了SpellCastTargets::read方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: HandleUseItemOpcode
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
Player* p_User = GetPlayer();
Log::getSingleton( ).outDetail("WORLD: got use Item packet, data length = %i\n",recvPacket.size());
uint8 tmp1,slot,tmp3;
uint32 spellId;
recvPacket >> tmp1 >> slot >> tmp3;
Item* tmpItem = new Item;
tmpItem = p_User->GetItemBySlot(slot);
ItemPrototype *itemProto = tmpItem->GetProto();
spellId = itemProto->SpellId[0];
// check for spell id
SpellEntry *spellInfo = sSpellStore.LookupEntry( spellId );
if(!spellInfo)
{
Log::getSingleton( ).outError("WORLD: unknown spell id %i\n", spellId);
return;
}
Spell *spell = new Spell(GetPlayer(), spellInfo,false, 0);
WPAssert(spell);
SpellCastTargets targets;
targets.read(&recvPacket,GetPlayer()->GetGUID());
spell->m_CastItem = tmpItem;
spell->prepare(&targets);
}
示例2: HandleCastSpellOpcode
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
uint32 spellId;
recvPacket >> spellId;
sLog.outDetail("WORLD: got cast spell packet, spellId - %i, data length = %i",
spellId, recvPacket.size());
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
{
sLog.outError("WORLD: unknown spell id %i\n", spellId);
return;
}
if ( !_player->HasSpell (spellId) )
{
//cheater? kick? ban?
return;
}
Spell *spell ;
spell = new Spell(_player, spellInfo, false, 0);
SpellCastTargets targets;
targets.read(&recvPacket,_player);
spell->prepare(&targets);
}
示例3: HandleCastSpellOpcode
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
uint32 spellId;
recvPacket >> spellId;
Log::getSingleton( ).outDetail("WORLD: got cast spell packet, spellId - %i, data length = %i\n",
spellId, recvPacket.size());
// check for spell id
SpellEntry *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
{
Log::getSingleton( ).outError("WORLD: unknown spell id %i\n", spellId);
return;
}
Spell *spell = new Spell(GetPlayer(), spellInfo, false, 0);
WPAssert(spell);
SpellCastTargets targets;
targets.read(&recvPacket,GetPlayer()->GetGUID());
spell->prepare(&targets);
}
示例4: HandleAddDynamicTargetOpcode
void WorldSession::HandleAddDynamicTargetOpcode(WorldPacket & recvPacket)
{
DEBUG_LOG( "WORLD"," got CMSG_PET_CAST_SPELL." );
uint64 guid;
uint8 counter;
uint32 spellid;
uint8 flags;
UnitPointer caster;
SpellCastTargets targets;
SpellEntry *sp;
SpellPointer pSpell;
list<AI_Spell*>::iterator itr;
recvPacket >> guid >> counter >> spellid >> flags;
sp = dbcSpell.LookupEntry(spellid);
// Summoned Elemental's Freeze
if (spellid == 33395)
{
caster = _player->m_Summon;
if( caster && TO_PET(caster)->GetAISpellForSpellId(spellid) == NULL )
return;
}
else
{
caster = _player->m_CurrentCharm;
if( caster != NULL )
{
for(itr = caster->GetAIInterface()->m_spells.begin(); itr != caster->GetAIInterface()->m_spells.end(); ++itr)
{
if( (*itr)->spell->Id == spellid )
break;
}
if( itr == caster->GetAIInterface()->m_spells.end() )
return;
}
}
if( caster == NULL || guid != caster->GetGUID() )
return;
targets.read(recvPacket, _player->GetGUID());
pSpell = SpellPointer(new Spell(caster, sp, false, NULLAURA));
pSpell->prepare(&targets);
}
示例5: HandlePetCastSpell
void WorldSession::HandlePetCastSpell(WorldPacket & recvPacket)
{
CHECK_INWORLD_RETURN
uint64 guid = 0;
uint8 castCount = 0;
uint32 spellid = 0;
uint8 castflags = 0;
uint32 targetmask = 0;
recvPacket >> guid;
recvPacket >> castCount;
recvPacket >> spellid;
recvPacket >> castflags;
SpellEntry* sp = dbcSpell.LookupEntryForced(spellid);
if(sp == NULL)
return;
// Summoned Elemental's Freeze
if(spellid == 33395)
{
if(!_player->GetSummon())
return;
}
else if(guid != _player->m_CurrentCharm)
{
if( _player->GetCharmedUnitGUID() != guid )
return;
}
SpellCastTargets targets;
targets.read( recvPacket, guid );
float missilepitch = 0.0f;
float missilespeed = 0;
uint32 traveltime = 0;
if( castflags & 2 ){
recvPacket >> missilepitch;
recvPacket >> missilespeed;
float dx = targets.m_destX - targets.m_srcX;
float dy = targets.m_destY - targets.m_srcY;
if( ( missilepitch != M_PI / 4 ) && ( missilepitch != -M_PI / 4 ) ) //lets not divide by 0 lul
traveltime = ( sqrtf( dx * dx + dy * dy ) / ( cosf( missilepitch ) * missilespeed ) ) * 1000;
}
示例6: HandleCastSpellOpcode
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
CHECK_PACKET_SIZE(recvPacket,1+4+1);
uint32 spellId;
uint8 cast_count, unk_flags;
recvPacket >> cast_count;
recvPacket >> spellId;
recvPacket >> unk_flags; // flags (if 0x02 - some additional data are received)
sLog.outDebug("WORLD: got cast spell packet, spellId - %u, cast_count: %u, unk_flags %u, data length = %i",
spellId, cast_count, unk_flags, recvPacket.size());
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
{
sLog.outError("WORLD: unknown spell id %u", spellId);
return;
}
// not have spell or spell passive and not casted by client
if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) )
{
//cheater? kick? ban?
return;
}
// client provided targets
SpellCastTargets targets;
if(!targets.read(&recvPacket,_player))
return;
// auto-selection buff level base at target level (in spellInfo)
if(targets.getUnitTarget())
{
SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel());
// 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(actualSpellInfo)
spellInfo = actualSpellInfo;
}
Spell *spell = new Spell(_player, spellInfo, false);
spell->m_cast_count = cast_count; // set count of casts
spell->prepare(&targets);
}
示例7: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
{
sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL");
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;
sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags);
if (!_player->GetPet() && !_player->GetCharm())
return;
Creature* pet = _player->GetMap()->GetCreatureOrPetOrVehicle(guid);
if (!pet || (pet != _player->GetPet() && pet!= _player->GetCharm()))
{
sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
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;
// do not cast not learned spells
if (!pet->HasSpell(spellid) || IsPassiveSpell(spellInfo))
return;
SpellCastTargets targets;
if (!targets.read(&recvPacket,pet))
return;
pet->DoPetCastSpell(GetPlayer(), cast_count, targets, spellInfo );
}
示例8: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket)
{
sLog->outDetail("WORLD: CMSG_PET_CAST_SPELL");
uint64 guid;
uint8 castCount;
uint32 spellId;
uint8 castFlags;
recvPacket >> guid >> castCount >> spellId >> castFlags;
sLog->outDebug("WORLD: CMSG_PET_CAST_SPELL, guid: " UI64FMTD ", castCount: %u, spellId %u, castFlags %u", guid, castCount, spellId, castFlags);
// This opcode is also sent from charmed and possessed units (players and creatures)
if (!_player->GetGuardianPet() && !_player->GetCharm())
return;
Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
if (!caster || (caster != _player->GetGuardianPet() && caster != _player->GetCharm()))
{
sLog->outError("HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .", uint32(GUID_LOPART(guid)),GetPlayer()->GetName());
return;
}
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId);
if (!spellInfo)
{
sLog->outError("WORLD: unknown PET spell id %i", spellId);
return;
}
if (spellInfo->StartRecoveryCategory > 0) // Check if spell is affected by GCD
if (caster->GetTypeId() == TYPEID_UNIT && caster->ToCreature()->GetGlobalCooldown() > 0)
{
caster->SendPetCastFail(spellId, SPELL_FAILED_NOT_READY);
return;
}
// do not cast not learned spells
if (!caster->HasSpell(spellId) || IsPassiveSpell(spellId))
return;
SpellCastTargets targets;
targets.read(recvPacket, caster);
HandleClientCastFlags(recvPacket, castFlags, targets);
caster->ClearUnitState(UNIT_STAT_FOLLOW);
Spell *spell = new Spell(caster, spellInfo, false);
spell->m_cast_count = castCount; // probably pending spell cast
spell->m_targets = targets;
// TODO: need to check victim?
SpellCastResult result;
if (caster->m_movedPlayer)
result = spell->CheckPetCast(caster->m_movedPlayer->GetSelectedUnit());
else
result = spell->CheckPetCast(NULL);
if (result == SPELL_CAST_OK)
{
if (caster->GetTypeId() == TYPEID_UNIT)
{
Creature* pet = caster->ToCreature();
pet->AddCreatureSpellCooldown(spellId);
if (pet->isPet())
{
Pet* p = (Pet*)pet;
// 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 (p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid);
}
}
spell->prepare(&(spell->m_targets));
}
else
{
caster->SendPetCastFail(spellId, result);
if (caster->GetTypeId() == TYPEID_PLAYER)
{
if (!caster->ToPlayer()->HasSpellCooldown(spellId))
GetPlayer()->SendClearCooldown(spellId, caster);
}
else
{
if (!caster->ToCreature()->HasSpellCooldown(spellId))
GetPlayer()->SendClearCooldown(spellId, caster);
}
spell->finish(false);
delete spell;
}
}
示例9: HandleUseItemOpcode
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
// TODO: add targets.read() check
Player* pUser = _player;
// ignore for remote control state
if (pUser->m_mover != pUser)
return;
uint8 bagIndex, slot;
uint8 unk_flags; // flags (if 0x02 - some additional data are received)
uint8 cast_count; // next cast if exists (single or not)
uint64 item_guid;
uint32 glyphIndex; // something to do with glyphs?
uint32 spellid; // casted spell id
recvPacket >> bagIndex >> slot >> cast_count >> spellid >> item_guid >> glyphIndex >> unk_flags;
Item *pItem = pUser->GetUseableItemByPos(bagIndex, slot);
if (!pItem)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
return;
}
if (pItem->GetGUID() != item_guid)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
return;
}
sLog.outDetail("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());
ItemPrototype const *proto = pItem->GetProto();
if (!proto)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
return;
}
// some item classes can be used only in equipped state
if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
return;
}
uint8 msg = pUser->CanUseItem(pItem);
if ( msg != EQUIP_ERR_OK )
{
pUser->SendEquipError( msg, 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_FLAGS_USEABLE_IN_ARENA) &&
pUser->InArena())
{
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))
{
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,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;
if (!targets.read(&recvPacket, pUser))
return;
targets.Update(pUser);
if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget()))
{
// free gray item after use fail
pUser->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);
// send spell error
//.........这里部分代码省略.........
示例10: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
{
sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL");
CHECK_PACKET_SIZE(recvPacket,8+1+4+1);
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;
sLog.outDebug("WORLD: CMSG_PET_CAST_SPELL, cast_count: %u, spellid %u, unk_flags %u", cast_count, spellid, unk_flags);
if(!_player->GetPet() && !_player->GetCharm())
return;
if (GUID_HIPART(guid) == HIGHGUID_PLAYER)
return;
Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player,guid);
if(!pet || (pet != _player->GetPet() && pet!= _player->GetCharm()))
{
sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
return;
}
if (pet->GetGlobalCooldown() > 0)
return;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid);
if(!spellInfo)
{
sLog.outError("WORLD: unknown PET spell id %i\n", spellid);
return;
}
// do not cast not learned spells
if(!pet->HasSpell(spellid) || IsPassiveSpell(spellid))
return;
SpellCastTargets targets;
if(!targets.read(&recvPacket,pet))
return;
pet->clearUnitState(UNIT_STAT_FOLLOW);
Spell *spell = new Spell(pet, spellInfo, false);
spell->m_cast_count = cast_count; // probably pending spell cast
spell->m_targets = targets;
int16 result = spell->PetCanCast(NULL);
if(result == -1)
{
pet->AddCreatureSpellCooldown(spellid);
if(pet->isPet())
{
Pet* p = (Pet*)pet;
p->CheckLearning(spellid);
//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(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid);
}
spell->prepare(&(spell->m_targets));
}
else
{
pet->SendPetCastFail(spellid, result);
if(!pet->HasSpellCooldown(spellid))
pet->SendPetClearCooldown(spellid);
spell->finish(false);
delete spell;
}
}
示例11: 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 = _player->m_mover;
if (mover != _player && mover->GetTypeId() == TYPEID_PLAYER)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
sLog.outDebug("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;
}
if (mover->GetTypeId() == TYPEID_PLAYER)
{
// not have spell in spellbook or spell passive and not casted by client
if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(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(spellId) )
{
//cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
// Client is resending autoshot cast opcode when other spell is casted during shoot rotation
// Skip it to prevent "interrupt" message
if (IsAutoRepeatRangedSpell(spellInfo) && _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)
&& _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->m_spellInfo == spellInfo)
return;
// can't use our own spells when we're in possession of another unit,
if (_player->isPossessing())
return;
// client provided targets
SpellCastTargets targets;
if (!targets.read(&recvPacket,mover))
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
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);
}
}
示例12: HandleUseItemOpcode
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
// TODO: add targets.read() check
CHECK_PACKET_SIZE(recvPacket,1+1+1);
sLog.outDetail("WORLD: CMSG_USE_ITEM packet, data length = %i",recvPacket.size());
Player* pUser = _player;
uint8 bagIndex, slot, tmp3;
recvPacket >> bagIndex >> slot >> tmp3;
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
if(!pItem)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
return;
}
ItemPrototype const *proto = pItem->GetProto();
if(!proto)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL );
return;
}
uint8 msg = pUser->CanUseItem(pItem);
if( msg != EQUIP_ERR_OK )
{
pUser->SendEquipError( msg, pItem, NULL );
return;
}
if (pUser->isInCombat())
{
for(int i = 0; i <5; ++i)
{
if (IsNonCombatSpell(proto->Spells[i].SpellId))
{
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT,pItem,NULL);
return;
}
}
}
// check also BIND_WHEN_PICKED_UP 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)
{
if (!pItem->IsSoulBound())
{
pItem->SetState(ITEM_CHANGED, pUser);
pItem->SetBinding( true );
}
}
SpellCastTargets targets;
if(!targets.read(&recvPacket, pUser))
return;
//Note: If script stop casting it must send appropriate data to client to prevent stuck item in gray state.
if(!Script->ItemUse(pUser,pItem,targets))
{
// no script or script not process request by self
// use triggered flag only for items with many spell casts and for not first cast
int count = 0;
for(int i = 0; i <5; ++i)
{
_Spell const& spellData = pItem->GetProto()->Spells[i];
// no spell
if(!spellData.SpellId)
continue;
// wrong triggering type
if( spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_USE && spellData.SpellTrigger != ITEM_SPELLTRIGGER_ON_NO_DELAY_USE)
continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellData.SpellId);
if(!spellInfo)
{
sLog.outError("Item (Entry: %u) in have wrong spell id %u, ignoring ",proto->ItemId, spellData.SpellId);
continue;
}
Spell *spell = new Spell(pUser, spellInfo, (count > 0) , 0);
spell->m_CastItem = pItem;
spell->prepare(&targets);
++count;
}
}
}
示例13: HandleCastSpellOpcode
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
CHECK_PACKET_SIZE(recvPacket,4+2);
uint32 spellId;
recvPacket >> spellId;
sLog.outDetail("WORLD: got cast spell packet, spellId - %i, data length = %i",
spellId, recvPacket.size());
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId );
if(!spellInfo)
{
sLog.outError("WORLD: unknown spell id %i\n", spellId);
return;
}
// not have spell or spell passive and not casted by client
if ( !_player->HasSpell (spellId) || IsPassiveSpell(spellId) )
{
//cheater? kick? ban?
return;
}
// client provided targets
SpellCastTargets targets;
if(!targets.read(&recvPacket,_player))
return;
// auto-selection buff level base at target level (in spellInfo)
if(!IsPassiveSpell(spellId) && targets.getUnitTarget())
{
bool needRankSelection = false;
for(int i=0;i<3;i++)
{
if(IsPositiveEffect(spellId, i) && spellInfo->Effect[i] == SPELL_EFFECT_APPLY_AURA)
{
needRankSelection = true;
break;
}
}
if(needRankSelection)
{
for(uint32 nextSpellId = spellId; nextSpellId!=0; nextSpellId = objmgr.GetPrevSpellInChain(nextSpellId))
{
SpellEntry const *nextSpellInfo = sSpellStore.LookupEntry(nextSpellId);
if(!nextSpellInfo)
break;
// if found appropriate level
if(targets.getUnitTarget()->getLevel() + 10 >= nextSpellInfo->spellLevel)
{
SpellEntry const *spellInfo = sSpellStore.LookupEntry(nextSpellId);
break;
}
}
// if appropriate spell rank not found spellInfo store original casted spell and will output error in Spell::CanCast
}
}
Spell *spell = new Spell(_player, spellInfo, false, 0);
spell->prepare(&targets);
}
示例14: HandlePetCastSpellOpcode
void WorldSession::HandlePetCastSpellOpcode( WorldPacket& recvPacket )
{
sLog.outDetail("WORLD: CMSG_PET_CAST_SPELL");
CHECK_PACKET_SIZE(recvPacket,8+4);
uint64 guid;
uint32 spellid;
recvPacket >> guid >> spellid;
// This opcode is also sent from charmed and possessed units (players and creatures)
if(!_player->GetPet() && !_player->GetCharm())
return;
Unit* caster = ObjectAccessor::GetUnit(*_player, guid);
if(!caster || (caster != _player->GetPet() && caster != _player->GetCharm()))
{
sLog.outError( "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s .\n", uint32(GUID_LOPART(guid)),GetPlayer()->GetName() );
return;
}
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellid);
if(!spellInfo)
{
sLog.outError("WORLD: unknown PET spell id %i\n", spellid);
return;
}
// do not cast not learned spells
if(!caster->HasSpell(spellid) || IsPassiveSpell(spellid))
return;
if (spellInfo->StartRecoveryCategory > 0) //Check if spell is affected by GCD
if (caster->GetTypeId() == TYPEID_UNIT && ((Creature*)caster)->GetGlobalCooldown() > 0)
{
caster->SendPetCastFail(spellid, SPELL_FAILED_NOT_READY);
return;
}
SpellCastTargets targets;
if(!targets.read(&recvPacket,caster))
return;
caster->clearUnitState(UNIT_STAT_FOLLOW);
Spell *spell = new Spell(caster, spellInfo, spellid == 33395); // water elemental can cast freeze as triggered
spell->m_targets = targets;
int16 result = spell->PetCanCast(NULL);
if(result == -1)
{
if(caster->GetTypeId() == TYPEID_UNIT)
{
Creature* pet = (Creature*)caster;
pet->AddCreatureSpellCooldown(spellid);
if(pet->isPet())
{
Pet* p = (Pet*)pet;
p->CheckLearning(spellid);
// 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(p->getPetType() == SUMMON_PET && (urand(0, 100) < 10))
pet->SendPetTalk((uint32)PET_TALK_SPECIAL_SPELL);
else
pet->SendPetAIReaction(guid);
}
}
spell->prepare(&(spell->m_targets));
}
else
{
caster->SendPetCastFail(spellid, result);
if(caster->GetTypeId() == TYPEID_PLAYER)
{
if(!((Player*)caster)->HasSpellCooldown(spellid))
caster->SendPetClearCooldown(spellid);
}
else
{
if(!((Creature*)caster)->HasSpellCooldown(spellid))
caster->SendPetClearCooldown(spellid);
}
spell->finish(false);
delete spell;
}
}
示例15: 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 = _player->m_mover;
if(mover != _player && mover->GetTypeId()==TYPEID_PLAYER)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
// vehicle spells are handled by CMSG_PET_CAST_SPELL,
// but player is still able to cast own spells
if(_player->GetCharmGUID() && _player->GetCharmGUID() == _player->GetVehicleGUID())
mover = _player;
sLog.outDebug("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;
}
if(mover->GetTypeId()==TYPEID_PLAYER)
{
// not have spell in spellbook or spell passive and not casted by client
if (!((Player*)mover)->HasActiveSpell (spellId) || IsPassiveSpell(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(spellId) )
{
//cheater? kick? ban?
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
return;
}
}
// client provided targets
SpellCastTargets targets;
if(!targets.read(&recvPacket,mover))
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at ignore packet
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?
recvPacket.read_skip<uint8>(); // >> 1
recvPacket.read_skip<uint32>(); // >> MSG_MOVE_STOP
MovementInfo movementInfo;
ReadMovementInfo(recvPacket, &movementInfo);
}
// auto-selection buff level base at target level (in spellInfo)
if(targets.getUnitTarget())
{
SpellEntry const *actualSpellInfo = spellmgr.SelectAuraRankForPlayerLevel(spellInfo,targets.getUnitTarget()->getLevel());
// 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(actualSpellInfo)
spellInfo = actualSpellInfo;
}
Spell *spell = new Spell(mover, spellInfo, false);
spell->m_cast_count = cast_count; // set count of casts
spell->prepare(&targets);
}