Public feed
#891102
Index: src/game/SharedDefines.h===================================================================--- src/game/SharedDefines.h (revision 5143)+++ src/game/SharedDefines.h (working copy)@@ -359,7 +359,7 @@ SPELL_EFFECT_123 = 123, SPELL_EFFECT_PLAYER_PULL = 124, SPELL_EFFECT_REDUCE_THREAT_PERCENT = 125,- SPELL_EFFECT_STEAL_BENEFICIAL_BUFF = 126,+ SPELL_EFFECT_SPELL_STEAL = 126, SPELL_EFFECT_PROSPECTING = 127, SPELL_EFFECT_APPLY_AURA_NEW2 = 128, SPELL_EFFECT_129 = 129,Index: src/game/Spell.cpp===================================================================--- src/game/Spell.cpp (revision 5143)+++ src/game/Spell.cpp (working copy)@@ -3108,6 +3108,27 @@ } } + // DISPEL - returns Nothing to dispel if no aura targets+ bool noDispel[3];+ noDispel[0] = false; noDispel[1] = false; noDispel[2] = false;+ for(int j = 0; j < 3; j++)+ {+ if(m_spellInfo->Effect[j] == SPELL_EFFECT_DISPEL && m_targets.getUnitTarget())+ {+ if(m_targets.getUnitTarget()->DispelAura(m_spellInfo->Id, j, m_caster, false, false, false) == 0)+ noDispel[j] = true;+ }+ }+ if(noDispel[0] && noDispel[1] && noDispel[2])+ return SPELL_FAILED_NOTHING_TO_DISPEL;++ // SPELL STEAL - returns Nothing to steal if no aura targets+ if(m_spellInfo->Effect[0] == SPELL_EFFECT_SPELL_STEAL && m_targets.getUnitTarget())+ {+ if(m_targets.getUnitTarget()->DispelAura(m_spellInfo->Id, 0, m_caster, false, false, false) == 0)+ return SPELL_FAILED_NOTHING_TO_STEAL;+ }+ for (int i = 0; i < 3; i++) { switch(m_spellInfo->EffectApplyAuraName[i])Index: src/game/Spell.h===================================================================--- src/game/Spell.h (revision 5143)+++ src/game/Spell.h (working copy)@@ -458,7 +458,7 @@ void EffectSkinPlayerCorpse(uint32 i); void EffectApplyPetAura(uint32 i); void EffectSummonDemon(uint32 i);- void EffectStealBeneficialBuff(uint32 i);+ void EffectSpellSteal(uint32 i); void EffectUnlearnSpecialization(uint32 i); Spell( Unit* Caster, SpellEntry const *info, bool triggered, uint64 originalCasterGUID = 0, Spell** triggeringContainer = NULL );Index: src/game/SpellAuras.cpp===================================================================--- src/game/SpellAuras.cpp (revision 5143)+++ src/game/SpellAuras.cpp (working copy)@@ -2729,6 +2729,7 @@ //immune movement impairement and loss of control if(GetId()==42292) mechanic=0x9967da6;+ std::vector<uint32> removeId; if(apply) {@@ -2746,6 +2747,7 @@ if( ((1<<spell->Mechanic) & mechanic) || ((1<<spell->EffectMechanic[iter->second->GetEffIndex()]) & mechanic)) { m_target->RemoveAurasDueToSpell(spell->Id);+ removeId.push_back(spell->Id); if(Auras.empty()) break; else@@ -2753,6 +2755,26 @@ } } }++ if(m_target->GetTypeId() == TYPEID_PLAYER && removeId.size())+ {+ // Struct for immunities SMSG_SPELLDISPELLOG always that type+ WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+2+4+12*removeId.size());+ data.append(m_target->GetPackGUID());+ data << uint8(0x0);+ data << uint32(0x0);+ data << uint8(0x1);+ data << uint32(removeId.size());++ for(uint32 j = 0; j < removeId.size(); j++)+ {+ data << uint32(removeId[j]);+ data << uint32(0x0);+ data << uint32(0x64);+ }++ ((Player*)m_target)->GetSession()->SendPacket(&data);+ } } m_target->ApplySpellImmune(GetId(),IMMUNITY_MECHANIC,m_modifier.m_miscvalue,apply);@@ -2827,6 +2849,7 @@ if(IsPositiveSpell(GetId())) //Only positive immunity removes auras { uint32 school_mask = m_modifier.m_miscvalue;+ std::vector<uint32> auras2remove; Unit::AuraMap& Auras = m_target->GetAuras(); for(Unit::AuraMap::iterator iter = Auras.begin(), next; iter != Auras.end(); iter = next) {@@ -2838,6 +2861,7 @@ && !iter->second->IsPositive() //Don't remove positive spells && spell->Id != GetId()) //Don't remove self {+ auras2remove.push_back(spell->Id); m_target->RemoveAurasDueToSpell(spell->Id); if(Auras.empty()) break;@@ -2845,6 +2869,26 @@ next = Auras.begin(); } }++ if(m_target->GetTypeId() == TYPEID_PLAYER && auras2remove.size())+ {+ // Struct for immunities SMSG_SPELLDISPELLOG always that type+ WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+2+4+12*auras2remove.size());+ data.append(m_target->GetPackGUID());+ data << uint8(0x0);+ data << uint32(0x0);+ data << uint8(0x1);+ data << uint32(auras2remove.size());++ for(uint32 j = 0; j < auras2remove.size(); j++)+ {+ data << uint32(auras2remove[j]);+ data << uint32(0x0);+ data << uint32(0x64);+ }++ ((Player*)m_target)->GetSession()->SendPacket(&data);+ } } } }Index: src/game/SpellEffects.cpp===================================================================--- src/game/SpellEffects.cpp (revision 5143)+++ src/game/SpellEffects.cpp (working copy)@@ -184,7 +184,7 @@ &Spell::EffectNULL, //123 SPELL_EFFECT_123 taxi/flight related &Spell::EffectPlayerPull, //124 SPELL_EFFECT_PLAYER_PULL opposite of knockback effect (pulls player twoard caster) &Spell::EffectReduceThreatPercent, //125 SPELL_EFFECT_REDUCE_THREAT_PERCENT- &Spell::EffectStealBeneficialBuff, //126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF spell steal effect?+ &Spell::EffectSpellSteal, //126 SPELL_EFFECT_126 spell steal effect? &Spell::EffectProspecting, //127 SPELL_EFFECT_PROSPECTING Prospecting spell &Spell::EffectApplyAura, //128 SPELL_EFFECT_APPLY_AURA_NEW2 probably apply aura again &Spell::EffectNULL, //129 SPELL_EFFECT_129 probably apply aura again@@ -2335,15 +2335,66 @@ { if(!unitTarget) return;-+ std::vector<uint32> removeId; for(int n = 0 ; n < damage; ++n)- if(unitTarget->RemoveFirstAuraByDispel(m_spellInfo->EffectMiscValue[i], m_caster))+ {+ uint32 dispelled_id =unitTarget->DispelAura(m_spellInfo->Id, i, m_caster, true, true, false);+ if(dispelled_id)+ {+ removeId.push_back(dispelled_id); sLog.outDebug("Spell: Removed aura type %u from %s %u (removed by %s %u)", m_spellInfo->EffectMiscValue[i], unitTarget->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", unitTarget->GetGUIDLow(), m_caster->GetTypeId()==TYPEID_PLAYER ? "player" : "creature", m_caster->GetGUIDLow() );+ }+ }+ if(unitTarget->GetTypeId() != TYPEID_PLAYER)+ return;+ WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+2+4+4*removeId.size());+ data.append(unitTarget->GetPackGUID());+ if(m_CastItem && unitTarget == m_caster)+ {+ data << uint8(0x0);+ data << uint32(0x0);+ }+ else+ {+ data.append(m_caster->GetPackGUID());+ data << uint32(m_spellInfo->Id);+ }+ data << uint8(0x0);+ data << uint32(removeId.size());+ for(uint32 j = 0; j < removeId.size(); j++)+ data << uint32(removeId[j]);+ ((Player*)unitTarget)->GetSession()->SendPacket(&data); } +void Spell::EffectSpellSteal(uint32 i)+{+ if(!unitTarget || !unitTarget->isAlive())+ return;++ uint32 resultId;+ for(int j = 0; j <= m_spellInfo->EffectBasePoints[i]; j++)+ resultId = unitTarget->DispelAura(m_spellInfo->Id, i, m_caster, true, true, true);++ if(!resultId || m_caster->GetTypeId() != TYPEID_PLAYER)+ return;++ // Packet should sends only to players+ if(unitTarget->GetTypeId() != TYPEID_PLAYER)+ return;++ WorldPacket data(SMSG_SPELLDISPELLOG, 8+8+4+2+4+4);+ data.append(unitTarget->GetPackGUID());+ data.append(m_caster->GetPackGUID());+ data << uint32(m_spellInfo->Id);+ data << uint8(0x0);+ data << uint32(0x1);+ data << uint32(resultId);+ ((Player*)unitTarget)->GetSession()->SendPacket(&data);+}+ void Spell::EffectDualWield(uint32 /*i*/) { if (unitTarget->GetTypeId() == TYPEID_PLAYER)@@ -4574,89 +4625,3 @@ ((Player*)unitTarget)->RemovedInsignia( (Player*)m_caster ); } -void Spell::EffectStealBeneficialBuff(uint32 /*i*/)-{- sLog.outDebug("Effect: StealBeneficialBuff");-- // get the auras of the target- Unit::AuraMap& Auras = unitTarget->GetAuras();-- // count possible for steal auras- uint32 count = 0;- for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter)- {- if( iter->second->IsPositive() && //only steel positive spell- !iter->second->IsPassive() && //don't steal passive abilities- !iter->second->IsPersistent() && //don't steal persistent auras- iter->second->GetSpellProto()->Dispel == m_spellInfo->Dispel )- //only steal magic effects- ++count;- }-- // not found any?- if(!count)- return;-- // random buff to steal- uint32 remove_prev_positive = urand(0, count-1);-- // id of the spell we'll steal- uint32 spellId = 0;-- // select aura by index- count = 0;- for(Unit::AuraMap::iterator iter = Auras.begin(); iter != Auras.end(); ++iter)- {- if( iter->second->IsPositive() && //only steel positive spell- !iter->second->IsPassive() && //don't steal passive abilities- !iter->second->IsPersistent() && //don't steal persistent auras- iter->second->GetSpellProto()->Dispel == m_spellInfo->Dispel )- //only steal magic effects- {- if(count==remove_prev_positive)- {- spellId = iter->first.first; // store the id of the last stealable spell- break;- }-- ++count;- }- }-- // we found a stealable buff- if(spellId)- {- // max duration 2 minutes (in msecs)- const int32 max_dur = 2*MINUTE*1000;-- // go through all the effects of the spell- for(int i=0; i<3; ++i)- {- // get the corresponding aura from the victim- Aura * aur = unitTarget->GetAura(spellId, i);-- if(!aur)- continue;-- // we have to check against the (remaining) duration on the victim- int32 dur = aur->GetAuraDuration();- int32 basePoints = aur->GetBasePoints();-- // construct the new aura for the attacker- Aura * new_aur = new Aura(aur->GetSpellProto(), i, &basePoints, m_caster);-- if(!new_aur)- continue;-- // set its duration and maximum duration- new_aur->SetAuraMaxDuration( max_dur > dur ? dur : max_dur );- new_aur->SetAuraDuration( max_dur > dur ? dur : max_dur );-- // add the new aura- m_caster->AddAura(new_aur);- }-- // remove the auras caused by the stolen spell from the victim- unitTarget->RemoveAurasDueToSpell(spellId);- }-}Index: src/game/Unit.cpp===================================================================--- src/game/Unit.cpp (revision 5143)+++ src/game/Unit.cpp (working copy)@@ -3540,39 +3540,116 @@ return true; } -bool Unit::RemoveFirstAuraByDispel(uint32 dispel_type, Unit *pCaster)+uint32 Unit::DispelAura(uint32 dispel_id, int32 effIndex, Unit *pCaster, bool removeAura, bool checkResist, bool steal) {- AuraMap::iterator i;- for (i = m_Auras.begin(); i != m_Auras.end();)- {- if ((*i).second && (*i).second->GetSpellProto()->Dispel == dispel_type)- {- SpellEntry const* spellInfo = (*i).second->GetSpellProto();- uint32 eff = (*i).second->GetEffIndex();-- if(dispel_type == 1)- {- bool positive = true;-- if(!IsPositiveTarget(spellInfo->EffectImplicitTargetA[eff],spellInfo->EffectImplicitTargetB[eff]))- positive = false;- else- positive = (spellInfo->AttributesEx & (1<<7))==0;-- if(positive && IsFriendlyTo(pCaster)) // PBW- {- ++i;- continue;- }- }- RemoveAura(i);- return true;- }- else- ++i;- }-- return false;+ // Steal can only be enabled while RemoveAura is also true+ if(steal)+ ASSERT(removeAura);+ + SpellEntry const *dispelProto = sSpellStore.LookupEntry(dispel_id);+ if(!dispelProto) return 0;+ + uint32 dispel_type = dispelProto->EffectMiscValue[effIndex];+ uint32 removeId = 0;+ AuraMap::iterator i;+ for (i = m_Auras.begin(); i != m_Auras.end();)+ {+ if ((*i).second && (*i).second->GetSpellProto()->Dispel == dispel_type)+ {+ if(dispel_type == 1)+ {+ bool positive = true;+ switch((*i).second->GetSpellProto()->EffectImplicitTargetA[(*i).second->GetEffIndex()])+ {+ case TARGET_CHAIN_DAMAGE:+ case TARGET_ALL_ENEMY_IN_AREA:+ case TARGET_ALL_ENEMY_IN_AREA_INSTANT:+ case TARGET_ALL_AROUND_CASTER:+ case TARGET_IN_FRONT_OF_CASTER:+ case TARGET_DUELVSPLAYER:+ case TARGET_ALL_ENEMY_IN_AREA_CHANNELED:+ case TARGET_CURRENT_SELECTED_ENEMY:+ positive = false;+ break;+ default:+ positive = ((*i).second->GetSpellProto()->AttributesEx & (1<<7)) ? false : true;+ }+ if(positive == IsFriendlyTo(pCaster))+ {+ ++i;+ continue;+ }+ }+ removeId = (*i).second->GetSpellProto()->Id;+ SpellEntry const *spellProto = (*i).second->GetSpellProto();+ // Resists check+ if((*i).second->GetCasterGUID() && checkResist)+ {+ // Dispel resist handling+ int32 Chance = 0; // Base chance+ Unit *auraCaster = (*i).second->GetCaster();+ if(auraCaster && pCaster->GetTypeId() == TYPEID_PLAYER)+ {+ if(auraCaster->GetTypeId() == TYPEID_PLAYER)+ ((Player*)auraCaster)->ApplySpellMod(removeId, SPELLMOD_RESIST_DISPEL_CHANCE, Chance);+ Chance = Chance - spellProto->spellLevel + dispelProto->spellLevel;+ if(Chance < 0 ) Chance = 0;+ if(urand(1,100) <= Chance)+ {+ // Resist+ WorldPacket data(SMSG_DISPEL_FAILED, 8+4+8+4+4+4);+ data.append(pCaster->GetPackGUID());+ data << uint32(0x0);+ data.append(this->GetPackGUID());+ data << uint32(0x0);+ data << uint32(dispel_id);+ data << uint32(spellProto->Id);+ ((Player*)pCaster)->GetSession()->SendPacket(&data);+ return 0;+ }+ }+ }+ // Remove+ if(removeAura)+ {+ // Stealing buffs+ if(steal && pCaster)+ {+ int32 effect0 = 0;+ int32 effect1 = 0;+ int32 effect2 = 0;+ SpellEntry const *originalSpell = sSpellStore.LookupEntry(removeId);+ // Add auras for the caster+ for(int j = 0; j < 3; j++)+ {+ Aura *oldAur = GetAura(removeId, j);+ if(oldAur)+ {+ int32 newBasePoints = oldAur->GetModifier()->m_amount-1;+ Aura* Aur = new Aura(originalSpell, j, &newBasePoints, pCaster, pCaster, NULL);+ if(Aur->GetAuraDuration() > 120000)+ Aur->SetAuraDuration(120000);+ bool added = pCaster->AddAura(Aur);+ if(!added)+ sLog.outError("Error in Spell Steal - aura cannot be added!");+ }+ }+ }+ // Unstable Affliction+ if(spellProto->SpellFamilyName == SPELLFAMILY_WARLOCK && spellProto->SpellIconID == 2039 &&+ spellProto->EffectApplyAuraName[0] == SPELL_AURA_PERIODIC_DAMAGE)+ {+ int32 damagePoints = int32((*i).second->GetBasePoints() * 9);+ CastCustomSpell(this, 31117, &damagePoints, 0, 0, true);+ }+ RemoveAurasDueToSpell(removeId);+ }+ break;+ }+ else+ ++i;+ }+ return removeId; } void Unit::RemoveAreaAurasByOthers(uint64 guid)Index: src/game/Unit.h===================================================================--- src/game/Unit.h (revision 5143)+++ src/game/Unit.h (working copy)@@ -807,7 +807,7 @@ bool AddAura(Aura *aur); - bool RemoveFirstAuraByDispel(uint32 dispel_type, Unit *pCaster);+ uint32 DispelAura(uint32 dispel_id, int32 effIndex, Unit *pCaster, bool removeAura, bool checkResist, bool steal); void RemoveAura(AuraMap::iterator &i, bool onDeath = false); void RemoveAura(uint32 spellId, uint32 effindex); void RemoveSingleAuraFromStack(uint32 spellId, uint32 effindex);