SPELL_EFFECT_OVERRIDE_RETURNS AH_17( Aura *aur, bool apply, uint8 i ) { if( apply == false && aur->GetSpellProto()->eff[i].EffectApplyAuraName == SPELL_AURA_SCHOOL_ABSORB ) { Absorb *abs = (Absorb*)aur->temp_custom_structure_holder; if( abs && abs->amt <= 0 ) { Unit * caster = aur->GetUnitCaster(); if( caster ) { Aura *a = caster->HasAuraWithNameHash( SPELL_HASH_RAPTURE, 0, AURA_SEARCH_PASSIVE ); if( a ) { //ever initialized ? if( a->m_modList[0].fixed_amount[0] < (int32)getMSTime() ) { uint32 energize_pct = a->GetSpellProto()->eff[0].EffectBasePoints; Aura *b = caster->HasAuraWithNameHash( SPELL_HASH_ITEM___PRIEST_T13_HEALER_4P_BONUS__HOLY_WORD_AND_POWER_WORD__SHIELD_, 0, AURA_SEARCH_PASSIVE ); if( b ) energize_pct += b->GetSpellProto()->eff[1].EffectBasePoints; caster->Energize( caster, 47755, caster->GetMaxPower( POWER_TYPE_MANA ) * energize_pct / 100, POWER_TYPE_MANA, 0 ); a->m_modList[0].fixed_amount[0] = getMSTime() + a->GetSpellProto()->proc_interval; // 12 seconds } } } } } return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; }
void AuraInterface::MassDispel(Unit* caster, uint32 index, SpellEntry* Dispelling, uint32 MaxDispel, uint8 start, uint8 end) { WorldPacket data(SMSG_SPELLDISPELLOG, 16); Aura* aur = NULL; for(uint32 x = start; x < end; x++) { if(m_auras.find(x) != m_auras.end()) { aur = m_auras.at(x); //Nothing can dispel resurrection sickness; if(aur != NULL && !aur->IsPassive() && !(aur->GetSpellProto()->Attributes & ATTRIBUTES_IGNORE_INVULNERABILITY)) { int32 resistchance = 0; Unit* caster = aur->GetUnitCaster(); if( caster ) SM_FIValue(caster->SM[SMT_RESIST_DISPEL][0], &resistchance, aur->GetSpellProto()->SpellGroupType); if( !Rand(resistchance) ) { if(Dispelling->DispelType == DISPEL_ALL) { m_Unit->HandleProc( PROC_ON_DISPEL_AURA_VICTIM, NULL, caster, Dispelling, aur->GetSpellId() ); data.clear(); data << caster->GetNewGUID(); data << m_Unit->GetNewGUID(); data << (uint32)1;//probably dispel type data << aur->GetSpellId(); caster->SendMessageToSet(&data,true); aur->AttemptDispel( caster ); if(!--MaxDispel) return; } else if(aur->GetSpellProto()->DispelType == Dispelling->EffectMiscValue[index]) { if( (aur->GetSpellProto()->NameHash != SPELL_HASH_ICE_BARRIER && aur->GetSpellProto()->NameHash != SPELL_HASH_DIVINE_SHIELD) || Dispelling->NameHash == SPELL_HASH_MASS_DISPEL ) { m_Unit->HandleProc( PROC_ON_DISPEL_AURA_VICTIM, NULL, caster, Dispelling, aur->GetSpellId() ); data.clear(); data << caster->GetNewGUID(); data << m_Unit->GetNewGUID(); data << (uint32)1; data << aur->GetSpellId(); caster->SendMessageToSet(&data,true); aur->AttemptDispel( caster ); if(!--MaxDispel) return; } } } else if( !--MaxDispel ) return; } } } }
bool DeathStrike(uint32 i, Spell* pSpell) { if(pSpell->p_caster == NULL || pSpell->GetUnitTarget() == NULL) return true; Unit* Target = pSpell->GetUnitTarget(); int count = 0; if(Target->HasAura(BLOOD_PLAGUE)) count++; if(Target->HasAura(FROST_FEVER)) count++; if(Target->HasAurasWithNameHash(SPELL_HASH_EBON_PLAGUE)) count++; if(Target->HasAurasWithNameHash(SPELL_HASH_CRYPT_FEVER)) count++; count = min(count, 3); //limited to 15% incase spell uniques are wrong for ebon plague and crypt fever if(count) { float pct = pSpell->p_caster->GetMaxHealth() * 0.05f; uint32 val = float2int32(pct * count); Aura* aur = pSpell->p_caster->FindAuraByNameHash(SPELL_HASH_IMPROVED_DEATH_STRIKE); if(aur != NULL) val += val * (aur->GetSpellProto()->EffectBasePoints[2] + 1) / 100; if(val > 0) pSpell->u_caster->Heal(pSpell->u_caster, pSpell->GetProto()->Id, val); } return true; }
bool DeathStrike(uint32 i, Spell* pSpell) { if(pSpell->p_caster == NULL || pSpell->GetUnitTarget() == NULL) return true; Unit* Target = pSpell->GetUnitTarget(); // Get count of diseases on target which were casted by caster uint32 count = Target->GetAuraCountWithDispelType(DISPEL_DISEASE, pSpell->p_caster->GetGUID()); // Not a logical error, Death Strike should heal only when diseases are presented on its target if(count) { // Calculate heal amount: // A deadly attack that deals $s2% weapon damage plus ${$m1*$m2/100} // and heals the Death Knight for $F% of $Ghis:her; maximum health for each of $Ghis:her; diseases on the target. // $F is dmg_multiplier. float amt = static_cast< float >(pSpell->p_caster->GetMaxHealth()) * pSpell->GetProto()->dmg_multiplier[0] / 100.0f; // Calculate heal amount with diseases on target uint32 val = static_cast< uint32 >(amt * count); Aura* aur = pSpell->p_caster->FindAuraByNameHash(SPELL_HASH_IMPROVED_DEATH_STRIKE); if(aur != NULL) val += val * (aur->GetSpellProto()->EffectBasePoints[2] + 1) / 100; if(val > 0) pSpell->u_caster->Heal(pSpell->u_caster, pSpell->GetProto()->Id, val); } return true; }
void FelhunterAI::PrepareSpellForAutocast(uint32 spellID) { if (!spellID) return; if (sSpellMgr.GetFirstSpellInChain(spellID) == 19505) // Devour Magic { SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellID); Unit *target = me->getVictim(); if (!spellInfo || !target) return; Unit::AuraMap const& auras = target->GetAuras(); for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); ++itr) { Aura *aur = (*itr).second; if (aur && aur->GetSpellProto()->Dispel == DISPEL_MAGIC) { if (aur->IsPositive()) { AddSpellForAutocast(spellID, target); return; } } } } else PetAI::PrepareSpellForAutocast(spellID); }
void HandleScriptEffect(SpellEffIndex effIndex) { Unit* caster = GetCaster(); Unit* unitTarget = GetHitUnit(); if (!unitTarget) return; uint32 spellId = 0; int32 basePoint = 0; Unit::AuraApplicationMap& Auras = unitTarget->GetAppliedAuras(); for (Unit::AuraApplicationMap::iterator i = Auras.begin(); i != Auras.end(); ++i) { Aura* aura = i->second->GetBase(); if (aura->GetCasterGUID() != caster->GetGUID()) continue; // Search only Serpent Sting, Viper Sting, Scorpid Sting auras flag96 familyFlag = aura->GetSpellProto()->SpellFamilyFlags; if (!(familyFlag[1] & 0x00000080 || familyFlag[0] & 0x0000C000)) continue; if (AuraEffect const * aurEff = aura->GetEffect(0)) { // Serpent Sting - Instantly deals 40% of the damage done by your Serpent Sting. if (familyFlag[0] & 0x4000) { int32 TickCount = aurEff->GetTotalTicks(); spellId = HUNTER_SPELL_CHIMERA_SHOT_SERPENT; basePoint = aurEff->GetAmount() * TickCount * 40 / 100; } // Viper Sting - Instantly restores mana to you equal to 60% of the total amount drained by your Viper Sting. else if (familyFlag[1] & 0x00000080) { int32 TickCount = aura->GetEffect(0)->GetTotalTicks(); spellId = HUNTER_SPELL_CHIMERA_SHOT_VIPER; // Amount of one aura tick basePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 100 ; int32 casterBasePoint = aurEff->GetAmount() * unitTarget->GetMaxPower(POWER_MANA) / 50 ; if (basePoint > casterBasePoint) basePoint = casterBasePoint; basePoint = basePoint * TickCount * 60 / 100; } // Scorpid Sting - Attempts to Disarm the target for 10 sec. This effect cannot occur more than once per 1 minute. else if (familyFlag[0] & 0x00008000) spellId = HUNTER_SPELL_CHIMERA_SHOT_SCORPID; // ?? nothing say in spell desc (possibly need addition check) //if (familyFlag & 0x0000010000000000LL || // dot // familyFlag & 0x0000100000000000LL) // stun //{ // spellId = 53366; // 53366 Chimera Shot - Wyvern //} // Refresh aura duration aura->RefreshDuration(); } break; } if (spellId) caster->CastCustomSpell(unitTarget, spellId, &basePoint, 0, 0, false); }
bool PlayerbotAI::HasAura(string name, Unit* unit) { if (!unit) return false; uint32 spellId = aiObjectContext->GetValue<uint32>("spell id", name)->Get(); if (spellId) return HasAura(spellId, unit); wstring wnamepart; if (!Utf8toWStr(name, wnamepart)) return 0; wstrToLower(wnamepart); for (uint32 auraType = SPELL_AURA_BIND_SIGHT; auraType < TOTAL_AURAS; auraType++) { Unit::AuraList const& auras = unit->GetAurasByType((AuraType)auraType); for (Unit::AuraList::const_iterator i = auras.begin(); i != auras.end(); i++) { Aura* aura = *i; if (!aura) continue; const string auraName = aura->GetSpellProto()->SpellName[0]; if (auraName.empty() || auraName.length() != wnamepart.length() || !Utf8FitTo(auraName, wnamepart)) continue; if (IsRealAura(bot, aura, unit)) return true; } } return false; }
bool CloakOfShadows(uint32 i, Spell* s) { Unit* unitTarget = s->GetUnitTarget(); if(!unitTarget || !unitTarget->isAlive()) return false; Aura* pAura; for(uint32 j = MAX_NEGATIVE_AURAS_EXTEDED_START; j < MAX_NEGATIVE_AURAS_EXTEDED_END; ++j) { pAura = unitTarget->m_auras[j]; if(pAura != NULL && !pAura->IsPassive() && !pAura->IsPositive() && !(pAura->GetSpellProto()->Attributes & ATTRIBUTES_IGNORE_INVULNERABILITY) && pAura->GetSpellProto()->School != 0 ) pAura->Remove(); } return true; }
bool PlayerbotClassAI::castDispel (uint32 dispelSpell, Unit *dTarget, bool checkFirst, bool castExistingAura, bool skipFriendlyCheck, bool skipEquipStanceCheck) { if (dispelSpell == 0 || !dTarget ) return false; //if (!canCast(dispelSpell, dTarget, true)) return false; //Needless cpu cycles wasted, usually a playerbot can cast a dispell const SpellEntry *dSpell = GetSpellStore()->LookupEntry(dispelSpell); if (!dSpell) return false; for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++i) { if (dSpell->Effect[i] != (uint32)SPELL_EFFECT_DISPEL) continue; uint32 dispel_type = dSpell->EffectMiscValue[i]; uint32 dispelMask = GetDispellMask(DispelType(dispel_type)); Unit::AuraMap const& auras = dTarget->GetOwnedAuras(); for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++) { Aura * aura = itr->second; AuraApplication * aurApp = aura->GetApplicationOfTarget(dTarget->GetGUID()); if (!aurApp) continue; if ((1<<aura->GetSpellProto()->Dispel) & dispelMask) { if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC) { bool positive = aurApp->IsPositive() ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR0_UNK7)) : false; // do not remove positive auras if friendly target // negative auras if non-friendly target if(positive == dTarget->IsFriendlyTo(GetPlayerBot())) continue; } // If there is a successfull match return, else continue searching. if (CastSpell(dSpell, dTarget, checkFirst, castExistingAura, skipFriendlyCheck, skipEquipStanceCheck)) { return true; } } } } return false; }
void AuraInterface::SpellStealAuras(Unit* caster, int32 MaxSteals) { Aura* aur = NULL; int32 spells_to_steal = MaxSteals > 1 ? MaxSteals : 1; for(uint32 x = 0; x < MAX_POSITIVE_AURAS; x++) { if(m_auras.find(x) != m_auras.end()) { aur = m_auras.at(x); if(aur != NULL && aur->GetSpellId() != 15007 && !aur->IsPassive() && aur->IsPositive()) //Nothing can dispel resurrection sickness { if(aur->GetSpellProto()->DispelType == DISPEL_MAGIC && aur->GetDuration() > 0) { WorldPacket data(SMSG_SPELLDISPELLOG, 16); data << caster->GetNewGUID(); data << m_Unit->GetNewGUID(); data << uint32(1); data << aur->GetSpellId(); caster->SendMessageToSet(&data,true); Aura* aura = new Aura(aur->GetSpellProto(), (aur->GetDuration()>120000) ? 120000 : aur->GetDuration(), caster, caster); aura->stackSize = aur->stackSize; // copy the mods across for( uint32 m = 0; m < aur->GetModCount(); ++m ) { Modifier *mod = aur->GetMod(m); aura->AddMod(mod->m_type, mod->m_baseAmount, mod->m_miscValue, mod->i); } caster->AddAura(aura); RemoveAuraBySlot(x); if( --spells_to_steal <= 0 ) break; //exit loop now } } } } }
bool SkyShatterRegalia(uint32 i, Spell* s) { // Shaman - Skyshatter Regalia - Two Piece Bonus // it checks for earth, air, water, fire totems and triggers Totemic Mastery spell 38437. if(!s->p_caster) return false; if(s->p_caster->summonhandler.HasSummonInSlot(0) && s->p_caster->summonhandler.HasSummonInSlot(1) && s->p_caster->summonhandler.HasSummonInSlot(2) && s->p_caster->summonhandler.HasSummonInSlot(3)) { Aura* aur = sSpellFactoryMgr.NewAura(dbcSpell.LookupEntry(38437), 5000, s->p_caster, s->p_caster, true); for(uint32 j = 0; j < 3; j++) aur->AddMod(aur->GetSpellProto()->eff[j].EffectApplyAuraName, aur->GetSpellProto()->eff[j].EffectBasePoints + 1, aur->GetSpellProto()->eff[j].EffectMiscValue, j); s->p_caster->AddAura(aur); } return true; }
void DoAfterHandleEffect(Unit* target, uint32 i) { if(p_caster == NULL || i != 1) return; Aura* aur = p_caster->FindAuraByNameHash(SPELL_HASH_SUDDEN_DOOM); if(aur == NULL) return; if(! Rand(aur->GetSpellProto()->procChance)) return; p_caster->CastSpell(target, 47632, false); }
bool DoEffect(Unit* victim, SpellEntry* CastingSpell, uint32 flag, uint32 dmg, uint32 abs, int* dmg_overwrite, uint32 weapon_damage_type) { Aura* aura = mTarget->FindAuraByNameHash(SPELL_HASH_SLICE_AND_DICE); if(aura) { // Duration of 5 combo maximum int32 dur = 21 * MSTIME_SECOND; SM_FIValue(mTarget->SM_FDur, &dur, aura->GetSpellProto()->SpellGroupType); SM_PIValue(mTarget->SM_PDur, &dur, aura->GetSpellProto()->SpellGroupType); // Set new aura's duration, reset event timer and set client visual aura aura->SetDuration(dur); sEventMgr.ModifyEventTimeLeft(aura, EVENT_AURA_REMOVE, aura->GetDuration()); mTarget->ModVisualAuraStackCount(aura, 0); } return true; }
void HandleScriptEffect(SpellEffIndex /*effIndex*/) { Unit* caster = GetCaster(); if (Unit* unitTarget = GetHitUnit()) if (AuraEffect const* aurEff = unitTarget->GetAuraEffect(SPELL_AURA_PERIODIC_DAMAGE, SPELLFAMILY_DRUID, 0x00000002, 0, 0, caster->GetGUID())) { Aura* aura = aurEff->GetBase(); uint32 countMin = aura->GetMaxDuration(); uint32 countMax = GetSpellMaxDuration(aura->GetSpellProto()) + 9000; if (caster->HasAura(DRUID_INCREASED_MOONFIRE_DURATION)) countMax += 3000; if (caster->HasAura(DRUID_NATURES_SPLENDOR)) countMax += 3000; if (countMin < countMax) { aura->SetDuration(uint32(aura->GetDuration() + 3000)); aura->SetMaxDuration(countMin + 3000); } } }
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; } Spell *spell = new Spell(mover, spellInfo, triggered, mover->GetObjectGuid(), triggeredBy); spell->m_cast_count = cast_count; // set count of casts spell->prepare(&targets, triggeredByAura); }
bool JudgementLightWisdomJustice(uint32 i, Spell* pSpell) { Unit* target = pSpell->GetUnitTarget(); if(target == NULL) return true; Player* caster = pSpell->p_caster; if(caster == NULL) return true; // Search for a previous judgement casted by this caster. He can have only 1 judgement active at a time uint32 index = 0; uint32 judgements[] = { SPELL_HASH_JUDGEMENT_OF_LIGHT, SPELL_HASH_JUDGEMENT_OF_WISDOM, SPELL_HASH_JUDGEMENT_OF_JUSTICE, SPELL_HASH_JUDGEMENT_OF_VENGEANCE, SPELL_HASH_JUDGEMENT_OF_CORRUPTION, SPELL_HASH_JUDGEMENT_OF_RIGHTEOUSNESS, 0 }; uint64 prev_target = caster->GetCurrentUnitForSingleTargetAura(judgements, &index); if(prev_target) { Unit* t = caster->GetMapMgr()->GetUnit(prev_target); if(t != NULL) t->RemoveAllAuraByNameHash(judgements[index]); caster->RemoveCurrentUnitForSingleTargetAura(judgements[index]); } // Search for seal to unleash its energy uint32 seals[] = { 20375, 20165, 20164, 21084, 31801, 53736, 20166, 0 }; Aura* aura = caster->FindAura(seals); if(aura == NULL) return true; uint32 id = 0; switch(aura->GetSpellId()) { case 20375: id = 20467; break; case 20165: id = 54158; break; case 20164: id = 54158; break; case 21084: id = 20187; break; case 31801: id = aura->GetSpellProto()->EffectBasePoints[2]; break; case 53736: id = aura->GetSpellProto()->EffectBasePoints[2]; break; case 20166: id = 54158; break; } caster->CastSpell(target, id, true); // Cast judgement spell switch(pSpell->GetProto()->NameHash) { case SPELL_HASH_JUDGEMENT_OF_JUSTICE: id = 20184; break; case SPELL_HASH_JUDGEMENT_OF_LIGHT: id = 20185; break; case SPELL_HASH_JUDGEMENT_OF_WISDOM: id = 20186; break; } caster->CastSpell(target, id, true); caster->SetCurrentUnitForSingleTargetAura(pSpell->GetProto(), target->GetGUID()); return true; }
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; } }
void AuraInterface::RemoveAllAurasByInterruptFlagButSkip(uint32 flag, uint32 skip) { Aura* a = NULL; for(uint32 x = 0; x < MAX_AURAS; x++) { a = NULL; if(m_auras.find(x) == m_auras.end()) continue; a = m_auras.at(x); if( a->GetDuration() > 0 && (int32)(a->GetTimeLeft()+500) > a->GetDuration() ) continue;//pretty new aura, don't remove //some spells do not get removed all the time only at specific intervals if((a->m_spellProto->AuraInterruptFlags & flag) && (a->m_spellProto->Id != skip) && a->m_spellProto->proc_interval==0) { //the black sheeps of sociaty if(a->m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_ON_CAST_SPELL) { switch(a->GetSpellProto()->Id) { // priest - holy conc case 34754: { if( m_Unit->GetCurrentSpell() !=NULL && !(m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_FLASH_HEAL || m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_BINDING_HEAL || m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_GREATER_HEAL)) continue; SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_FLASH_HEAL && spi->NameHash != SPELL_HASH_BINDING_HEAL && spi->NameHash != SPELL_HASH_GREATER_HEAL) continue; }break; //Arcane Potency case 57529: case 57531: { if( m_Unit->GetCurrentSpell() != NULL && !(m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_PRESENCE_OF_MIND || m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_CLEARCASTING )) continue; SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL || !(spi->c_is_flags & SPELL_FLAG_IS_DAMAGING) ) continue; }break; //paladin - Art of war case 53489: case 59578: { if( m_Unit->GetCurrentSpell() != NULL && m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_FLASH_OF_LIGHT ) continue; SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_FLASH_OF_LIGHT ) continue; }break; //paladin - Infusion of light case 53672: case 54149: { if( m_Unit->GetCurrentSpell() != NULL && !(m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_FLASH_OF_LIGHT || m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_HOLY_LIGHT)) continue; SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_FLASH_OF_LIGHT && spi->NameHash != SPELL_HASH_HOLY_LIGHT) continue; }break; //Mage - Firestarter case 54741: { if( m_Unit->GetCurrentSpell() != NULL && m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_FLAMESTRIKE ) continue; SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_FLAMESTRIKE ) continue; }break; case 34936: // Backlash { SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_SHADOW_BOLT && spi->NameHash != SPELL_HASH_INCINERATE ) continue; }break; case 17941: //Shadow Trance { SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_SHADOW_BOLT ) continue; }break; // Glyph of Revenge Proc case 58363: { if( m_Unit->GetCurrentSpell() != NULL && m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_HEROIC_STRIKE ) continue; SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_HEROIC_STRIKE ) continue; }break; case 18708: //Fel Domination { SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_SUMMON_IMP && spi->NameHash != SPELL_HASH_SUMMON_VOIDWALKER && spi->NameHash != SPELL_HASH_SUMMON_SUCCUBUS && spi->NameHash != SPELL_HASH_SUMMON_FELHUNTER && spi->NameHash != SPELL_HASH_SUMMON_FELGUARD ) continue; }break; case 46916: // Bloodsurge { SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_SLAM ) continue; }break; case 14177: // Cold Blood { SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && !(spi->c_is_flags & SPELL_FLAG_IS_DAMAGING) && spi->NameHash != SPELL_HASH_MUTILATE ) continue; }break; case 31834: // Light's Grace { if( m_Unit->GetCurrentSpell() != NULL && m_Unit->GetCurrentSpell()->GetSpellProto()->NameHash == SPELL_HASH_HOLY_LIGHT ) continue; SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && spi->NameHash != SPELL_HASH_HOLY_LIGHT ) continue; }break; // Shadowstep case 44373: case 36563: { SpellEntry *spi = dbcSpell.LookupEntry( skip ); if( spi != NULL && !(spi->c_is_flags & SPELL_FLAG_IS_DAMAGING) ) continue; }break; } } RemoveAuraBySlot(x); } } }
void WorldSession::HandleCastSpellOpcode(WorldPacket& recvPacket) { uint32 spellId; uint8 cast_count, cast_flags; recvPacket >> cast_count; recvPacket >> spellId; 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: CMSG_CAST_SPELL, spellId - %u, cast_count: %u, unk_flags %u, data length = " SIZEFMTD, spellId, cast_count, cast_flags, recvPacket.size()); SpellEntry const* spellInfo = sSpellTemplate.LookupEntry<SpellEntry>(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; } } // client provided targets SpellCastTargets targets; #ifdef BUILD_PLAYERBOT recvPacket >> targets.ReadForCaster(mover); #else recvPacket >> targets.ReadForCaster(_player); #endif // some spell cast packet including more data (for projectiles) targets.ReadAdditionalSpellData(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 nullptr 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 ? TRIGGERED_OLD_TRIGGERED : TRIGGERED_NONE, mover->GetObjectGuid(), triggeredByAura ? triggeredByAura->GetSpellProto() : nullptr); spell->m_cast_count = cast_count; // set count of casts spell->SpellStart(&targets, triggeredByAura); }
SPELL_EFFECT_OVERRIDE_RETURNS AH_642( Aura *aur, bool apply, uint8 i ) { if( apply == true && aur->GetSpellProto()->eff[i].EffectApplyAuraName == SPELL_AURA_SCHOOL_IMMUNITY ) { //remove dots from target Unit *t = aur->GetTarget(); for(uint32 x=MAX_POSITIVE_AURAS; x<MAX_NEGATIVE_AURAS1(t); x++) { Aura *pAura = t->m_auras[i]; if( pAura != aur && pAura != NULL && !pAura->IsPassive() && !pAura->IsPositive() && !(pAura->GetSpellProto()->Attributes & ATTRIBUTES_IGNORE_INVULNERABILITY) ) pAura->Remove(); } t->RemoveAurasByInterruptFlag( AURA_INTERRUPT_ON_INVINCIBLE ); for(uint32 i = 0; i < SCHOOL_COUNT; i++) if( aur->mod->m_miscValue & (1<<i) ) t->RemoveAurasOfSchool(i, false, true); //hmm, script this if you need. Cyclone does not need to remove DOTS, just make you immune to dmg } return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; }
SPELL_EFFECT_OVERRIDE_RETURNS AH_33763( Aura *aur, bool apply, uint8 i ) { if( apply == false ) { Unit *m_target = aur->GetTarget(); if( m_target->isAlive() == false ) { return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; } //do not proc if this is getting removed due to aplying to new target ( from script ) if( aur->GetTimeLeft() > 500 && ( ( aur->m_flags & WAS_REMOVED_ON_DISPEL ) == 0 ) ) { return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; } // apply ONCE only. int64 *LockExecution = (int64*)m_target->GetCreateIn64Extension( EXTENSION_ID_LIFEBLOOM_DISABLER ); //"lifebloomdisabler" if( *LockExecution >= getMSTime() ) { return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; } *LockExecution = getMSTime() + 1000; //after we made sure the stacks will not heal due to auto remove. We can exit this function if( ( aur->m_flags & ( WAS_REMOVED_ON_PLAYER_REQUEST | WAS_REMOVED_ON_SCRIPT_REQUEST ) ) != 0 ) return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; Unit * pCaster = aur->GetUnitCaster(); if( pCaster == NULL ) pCaster = m_target; // Remove other Lifeblooms - but do NOT handle unapply again // bool expired = true; /* for(uint32 x=MAX_AURAS;x<MAX_POSITIVE_AURAS1( m_target );x++) { if(m_target->m_auras[x] && m_target->m_auras[x]->GetSpellId() == aur->GetSpellId() ) { if( m_target->m_auras[x]->GetTimeLeft() != 0 ) expired = false; m_target->m_auras[x]->Remove(); } } */ // if( expired ) { /* Heals the target for ${$o1*$<mult>} over $d. When Lifebloom expires or is dispelled, the target is instantly healed for ${$m2*$<bloom>}. This effect can stack up to $u times on the same target. $?a33891[][Lifebloom can be active only on one target at a time.]$?s33891[ |C0033AA11Tree of Life: Can be cast on unlimited targets.|R][] 176,"$genesis1=$?s57810[${1+0.01*$57810m1}][${1}] $genesis2=$?s57811[${1+0.01*$57811m1}][${$<genesis1>}] $genesis3=$?s57812[${1+0.01*$57812m1}][${$<genesis2>}] $mult=${$<genesis3>} $mstrshape=$?s48411[${1+0.01*$48411m1}][${1}] $gotem1=$?s51179[${1+0.01*$51179m1}][${1}] $gotem2=$?s51180[${1+0.01*$51180m1}][${$<gotem1>}] $gotem3=$?s51181[${1+0.01*$51181m1}][${$<gotem2>}] $tol=$?a5420[${1+0.01+$5420m1}][${1}] $gift=$?s87305[${1.25}][${1}] $bloom=${$<gift>*$<genesis3>*$<mstrshape>*$<gotem3>*$<tol>}", 5420 - Tree of Life 48411 - Master Shapeshifter 51181 - Gift of the Earthmother 57812 - Genesis - balance tree 87305 - Gift of Nature - */ int32 earthmother = 0; int32 LifeBloomCount = m_target->CountAuraNameHash( SPELL_HASH_LIFEBLOOM, AURA_SEARCH_POSITIVE ); Spell *spell=SpellPool.PooledNew( __FILE__, __LINE__ ); spell->Init( pCaster, aur->GetSpellProto(), true, NULL ); SpellCastTargets targets2( m_target->GetGUID() ); // spell->SetUnitTarget( m_target ); { Aura *a = pCaster->HasAuraWithNameHash( SPELL_HASH_GIFT_OF_THE_EARTHMOTHER, 0, AURA_SEARCH_PASSIVE ); if( a ) earthmother = a->GetSpellProto()->eff[0].EffectBasePoints; } spell->redirected_effect[0] = SPELL_EFFECT_REDIRECT_FLAG_REDIRECT_ALL_TARGETS; spell->forced_pct_mod[1] += LifeBloomCount * 100; spell->forced_pct_mod[1] = ( spell->forced_pct_mod[1] * ( 100 + earthmother ) ) / 100; spell->redirected_effect[2] = SPELL_EFFECT_REDIRECT_FLAG_REDIRECT_ALL_TARGETS; spell->prepare( &targets2 ); /* { int32 dmg = spell->CalculateEffect( 1, m_target ); earthmother = earthmother * dmg / 100; spell->Heal( dmg, false, 1 ); spell->Heal( earthmother, false, 1 ); } SpellPool.PooledDelete( spell );*/ /* //was not able to find earth mother combat log ID if( earthmother != 0 ) { SpellEntry *spearthmother = dbcSpell.LookupEntryForced( 51180 ); Spell *spell=SpellPool.PooledNew( __FILE__, __LINE__ ); spell->Init(pCaster, spearthmother, true, NULL); spell->SetUnitTarget( m_target ); spell->Heal( earthmother ); SpellPool.PooledDelete( spell ); }*/ } } return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; }
void AuraInterface::AddAura(Aura* aur) { uint32 x,delslot = 0; Unit* pCaster = NULLUNIT; if(aur->GetUnitTarget() != NULL) pCaster = aur->GetUnitCaster(); else if( aur->GetCasterGUID() == m_Unit->GetGUID() ) pCaster = m_Unit; else if( m_Unit->GetMapMgr() && aur->GetCasterGUID()) pCaster = m_Unit->GetMapMgr()->GetUnit( aur->GetCasterGUID()); if(pCaster == NULL) return; if( !aur->IsPassive() ) { uint32 maxStack = aur->GetSpellProto()->maxstack; if( m_Unit->IsPlayer() && TO_PLAYER(m_Unit)->stack_cheat ) maxStack = 255; SpellEntry * info = aur->GetSpellProto(); bool deleteAur = false; Aura* curAura = NULLAURA; //check if we already have this aura by this caster -> update duration // Nasty check for Blood Fury debuff (spell system based on namehashes is bs anyways) if( !info->always_apply ) { for( x = 0; x < MAX_AURAS; x++ ) { if(m_auras.find(x) == m_auras.end()) continue; curAura = m_auras.at(x); if( curAura != NULL && !curAura->m_deleted ) { if( curAura->GetSpellProto()->Id != aur->GetSpellId() && ( aur->pSpellId != curAura->GetSpellProto()->Id )) //if this is a proc spell then it should not remove it's mother : test with combustion later { if( info->buffType > 0 && m_auras.at(x)->GetSpellProto()->buffType > 0 && (info->buffType & m_auras.at(x)->GetSpellProto()->buffType) ) { if( m_auras.at(x)->GetSpellProto()->buffType & SPELL_TYPE_BLESSING ) { // stupid blessings // if you have better idea correct bool ispair = false; switch( info->NameHash ) { case SPELL_HASH_BLESSING_OF_MIGHT: case SPELL_HASH_GREATER_BLESSING_OF_MIGHT: { if( m_auras.at(x)->GetSpellProto()->NameHash == SPELL_HASH_BLESSING_OF_MIGHT || m_auras.at(x)->GetSpellProto()->NameHash == SPELL_HASH_GREATER_BLESSING_OF_MIGHT ) ispair = true; }break; case SPELL_HASH_BLESSING_OF_WISDOM: case SPELL_HASH_GREATER_BLESSING_OF_WISDOM: { if( m_auras.at(x)->GetSpellProto()->NameHash == SPELL_HASH_BLESSING_OF_WISDOM || m_auras.at(x)->GetSpellProto()->NameHash == SPELL_HASH_GREATER_BLESSING_OF_WISDOM ) ispair = true; }break; case SPELL_HASH_BLESSING_OF_KINGS: case SPELL_HASH_GREATER_BLESSING_OF_KINGS: { if( m_auras.at(x)->GetSpellProto()->NameHash == SPELL_HASH_BLESSING_OF_KINGS || m_auras.at(x)->GetSpellProto()->NameHash == SPELL_HASH_GREATER_BLESSING_OF_KINGS ) ispair = true; }break; case SPELL_HASH_BLESSING_OF_SANCTUARY: case SPELL_HASH_GREATER_BLESSING_OF_SANCTUARY: { if( m_auras.at(x)->GetSpellProto()->NameHash == SPELL_HASH_BLESSING_OF_SANCTUARY || m_auras.at(x)->GetSpellProto()->NameHash == SPELL_HASH_GREATER_BLESSING_OF_SANCTUARY ) ispair = true; }break; } if( m_auras.at(x)->GetUnitCaster() == aur->GetUnitCaster() || ispair ) { RemoveAuraBySlot(x); continue; } } else if( m_auras.at(x)->GetSpellProto()->buffType & SPELL_TYPE_AURA ) { if( m_auras.at(x)->GetUnitCaster() == aur->GetUnitCaster() || m_auras.at(x)->GetSpellProto()->NameHash == info->NameHash ) { RemoveAuraBySlot(x); continue; } } else { RemoveAuraBySlot(x); continue; } } else if( info->poison_type > 0 && m_auras.at(x)->GetSpellProto()->poison_type == info->poison_type ) { if( m_auras.at(x)->GetSpellProto()->RankNumber < info->RankNumber || maxStack == 0) { RemoveAuraBySlot(x); continue; } else if( m_auras.at(x)->GetSpellProto()->RankNumber > info->RankNumber ) { RemoveAuraBySlot(x); break; } } else if( m_auras.at(x)->GetSpellProto()->NameHash == info->NameHash ) { if( m_auras.at(x)->GetUnitCaster() == aur->GetUnitCaster() ) { RemoveAuraBySlot(x); continue; } else if( m_auras.at(x)->GetSpellProto()->Unique ) { if( m_auras.at(x)->GetSpellProto()->RankNumber < info->RankNumber ) { RemoveAuraBySlot(x); continue; } else { delslot = x; deleteAur = true; break; } } } } else if( curAura->GetSpellId() == aur->GetSpellId() ) { if( !aur->IsPositive() && curAura->GetCasterGUID() != aur->GetCasterGUID() && maxStack == 0 && !info->Unique ) continue; // target already has this aura. Update duration, time left, procCharges curAura->SetDuration(aur->GetDuration()); curAura->SetTimeLeft(aur->GetDuration()); curAura->procCharges = curAura->GetMaxProcCharges(pCaster); curAura->UpdateModifiers(); curAura->ModStackSize(1); // increment stack size return; } } } } if(deleteAur) { sEventMgr.RemoveEvents(aur); RemoveAuraBySlot(delslot); return; } } //////////////////////////////////////////////////////// if( aur->m_auraSlot != 255 && aur->m_auraSlot < TOTAL_AURAS) { if( m_auras.find(aur->m_auraSlot) != m_auras.end() ) RemoveAuraBySlot(aur->m_auraSlot); } aur->m_auraSlot = 255; Unit* target = aur->GetUnitTarget(); if(target == NULL) return; // Should never happen. aur->SetAuraFlags(AFLAG_VISIBLE | AFLAG_EFF_INDEX_1 | AFLAG_EFF_INDEX_2 | AFLAG_NOT_GUID | (aur->GetDuration() ? AFLAG_HAS_DURATION : AFLAG_NONE) | (aur->IsPositive() ? (AFLAG_POSITIVE) : (AFLAG_NEGATIVE))); aur->SetAuraLevel(aur->GetUnitCaster() != NULL ? aur->GetUnitCaster()->getLevel() : MAXIMUM_ATTAINABLE_LEVEL); if(!aur->IsPassive()) { aur->AddAuraVisual(); if(aur->m_auraSlot == 255) { //add to invisible slot for(x = MAX_AURAS; x < TOTAL_AURAS; x++) { if(m_auras.find(x) == m_auras.end()) { m_auras.insert(make_pair(x, aur)); aur->m_auraSlot = x; break; } } if(aur->m_auraSlot == 255) { DEBUG_LOG("Unit","AddAura error in active aura. removing. SpellId: %u", aur->GetSpellProto()->Id); RemoveAura(aur); return; } } else { m_auras.insert(make_pair(aur->m_auraSlot, aur)); } } else { if(aur->m_spellProto->AttributesEx & 1024) aur->AddAuraVisual(); for(x = MAX_AURAS; x < TOTAL_AURAS; x++) { if(m_auras.find(x) == m_auras.end()) { m_auras.insert(make_pair(x, aur)); aur->m_auraSlot = x; break; } } if(aur->m_auraSlot == 255) { DEBUG_LOG("Unit","AddAura error in passive aura. removing. SpellId: %u", aur->GetSpellProto()->Id); RemoveAura(aur); return; } } if(aur->GetSpellId() == 15007) //Resurrection sickness { aur->SetNegative(100); //we're negative aur->SetDuration(target->getLevel() > 19 ? 600000 : 60000); } aur->ApplyModifiers(true); // We add 500ms here to allow for the last tick in DoT spells. This is a dirty hack, but at least it doesn't crash like my other method. // - Burlex, Crow: Changed to 400ms if(aur->GetDuration() > 0) { uint32 addTime = 400; for(uint32 spx = 0; spx < 3; spx++) { if( aur->GetSpellProto()->EffectApplyAuraName[spx] == SPELL_AURA_MOD_STUN || aur->GetSpellProto()->EffectApplyAuraName[spx] == SPELL_AURA_MOD_FEAR || aur->GetSpellProto()->EffectApplyAuraName[spx] == SPELL_AURA_MOD_ROOT || aur->GetSpellProto()->EffectApplyAuraName[spx] == SPELL_AURA_MOD_CHARM ) addTime = 50; } sEventMgr.AddAuraEvent(m_Unit, &Unit::RemoveAuraBySlot, uint8(aur->m_auraSlot), aur->GetDuration() + addTime, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT | EVENT_FLAG_DELETES_OBJECT, aur->GetSpellId()); } aur->RelocateEvents(); // Send log to client if (target != NULL) { //send the aura log WorldPacket data(SMSG_AURACASTLOG, 28); data << aur->GetCasterGUID(); data << aur->GetTargetGUID(); data << aur->m_spellProto->Id; data << uint64(0); target->SendMessageToSet(&data, true); } m_Unit->m_chargeSpellsInUse = true; if( aur->procCharges > 0 && !(aur->GetSpellProto()->procflags2 & PROC_REMOVEONUSE)) m_Unit->m_chargeSpells.push_back(aur); m_Unit->m_chargeSpellsInUse = false; aur->m_added = true; // Reaction from enemy AI if( !aur->IsPositive() && CanAgroHash( aur->GetSpellProto()->NameHash ) ) { if(pCaster != NULL && m_Unit->isAlive()) { pCaster->CombatStatus.OnDamageDealt(TO_UNIT(this), 1); if(m_Unit->IsCreature()) m_Unit->GetAIInterface()->AttackReaction(pCaster, 1, aur->GetSpellId()); } } if (aur->GetSpellProto()->AuraInterruptFlags & AURA_INTERRUPT_ON_INVINCIBLE) { if( pCaster != NULL ) { pCaster->RemoveStealth(); pCaster->RemoveInvisibility(); pCaster->m_AuraInterface.RemoveAllAurasByNameHash(SPELL_HASH_ICE_BLOCK, false); pCaster->m_AuraInterface.RemoveAllAurasByNameHash(SPELL_HASH_DIVINE_SHIELD, false); pCaster->m_AuraInterface.RemoveAllAurasByNameHash(SPELL_HASH_BLESSING_OF_PROTECTION, false); } } }
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 = _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); 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; } }
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); }
bool PlayerbotClassAI::castSelfCCBreakers (uint32 castList[]) { uint32 dispelSpell = 0; Player *dTarget = GetPlayerBot(); /* dispelSpell = (uint32) R_ESCAPE_ARTIST; // this is script effect, Unit::AuraMap const& auras = dTarget->GetOwnedAuras(); for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++) { Aura * aura = itr->second; AuraApplication * aurApp = aura->GetApplicationOfTarget(dTarget->GetGUID()); if (!aurApp) continue; if ( ( aura->GetSpellProto()->Mechanic == MECHANIC_SNARE ) || ( aura->GetSpellProto()->Mechanic == MECHANIC_ROOT ) ) { if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC) { bool positive = aurApp->IsPositive() ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR0_UNK7)) : false; // do not remove positive auras if friendly target // negative auras if non-friendly target if(positive == dTarget->IsFriendlyTo(caster)) continue; } return castSpell(dispelSpell, dTarget); } } return false; */ // racial abilities /* if( GetPlayerBot()->getRace() == RACE_BLOODELF && !pTarget->HasAura( ARCANE_TORRENT,0 ) && castSpell( ARCANE_TORRENT,pTarget ) ) { //GetPlayerBot()->Say("Arcane Torrent!", LANG_UNIVERSAL); } else if( GetPlayerBot()->getRace() == RACE_HUMAN && (GetPlayerBot()->HasUnitState( UNIT_STAT_STUNNED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_FEAR ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_DECREASE_SPEED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_CHARM )) && castSpell( EVERY_MAN_FOR_HIMSELF, GetPlayerBot() ) ) { //GetPlayerBot()->Say("EVERY MAN FOR HIMSELF!", LANG_UNIVERSAL); } else if( GetPlayerBot()->getRace() == RACE_UNDEAD_PLAYER && (GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_FEAR ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_CHARM )) && castSpell( WILL_OF_THE_FORSAKEN, GetPlayerBot() ) ) { // GetPlayerBot()->Say("WILL OF THE FORSAKEN!", LANG_UNIVERSAL); } else if( GetPlayerBot()->getRace() == RACE_DWARF && GetPlayerBot()->HasAuraState( AURA_STATE_DEADLY_POISON ) && castSpell( STONEFORM, GetPlayerBot() ) ) { //GetPlayerBot()->Say("STONEFORM!", LANG_UNIVERSAL); } else if( GetPlayerBot()->getRace() == RACE_GNOME && (GetPlayerBot()->HasUnitState( UNIT_STAT_STUNNED ) || GetPlayerBot()->HasAuraType( SPELL_AURA_MOD_DECREASE_SPEED )) && castSpell( ESCAPE_ARTIST, GetPlayerBot() ) ) { // GetPlayerBot()->Say("ESCAPE ARTIST!", LANG_UNIVERSAL); } */ for (uint8 j = 0; j < sizeof (castList); j++) { dispelSpell = castList[j]; if (dispelSpell == 0 || !dTarget->HasSpell(dispelSpell) || !CanCast(dispelSpell, dTarget, true)) continue; SpellEntry const *dSpell = GetSpellStore()->LookupEntry(dispelSpell); if (!dSpell) continue; for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS ; ++i) { if (dSpell->Effect[i] != (uint32)SPELL_EFFECT_DISPEL && dSpell->Effect[i] != (uint32)SPELL_EFFECT_APPLY_AURA) continue; if (dSpell->Effect[i] == (uint32)SPELL_EFFECT_APPLY_AURA && ( (dSpell->EffectApplyAuraName[i] != (uint32) SPELL_AURA_MECHANIC_IMMUNITY) || (dSpell->EffectApplyAuraName[i] != (uint32) SPELL_AURA_DISPEL_IMMUNITY) )) continue; Unit::AuraMap const& auras = dTarget->GetOwnedAuras(); for (Unit::AuraMap::const_iterator itr = auras.begin(); itr != auras.end(); itr++) { Aura * aura = itr->second; AuraApplication * aurApp = aura->GetApplicationOfTarget(dTarget->GetGUID()); if (!aurApp) continue; if (aura->GetSpellProto() && ( (dSpell->Effect[i] == (uint32)SPELL_EFFECT_DISPEL && ((1<<aura->GetSpellProto()->Dispel) & GetDispellMask(DispelType(dSpell->EffectMiscValue[i]))) ) || (dSpell->EffectApplyAuraName[i] == (uint32) SPELL_AURA_MECHANIC_IMMUNITY && ( GetAllSpellMechanicMask(aura->GetSpellProto()) & ( 1 << dSpell->EffectMiscValue[i]) ) ) || (dSpell->EffectApplyAuraName[i] == (uint32) SPELL_AURA_DISPEL_IMMUNITY && ( (1<<aura->GetSpellProto()->Dispel) & GetDispellMask(DispelType(dSpell->EffectMiscValue[i])) ) ) ) ) { if(aura->GetSpellProto()->Dispel == DISPEL_MAGIC) { bool positive = aurApp->IsPositive() ? (!(aura->GetSpellProto()->AttributesEx & SPELL_ATTR0_UNK7)) : false; if(positive)continue; } return CastSpell(dispelSpell, dTarget, false); } } } } return false; }
SPELL_EFFECT_OVERRIDE_RETURNS AH_31821( Aura *aur, bool apply, uint8 i ) { if( i == 0 ) { Unit *target = aur->GetTarget(); //this is actually caster Aura *a; if( apply ) { InRangeSetRecProt::iterator itr; target->AquireInrangeLock(); //make sure to release lock before exit function ! InrangeLoopExitAutoCallback AutoLock; for( itr = target->GetInRangeSetBegin( AutoLock ); itr != target->GetInRangeSetEnd(); itr++ ) { if(!((*itr)->IsUnit()) || !SafeUnitCast((*itr))->isAlive()) continue; a = SafeUnitCast((*itr))->HasAuraWithNameHash( SPELL_HASH_CONCENTRATION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a != NULL ) target->CastSpell( SafeUnitCast((*itr)), 64364, true ); //immunity } target->ReleaseInrangeLock(); a = target->HasAuraWithNameHash( SPELL_HASH_CONCENTRATION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a != NULL ) { target->CastSpell( target, 64364, true ); //immunity } else { if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_DEVOTION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_RESISTANCE_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_RETRIBUTION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a != NULL ) { SpellEntry *sp = a->GetSpellProto(); a->Remove(); a = NULL; target->CastSpellDelayed( target->GetGUID(), sp->Id, 1, true ); } } } else { target->RemoveAura( 64364 ); //immunity a = target->HasAuraWithNameHash( SPELL_HASH_DEVOTION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_RESISTANCE_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a == NULL ) a = target->HasAuraWithNameHash( SPELL_HASH_RETRIBUTION_AURA, target->GetGUID(), AURA_SEARCH_POSITIVE ); if( a != NULL ) { SpellEntry *sp = a->GetSpellProto(); a->Remove(); a = NULL; target->CastSpellDelayed( target->GetGUID(), sp->Id, 1, true ); } } } return SPELL_EFFECT_OVERRIDE_CONTINUE_EXECUTION; }