Пример #1
0
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;
}
Пример #2
0
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;
			}
		}
	}
}
Пример #3
0
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;
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
0
        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);
        }
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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
				}
			}
		}
	}
}
Пример #11
0
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;
}
Пример #12
0
		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);
		}
Пример #13
0
		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;
		}
Пример #14
0
            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);
                        }
                    }
            }
Пример #15
0
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);
}
Пример #16
0
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;
}
Пример #17
0
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;
    }
}
Пример #18
0
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);
		}
	}
}
Пример #19
0
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);
}
Пример #20
0
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;
}
Пример #21
0
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;
}
Пример #22
0
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);
		}
	}
}
Пример #23
0
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;
    }
}
Пример #24
0
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);
}
Пример #25
0
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;
}
Пример #26
0
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;
}