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; } } } }
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 AuraInterface::BuildAuraUpdateAllPacket(WorldPacket* data) { if(!m_auras.size()) return false; bool res = false; Aura* aur = NULL; for (uint32 i=0; i<MAX_AURAS; i++) { if(m_auras.find(i) != m_auras.end()) { res = true; aur = m_auras.at(i); aur->BuildAuraUpdate(); uint8 flags = aur->GetAuraFlags(); *data << uint8(aur->m_auraSlot); int32 stack = aur->stackSize; if(aur->procCharges > stack && stack != 0) stack = aur->procCharges; if(stack < 0) { *data << uint32(0); continue; } *data << uint32(aur->GetSpellId()); *data << uint8(flags); *data << uint8(aur->GetUnitCaster() ? aur->GetUnitCaster()->getLevel() : 0); *data << uint8(stack); if(!(flags & AFLAG_NOT_GUID)) FastGUIDPack(*data, aur->GetCasterGUID()); if(flags & AFLAG_HAS_DURATION) { *data << aur->GetDuration(); *data << aur->GetTimeLeft(); } } } return res; }
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 AuraInterface::SaveAuras(stringstream& ss) { for(uint32 x = 0; x < MAX_AURAS; x++) // Crow: Changed to max auras in r1432, since we skip passive auras. { if(m_auras.find(x) != m_auras.end()) { Aura* aur = m_auras.at(x); // skipped spells due to bugs switch(aur->m_spellProto->Id) { case 642: case 1020: // Divine Shield case 11129: // Combustion case 12043: // Presence of mind case 16188: // Natures Swiftness case 17116: // Natures Swiftness case 23333: // WSG case 23335: // WSG case 28682: // Combustion proc case 31665: // Master of Subtlety (buff) case 32724: // Gold Team case 32725: // Green Team case 32727: // Arena Preparation case 32728: // Arena Preparation case 32071: // Hellfire Superority case 32049: // Hellfire Superority case 34936: // Backlash case 35076: // Blessing of A'dal case 35774: // Gold Team case 35775: // Green Team case 44521: // Preparation? case 44683: // Team A case 44684: // Team B case 45438: // Ice Block case 48418: // Master Shapeshifter Damage (buff) case 48420: // Master Shapeshifter Critical Strike (buff) case 48421: // Master Shapeshifter Spell Damage (buff) case 48422: // Master Shapeshifter Healing (buff) continue; break; } bool stop = false; for(uint32 i = 0; i < 3; i++) { if(!stop) { if((aur->m_spellProto->Effect[i] == SPELL_EFFECT_APPLY_AREA_AURA && aur->GetCasterGUID() != m_Unit->GetGUID()) || aur->m_spellProto->Effect[i] == SPELL_EFFECT_APPLY_AURA_128 || aur->m_spellProto->Effect[i] == SPELL_EFFECT_ADD_FARSIGHT) { stop = true; break; } } } if(stop) continue; // We are going to cast passive spells anyway on login so no need to save auras for them if( aur->IsPassive() || aur->m_spellProto->c_is_flags & SPELL_FLAG_IS_EXPIREING_WITH_PET || aur->m_spellProto->AuraInterruptFlags & AURA_INTERRUPT_ON_STAND_UP ) continue; // To prevent food/drink bug ss << aur->GetSpellId() << "," << aur->GetTimeLeft() << ","; } } }
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; }