inline GameObject* Map::_FindGameObject(WorldObject* searchObject, uint32 guid) const { GameObject* gameobject = NULL; CellCoord p(MistCore::ComputeCellCoord(searchObject->GetPositionX(), searchObject->GetPositionY())); Cell cell(p); MistCore::GameObjectWithDbGUIDCheck goCheck(*searchObject, guid); MistCore::GameObjectSearcher<MistCore::GameObjectWithDbGUIDCheck> checker(searchObject, gameobject, goCheck); TypeContainerVisitor<MistCore::GameObjectSearcher<MistCore::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > objectChecker(checker); cell.Visit(p, objectChecker, *searchObject->GetMap(), *searchObject, searchObject->GetGridActivationRange()); return gameobject; }
inline GameObject* Map::_FindGameObject(WorldObject* pSearchObject, uint32 guid) const { GameObject* pGameObject = NULL; CellPair p(BlizzLike::ComputeCellPair(pSearchObject->GetPositionX(), pSearchObject->GetPositionY())); Cell cell(p); cell.data.Part.reserved = ALL_DISTRICT; BlizzLike::GameObjectWithDbGUIDCheck goCheck(*pSearchObject, guid); BlizzLike::GameObjectSearcher<BlizzLike::GameObjectWithDbGUIDCheck> checker(pGameObject, goCheck); TypeContainerVisitor<BlizzLike::GameObjectSearcher<BlizzLike::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > objectChecker(checker); cell.Visit(p, objectChecker, *pSearchObject->GetMap()); return pGameObject; }
void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) { TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "WORLD: CMSG_PET_CAST_SPELL"); uint64 guid; uint8 castCount; uint32 spellId; uint8 castFlags; recvPacket >> guid >> castCount >> spellId >> castFlags; TC_LOG_DEBUG(LOG_FILTER_NETWORKIO, "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())) { TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "HandlePetCastSpellOpcode: Pet %u isn't pet of player %s (GUID: %u).", uint32(GUID_LOPART(guid)), GetPlayer()->GetName().c_str(), GUID_LOPART(GetPlayer()->GetGUID())); return; } SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { TC_LOG_ERROR(LOG_FILTER_NETWORKIO, "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->GetCharmInfo() && caster->GetCharmInfo()->GetGlobalCooldownMgr().HasGlobalCooldown(spellInfo)) { caster->SendPetCastFail(spellId, SPELL_FAILED_NOT_READY); return; } // check spell focus object if (spellInfo->RequiresSpellFocus && caster->IsVehicle()) { CellCoord p(Trinity::ComputeCellCoord(caster->GetPositionX(), caster->GetPositionY())); Cell cell(p); GameObject* ok = NULL; Trinity::GameObjectFocusCheck goCheck(caster, spellInfo->RequiresSpellFocus); Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> checker(caster, ok, goCheck); TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck>, GridTypeMapContainer > objectChecker(checker); Map& map = *caster->GetMap(); cell.Visit(p, objectChecker, map, *caster, caster->GetVisibilityRange()); if (!ok) { caster->SendPetCastFail(spellId, SPELL_FAILED_REQUIRES_SPELL_FOCUS); return; } } // do not cast not learned spells if (!caster->HasSpell(spellId) || spellInfo->IsPassive()) return; SpellCastTargets targets; targets.Read(recvPacket, caster); HandleClientCastFlags(recvPacket, castFlags, targets); caster->ClearUnitState(UNIT_STATE_FOLLOW); Spell* spell = new Spell(caster, spellInfo, TRIGGERED_NONE); 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; } }