diff options
Diffstat (limited to 'src/game/Unit.cpp')
| -rw-r--r-- | src/game/Unit.cpp | 122 |
1 files changed, 84 insertions, 38 deletions
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index efa85d137a4..f2ae30ffee6 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -1023,66 +1023,75 @@ void Unit::CastSpell(Unit* Victim,SpellEntry const *spellInfo, bool triggered, I spell->prepare(&targets, triggeredByAura); } -void Unit::CastCustomSpell(Unit* Victim,uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster) +void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster) { - SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); - - if(!spellInfo) - { - sLog.outError("CastCustomSpell: unknown spell id %i", spellId); - return; - } + CustomSpellValues values; + if(bp0) values.AddSpellMod(SPELLVALUE_BASE_POINT0, *bp0); + if(bp1) values.AddSpellMod(SPELLVALUE_BASE_POINT1, *bp1); + if(bp2) values.AddSpellMod(SPELLVALUE_BASE_POINT2, *bp2); + CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster); +} - CastCustomSpell(Victim,spellInfo,bp0,bp1,bp2,triggered,castItem,triggeredByAura, originalCaster); +void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, uint32 value, Unit* target, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster) +{ + CustomSpellValues values; + values.AddSpellMod(mod, value); + CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster); } -void Unit::CastCustomSpell(Unit* Victim,SpellEntry const *spellInfo, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster) +void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim, bool triggered, Item *castItem, AuraEffect* triggeredByAura, uint64 originalCaster) { + SpellEntry const *spellInfo = sSpellStore.LookupEntry(spellId ); if(!spellInfo) { - sLog.outError("CastCustomSpell: unknown spell"); + sLog.outError("CastSpell: unknown spell id %i by caster: %s %u)", spellId,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); return; } SpellCastTargets targets; uint32 targetMask = spellInfo->Targets; - targets.setUnitTarget(Victim); - /*if(targetMask & (TARGET_FLAG_UNIT|TARGET_FLAG_UNK2)) + + //check unit target + for(int i = 0; i < 3; ++i) { - if(!Victim) + if(spellmgr.SpellTargetType[spellInfo->EffectImplicitTargetA[i]] == TARGET_TYPE_UNIT_TARGET) { - sLog.outError("CastCustomSpell: spell id %i by caster: %s %u) does not have unit target", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); - return; + if(!Victim) + { + sLog.outError("CastSpell: spell id %i by caster: %s %u) does not have unit target", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + return; + } + else + break; } - }*/ + } + targets.setUnitTarget(Victim); + + //check destination if(targetMask & (TARGET_FLAG_SOURCE_LOCATION|TARGET_FLAG_DEST_LOCATION)) { if(!Victim) { - sLog.outError("CastCustomSpell: spell id %i by caster: %s %u) does not have destination", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + sLog.outError("CastSpell: spell id %i by caster: %s %u) does not have destination", spellInfo->Id,(GetTypeId()==TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"),(GetTypeId()==TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); return; } targets.setDestination(Victim); } - if (castItem) - DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id); - if(!originalCaster && triggeredByAura) originalCaster = triggeredByAura->GetCasterGUID(); - Spell *spell = new Spell(this, spellInfo, triggered, originalCaster); - - if(bp0) - spell->m_currentBasePoints[0] = *bp0-int32(spellInfo->EffectBaseDice[0]); + Spell *spell = new Spell(this, spellInfo, triggered, originalCaster ); - if(bp1) - spell->m_currentBasePoints[1] = *bp1-int32(spellInfo->EffectBaseDice[1]); + if(castItem) + { + DEBUG_LOG("WORLD: cast Item spellId - %i", spellInfo->Id); + spell->m_CastItem = castItem; + } - if(bp2) - spell->m_currentBasePoints[2] = *bp2-int32(spellInfo->EffectBaseDice[2]); + for(CustomSpellValues::const_iterator itr = value.begin(); itr != value.end(); ++itr) + spell->SetSpellValue(itr->first, itr->second); - spell->m_CastItem = castItem; spell->prepare(&targets, triggeredByAura); } @@ -2257,6 +2266,9 @@ void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool ex return; } + // attack can be redirected to another target + pVictim = SelectMagnetTarget(pVictim); + CalcDamageInfo damageInfo; CalculateMeleeDamage(pVictim, 0, &damageInfo, attType); // Send log damage message to client @@ -6285,8 +6297,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger { uint32 spell = (*itr)->GetSpellProto()->EffectTriggerSpell[(*itr)->GetEffIndex()]; CastSpell(this, spell, true, castItem, triggeredByAura); - if ((*itr)->GetParentAura()->DropAuraCharge()) - RemoveAurasDueToSpell((*itr)->GetId()); + (*itr)->GetParentAura()->DropAuraCharge(); return true; } } @@ -6370,8 +6381,7 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger return false; } CastSpell(this, spell, true, castItem, triggeredByAura); - if ((*itr)->GetParentAura()->DropAuraCharge()) - RemoveAurasDueToSpell((*itr)->GetId()); + (*itr)->GetParentAura()->DropAuraCharge(); return true; } } @@ -8166,6 +8176,44 @@ void Unit::SetCharm(Unit* charm, bool apply) } } +Unit* Unit::SelectMagnetTarget(Unit *victim, SpellEntry const *spellInfo) +{ + if(!victim) + return NULL; + + // Magic case + if(spellInfo && (spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE || spellInfo->DmgClass == SPELL_DAMAGE_CLASS_MAGIC)) + { + //I am not sure if this should be redirected. + if(spellInfo->DmgClass == SPELL_DAMAGE_CLASS_NONE) + return victim; + + Unit::AuraEffectList const& magnetAuras = victim->GetAurasByType(SPELL_AURA_SPELL_MAGNET); + for(Unit::AuraEffectList::const_iterator itr = magnetAuras.begin(); itr != magnetAuras.end(); ++itr) + if(Unit* magnet = (*itr)->GetCaster()) + if(magnet->isAlive()) + { + (*itr)->GetParentAura()->DropAuraCharge(); + return magnet; + } + } + // Melee && ranged case + else + { + AuraEffectList const& hitTriggerAuras = victim->GetAurasByType(SPELL_AURA_ADD_CASTER_HIT_TRIGGER); + for(AuraEffectList::const_iterator i = hitTriggerAuras.begin(); i != hitTriggerAuras.end(); ++i) + if(Unit* magnet = (*i)->GetCaster()) + if(magnet->isAlive() && magnet->IsWithinLOSInMap(this)) + if(roll_chance_i((*i)->GetAmount())) + { + (*i)->GetParentAura()->DropAuraCharge(); + return magnet; + } + } + + return victim; +} + Unit* Unit::GetFirstControlled() const { //Sequence: charmed, pet, other guardians @@ -8774,8 +8822,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM // Fingers of Frost // TODO: Change this code to less hacky if (Aura * aur = GetAura(44544)) - if (aur->DropAuraCharge()) - RemoveAura(aur); + aur->DropAuraCharge(); break; case 7917: // Glyph of Shadowburn if (pVictim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this)) @@ -11759,8 +11806,7 @@ void Unit::ProcDamageAndSpellFor( bool isVictim, Unit * pTarget, uint32 procFlag // Remove charge (aura can be removed by triggers) if(useCharges && takeCharges) { - if (i->aura->DropAuraCharge()) - RemoveAura(i->aura); + i->aura->DropAuraCharge(); } } } |
