本文整理汇总了C++中IsNonCombatSpell函数的典型用法代码示例。如果您正苦于以下问题:C++ IsNonCombatSpell函数的具体用法?C++ IsNonCombatSpell怎么用?C++ IsNonCombatSpell使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了IsNonCombatSpell函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: GetSpellType
uint32 PetAI::GetSpellType(PetAutoSpellType type)
{
if (type >= PET_SPELL_MAX || m_spellType[type].empty())
return 0;
std::vector<uint32> tmpSet;
for (Unit::SpellIdSet::const_iterator itr = m_spellType[type].begin(); itr != m_spellType[type].end(); ++itr)
{
uint32 _spellID = *itr;
if (!_spellID)
continue;
SpellEntry const* spellInfo = sSpellStore.LookupEntry(_spellID);
if (!spellInfo)
continue;
if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
if (m_creature->HasSpellCooldown(spellInfo))
continue;
if (IsInCombat() && IsNonCombatSpell(spellInfo))
continue;
if (!IsInCombat() && IsPositiveSpell(spellInfo) && !IsNonCombatSpell(spellInfo))
{
int32 duration = GetSpellDuration(spellInfo);
// if ((spellInfo->manaCost || spellInfo->ManaCostPercentage || spellInfo->manaPerSecond) && duration > 0)
// continue;
// allow only spell without cooldown > duration
int32 cooldown = GetSpellRecoveryTime(spellInfo);
if (cooldown >= 0 && duration >= 0 && cooldown > duration)
continue;
}
tmpSet.push_back(_spellID);
}
if (tmpSet.empty())
return 0;
else
return tmpSet[urand(0, tmpSet.size() - 1)];
}
示例2: DEBUG_LOG
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket)
{
uint32 spellId;
uint8 cast_count;
recvPacket >> spellId;
recvPacket >> cast_count;
DEBUG_LOG("WORLD: got cast spell packet, spellId - %u, cast_count: %u data length = %i",
spellId, cast_count, 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;
}
// can't use our own spells when we're in possession of another unit,
if (_player->isPossessing())
return;
// client provided targets
SpellCastTargets targets;
recvPacket >> targets.ReadForCaster(_player);
Unit* target = targets.getUnitTarget();
if (target) // auto-selection buff level base at target level (in spellInfo)
{
// 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.SelectAuraRankForPlayerLevel(spellInfo, target->getLevel()))
spellInfo = actualSpellInfo;
}
if (spellInfo->AttributesEx2 & SPELL_ATTR2_AUTOREPEAT_FLAG)
{
if (_player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL) && _player->GetCurrentSpell(CURRENT_AUTOREPEAT_SPELL)->m_spellInfo->Id == spellInfo->Id)
return;
}
// When casting a combat spell the unit has to be flagged as initiating combat
// No need to check if spell is self-cast because combat spells can only be cast on self with commands
if (target && !IsNonCombatSpell(spellInfo))
_player->setInitiatingCombat(true);
Spell* spell = new Spell(_player, spellInfo, false);
spell->m_cast_count = cast_count; // set count of casts
spell->prepare(&targets);
}
示例3: CHECK_PACKET_SIZE
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
// TODO: add targets.read() check
CHECK_PACKET_SIZE(recvPacket,1+1+1+1+8);
Player* pUser = _player;
uint8 bagIndex, slot;
uint8 spell_count; // number of spells at item, not used
uint8 cast_count; // next cast if exists (single or not)
uint64 item_guid;
recvPacket >> bagIndex >> slot >> spell_count >> cast_count >> item_guid;
Item *pItem = pUser->GetItemByPos(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, spell_count: %u , cast_count: %u, Item: %u, data length = %i", bagIndex, slot, spell_count, cast_count, pItem->GetEntry(), 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 < 5; ++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;
//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
// special learning case
if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN)
{
uint32 learning_spell_id = pItem->GetProto()->Spells[1].SpellId;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(SPELL_ID_GENERIC_LEARN);
if(!spellInfo)
{
//.........这里部分代码省略.........
示例4: DETAIL_LOG
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
uint8 bagIndex, slot;
uint8 spell_count; // number of spells at item, not used
recvPacket >> bagIndex >> slot >> spell_count;
// TODO: add targets.read() check
Player* pUser = _player;
// ignore for remote control state
if (!pUser->IsSelfMover())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
return;
}
Item* pItem = pUser->GetItemByPos(bagIndex, slot);
if (!pItem)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
return;
}
DETAIL_LOG("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , Item: %u, data length = %u", bagIndex, slot, spell_count, pItem->GetEntry(), (uint32)recvPacket.size());
ItemPrototype const* proto = pItem->GetProto();
if (!proto)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
return;
}
// some item classes can be used only in equipped state
if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
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, nullptr);
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, nullptr);
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, nullptr);
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);
if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget()))
{
// free gray item after use fail
pUser->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr);
// search spell for spell error
uint32 spellid = 0;
for (int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
//.........这里部分代码省略.........
示例5: HandleUseItemOpcode
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
// TODO: add targets.read() check
Player* pUser = _player;
uint8 bagIndex, slot;
uint8 spell_count; // number of spells at item, not used
recvPacket >> bagIndex >> slot >> spell_count;
Item *pItem = pUser->GetItemByPos(bagIndex, slot);
if(!pItem)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
return;
}
sLog.outDetail("WORLD: CMSG_USE_ITEM packet, bagIndex: %u, slot: %u, spell_count: %u , Item: %u, data length = %i", bagIndex, slot, spell_count, pItem->GetEntry(), (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;
}
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;
recvPacket >> targets.ReadForCaster(pUser);
targets.Update(pUser);
if (!pItem->IsTargetValidForItemUse(targets.getUnitTarget()))
{
// free gray item after use fail
pUser->SendEquipError(EQUIP_ERR_NONE, pItem, NULL);
// search spell for spell error
uint32 spellid = 0;
for(int i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
{
if( proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_USE || proto->Spells[i].SpellTrigger == ITEM_SPELLTRIGGER_ON_NO_DELAY_USE)
{
spellid = proto->Spells[i].SpellId;
break;
}
}
// send spell error
if (SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellid))
Spell::SendCastResult(_player,spellInfo,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(!Script->ItemUse(pUser,pItem,targets))
{
// no script or script not process request by self
// special learning case
if(pItem->GetProto()->Spells[0].SpellId==SPELL_ID_GENERIC_LEARN)
{
//.........这里部分代码省略.........
示例6: UpdateAllies
void PetAI::Reset()
{
m_primaryTargetGuid.Clear();
m_savedTargetGuid.Clear();
m_attackDistanceRecheckTimer.SetInterval(TIME_INTERVAL_LOOK);
m_attackDistanceRecheckTimer.Reset();
m_updateAlliesTimer.SetInterval(ALLIES_UPDATE_TIME);
m_updateAlliesTimer.Reset();
UpdateAllies();
for (uint8 i = PET_SPELL_PASSIVE; i < PET_SPELL_MAX; ++i)
m_spellType[i].clear();
m_AIType = PET_AI_PASSIVE;
m_attackDistance = 0.0f;
float f_range = 0.0f;
if (!m_creature->GetCharmInfo())
return;
uint32 spellsSize = m_creature->IsPet() ? ((Pet*)m_creature)->GetPetAutoSpellSize() : m_creature->GetPetAutoSpellSize();
uint8 rangedDamageSpells = 0;
uint8 meleeDamageSpells = 0;
// classification for pet spells
for (uint32 i = 0; i < spellsSize; ++i)
{
uint32 spellID = m_creature->IsPet() ? ((Pet*)m_creature)->GetPetAutoSpellOnPos(i) : m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
if (!spellInfo)
continue;
if (IsPassiveSpell(spellInfo))
{
m_spellType[PET_SPELL_PASSIVE].insert(spellID);
continue;
}
if (IsNonCombatSpell(spellInfo))
{
// Voidwalker Consume Shadows
if (IsChanneledSpell(spellInfo))
m_spellType[PET_SPELL_HEAL].insert(spellID);
else
m_spellType[PET_SPELL_NONCOMBAT].insert(spellID);
continue;
}
// need more correct define this type
if (IsSpellReduceThreat(spellInfo) || IsChanneledSpell(spellInfo))
{
m_spellType[PET_SPELL_DEFENCE].insert(spellID);
continue;
}
// Voracious Appetite && Cannibalize && Carrion Feeder
if (spellInfo->HasAttribute(SPELL_ATTR_ABILITY) && spellInfo->HasAttribute(SPELL_ATTR_EX2_ALLOW_DEAD_TARGET))
{
m_spellType[PET_SPELL_HEAL].insert(spellID);
continue;
}
if (IsPositiveSpell(spellInfo) && IsSpellAppliesAura(spellInfo))
{
m_spellType[PET_SPELL_BUFF].insert(spellID);
continue;
}
if (spellInfo->HasAttribute(SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY))
{
m_spellType[PET_SPELL_FREEACTION].insert(spellID);
continue;
}
// don't have SPELL_ATTR_EX_DISPEL_AURAS_ON_IMMUNITY !
if (spellInfo->HasAttribute(SPELL_ATTR_EX_CANT_REFLECTED) ||
spellInfo->HasAttribute(SPELL_ATTR_EX7_HAS_CHARGE_EFFECT))
{
m_spellType[PET_SPELL_ATTACKSTART].insert(spellID);
continue;
}
if (IsSpellIncreaseThreat(spellInfo))
{
m_spellType[PET_SPELL_THREAT].insert(spellID);
continue;
}
// all non-combat spells classified.
switch (spellInfo->rangeIndex)
{
case SPELL_RANGE_IDX_COMBAT:
{
if (IsSpellCauseDamage(spellInfo))
{
m_spellType[PET_SPELL_MELEE].insert(spellID);
++meleeDamageSpells;
//.........这里部分代码省略.........
示例7: UpdateAllies
void PetAI::UpdateAI(const uint32 diff)
{
if (!m_creature->isAlive())
return;
Unit* owner = m_creature->GetCharmerOrOwner();
if(m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
UpdateAllies();
else
m_updateAlliesTimer -= diff;
if (inCombat && !m_creature->getVictim())
_stopAttack();
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
if (m_creature->getVictim())
{
if (_needToStop())
{
DEBUG_LOG("Pet AI stoped attacking [guid=%u]", m_creature->GetGUIDLow());
_stopAttack();
return;
}
else if (m_creature->IsStopped() || m_creature->IsWithinDistInMap(m_creature->getVictim(), ATTACK_DISTANCE))
{
// required to be stopped cases
if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
{
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW))
m_creature->InterruptNonMeleeSpells(false);
else
return;
}
// not required to be stopped case
else if (m_creature->isAttackReady() && m_creature->canReachWithAttack(m_creature->getVictim()))
{
m_creature->AttackerStateUpdate(m_creature->getVictim());
m_creature->resetAttackTimer();
if (!m_creature->getVictim())
return;
//if pet misses its target, it will also be the first in threat list
m_creature->getVictim()->AddThreat(m_creature,0.0f);
if( _needToStop() )
_stopAttack();
}
}
}
else if (owner && m_creature->GetCharmInfo())
{
if (owner->isInCombat() && !(m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
{
AttackStart(owner->getAttackerForHelper());
}
else if(m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
{
if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW) )
{
m_creature->GetMotionMaster()->MoveFollow(owner,PET_FOLLOW_DIST,PET_FOLLOW_ANGLE);
}
}
}
if (m_creature->GetGlobalCooldown() == 0 && !m_creature->IsNonMeleeSpellCasted(false))
{
//Autocast
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); i++)
{
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID);
if (!spellInfo)
continue;
// ignore some combinations of combat state and combat/noncombat spells
if (!inCombat)
{
if (!IsPositiveSpell(spellInfo->Id))
continue;
}
else
{
if (IsNonCombatSpell(spellInfo))
continue;
}
Spell *spell = new Spell(m_creature, spellInfo, false, 0);
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
{
m_targetSpellStore.push_back(std::make_pair<Unit*, Spell*>(m_creature->getVictim(), spell));
continue;
}
//.........这里部分代码省略.........
示例8: CHECK_PACKET_SIZE
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
// TODO: add targets.read() check
CHECK_PACKET_SIZE(recvPacket,1+1+1+4+8+4+1);
Player* pUser = _player;
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->GetItemByPos(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, 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;
//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
pUser->CastItemUseSpell(pItem,targets,cast_count,glyphIndex);
}
}
示例9: flags
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
{
uint8 bagIndex, slot;
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 >> cast_flags;
// TODO: add targets.read() check
Player* pUser = _player;
// ignore for remote control state
if (!pUser->IsSelfMover())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
return;
}
// reject fake data
if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
return;
}
Item* pItem = pUser->GetItemByPos(bagIndex, slot);
if (!pItem)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
return;
}
if (pItem->GetObjectGuid() != itemGuid)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr);
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 = %u", bagIndex, slot, cast_count, spellid, pItem->GetEntry(), glyphIndex, cast_flags, (uint32)recvPacket.size());
ItemPrototype const* proto = pItem->GetProto();
if (!proto)
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
return;
}
// some item classes can be used only in equipped state
if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr);
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, nullptr);
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, nullptr);
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_IGNORE_DEFAULT_ARENA_RESTRICTIONS) &&
pUser->InArena())
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr);
return;
}
if (pUser->isInCombat())
{
for (const auto& Spell : proto->Spells)
{
if (SpellEntry const* spellInfo = sSpellTemplate.LookupEntry<SpellEntry>(Spell.SpellId))
{
if (IsNonCombatSpell(spellInfo))
{
recvPacket.rpos(recvPacket.wpos()); // prevent spam at not read packet tail
pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, nullptr);
return;
}
//.........这里部分代码省略.........
示例10: UpdateAllies
//.........这里部分代码省略.........
else
return;
}
// Autocast (casted only in combat or persistent spells in any state)
else if (!m_creature->IsNonMeleeSpellCasted(false))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
if (!spellInfo)
continue;
if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
// ignore some combinations of combat state and combat/noncombat spells
if (!inCombat)
{
// ignore attacking spells, and allow only self/around spells
if (!IsPositiveSpell(spellInfo->Id))
continue;
// non combat spells allowed
// only pet spells have IsNonCombatSpell and not fit this reqs:
// Consume Shadows, Lesser Invisibility, so ignore checks for its
if (!IsNonCombatSpell(spellInfo))
{
int32 duration = GetSpellDuration(spellInfo);
int32 cooldown = GetSpellRecoveryTime(spellInfo);
// allow only spell not on cooldown
if (cooldown != 0 && duration < cooldown)
continue;
// not allow instant kill autocasts as full health cost
if (IsSpellHaveEffect(spellInfo, SPELL_EFFECT_INSTAKILL))
continue;
}
}
// just ignore non-combat spells
else if (IsNonCombatSpell(spellInfo))
continue;
Spell* spell = new Spell(m_creature, spellInfo, false);
if (inCombat && !m_creature->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(m_creature->getVictim()))
{
targetSpellStore.push_back(TargetSpellList::value_type(m_creature->getVictim(), spell));
continue;
}
else
{
bool spellUsed = false;
for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* Target = m_creature->GetMap()->GetUnit(*tar);
// only buff targets that are in combat, unless the spell can only be cast while out of combat
示例11: UpdateAllies
//.........这里部分代码省略.........
AttackStart(nextTarget);
else
HandleReturnMovement();
}
else
HandleReturnMovement();
}
// Autocast (casted only in combat or persistent spells in any state)
if (!m_creature->IsNonMeleeSpellCasted(false))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const *spellInfo = sSpellMgr.GetSpellEntry(spellID);
if (!spellInfo)
continue;
if (m_creature->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
// check spell cooldown
if (m_creature->HasSpellCooldown(spellInfo->Id))
continue;
if (IsPositiveSpell(spellInfo->Id))
{
if (!IsNonCombatSpell(spellInfo)) // Can be used in combat.
{
/*
Spells handled here:
Dash (1850), Dive (23145), Furious Howl (24604), Tainted Blood (19478)
Blood Pact (6307), Fire Shield (11771), Sacrifice ...
Consume Shadows (17767)
*/
// Warlock Sacrifice: do not auto cast if not in combat
bool castOnlyInCombat = IsSpellHaveEffect(spellInfo, SPELL_EFFECT_INSTAKILL);
if (!castOnlyInCombat)
{
int32 duration = GetSpellDuration(spellInfo);
int32 cooldown = GetSpellRecoveryTime(spellInfo);
// Keep this spell for when we will be in combat.
if (cooldown >= 0 && duration >= 0 && cooldown > duration)
castOnlyInCombat = true;
}
// 19478 - Tainted Blood, rank 1 enUS
if (spellInfo->SpellIconID == 153)
castOnlyInCombat = true;
// 2947 - Fire Shield, rank 1 enUS
// When set to auto-cast, the Imp will cast this on any party members within 30 yds if they receive a melee attack.
if (spellInfo->IsFitToFamily<SPELLFAMILY_WARLOCK, CF_WARLOCK_IMP_BUFFS>() && spellInfo->SpellVisual == 289)
castOnlyInCombat = false;
// Furious Howl: in combat only
if (IsSpellHaveAura(spellInfo, SPELL_AURA_MOD_DAMAGE_DONE))
castOnlyInCombat = true;
if (castOnlyInCombat && !m_creature->getVictim())
continue;
}
示例12: CHECK_PACKET_SIZE
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: UpdateAllies
void PetAI::UpdateAI(const uint32 diff)
{
if (!m_creature->isAlive())
return;
Unit* owner = m_creature->GetCharmerOrOwner();
if (m_updateAlliesTimer <= diff)
// UpdateAllies self set update timer
UpdateAllies();
else
m_updateAlliesTimer -= diff;
if (inCombat && (!m_creature->getVictim() || (m_creature->IsPet() && ((Pet*)m_creature)->GetModeFlags() & PET_MODE_DISABLE_ACTIONS)))
_stopAttack();
// i_pet.getVictim() can't be used for check in case stop fighting, i_pet.getVictim() clear at Unit death etc.
if (m_creature->getVictim())
{
if (_needToStop())
{
DEBUG_FILTER_LOG(LOG_FILTER_AI_AND_MOVEGENSS, "PetAI (guid = %u) is stopping attack.", m_creature->GetGUIDLow());
_stopAttack();
return;
}
bool meleeReach = m_creature->CanReachWithMeleeAttack(m_creature->getVictim());
if (m_creature->IsStopped() || meleeReach)
{
// required to be stopped cases
if (m_creature->IsStopped() && m_creature->IsNonMeleeSpellCasted(false))
{
if (m_creature->hasUnitState(UNIT_STAT_FOLLOW_MOVE))
m_creature->InterruptNonMeleeSpells(false);
else
return;
}
// not required to be stopped case
else if (DoMeleeAttackIfReady())
{
if (!m_creature->getVictim())
return;
// if pet misses its target, it will also be the first in threat list
m_creature->getVictim()->AddThreat(m_creature);
if (_needToStop())
_stopAttack();
}
}
}
else if (owner && m_creature->GetCharmInfo())
{
if (owner->isInCombat() && !(m_creature->GetCharmInfo()->HasReactState(REACT_PASSIVE) || m_creature->GetCharmInfo()->HasCommandState(COMMAND_STAY)))
{
AttackStart(owner->getAttackerForHelper());
}
else if (m_creature->GetCharmInfo()->HasCommandState(COMMAND_FOLLOW))
{
if (!m_creature->hasUnitState(UNIT_STAT_FOLLOW))
{
m_creature->GetMotionMaster()->MoveFollow(owner, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE);
}
}
}
// Autocast (casted only in combat or persistent spells in any state)
if (!m_creature->IsNonMeleeSpellCasted(false))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
for (uint8 i = 0; i < m_creature->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = m_creature->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const* spellInfo = sSpellStore.LookupEntry(spellID);
if (!spellInfo)
continue;
if (m_creature->GetCharmInfo() && m_creature->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo))
continue;
// ignore some combinations of combat state and combat/noncombat spells
if (!inCombat)
{
// ignore attacking spells, and allow only self/around spells
if (!IsPositiveSpell(spellInfo->Id))
continue;
// non combat spells allowed
// only pet spells have IsNonCombatSpell and not fit this reqs:
// Consume Shadows, Lesser Invisibility, so ignore checks for its
if (!IsNonCombatSpell(spellInfo))
{
// allow only spell without spell cost or with spell cost but not duration limit
int32 duration = GetSpellDuration(spellInfo);
//.........这里部分代码省略.........
示例14: UpdateAllies
//.........这里部分代码省略.........
else
return;
}
// Auto cast (casted only in combat or persistent spells in any state)
else if (!m_unit->IsNonMeleeSpellCasted(false))
{
typedef std::vector<std::pair<Unit*, Spell*> > TargetSpellList;
TargetSpellList targetSpellStore;
if (pet)
{
for (uint8 i = 0; i < pet->GetPetAutoSpellSize(); ++i)
{
uint32 spellID = pet->GetPetAutoSpellOnPos(i);
if (!spellID)
continue;
SpellEntry const* spellInfo = sSpellTemplate.LookupEntry<SpellEntry>(spellID);
if (!spellInfo)
continue;
if (!m_unit->IsSpellReady(*spellInfo))
continue;
// ignore some combinations of combat state and combat/non combat spells
if (!inCombat)
{
// ignore attacking spells, and allow only self/around spells
if (!IsPositiveSpell(spellInfo->Id))
continue;
// non combat spells allowed
// only pet spells have IsNonCombatSpell and not fit this requirements:
// Consume Shadows, Lesser Invisibility, so ignore checks for its
if (!IsNonCombatSpell(spellInfo))
{
int32 duration = GetSpellDuration(spellInfo);
int32 cooldown = GetSpellRecoveryTime(spellInfo);
// allow only spell not on cooldown
if (cooldown != 0 && duration < cooldown)
continue;
// not allow instant kill auto casts as full health cost
if (IsSpellHaveEffect(spellInfo, SPELL_EFFECT_INSTAKILL))
continue;
}
}
// just ignore non-combat spells
else if (IsNonCombatSpell(spellInfo))
continue;
Spell* spell = new Spell(m_unit, spellInfo, false);
if (inCombat && !m_unit->hasUnitState(UNIT_STAT_FOLLOW) && spell->CanAutoCast(victim))
{
targetSpellStore.push_back(TargetSpellList::value_type(victim, spell));
continue;
}
else
{
bool spellUsed = false;
for (GuidSet::const_iterator tar = m_AllySet.begin(); tar != m_AllySet.end(); ++tar)
{
Unit* Target = m_unit->GetMap()->GetUnit(*tar);
// only buff targets that are in combat, unless the spell can only be cast while out of combat
示例15: flags
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;
// reject fake data
if (glyphIndex >= MAX_GLYPH_SLOT_INDEX)
{
pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL );
return;
}
Item *pItem = pUser->GetItemByPos(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;
recvPacket >> targets.ReadForCaster(pUser);
targets.Update(pUser);
//.........这里部分代码省略.........