Core/Auras:

* Fixed loading aura charges when they would exceed count set in SpellEntry while still remaining a valid value due to spell modifiers (that might not yet be active)
* Fixed refreshing aura charges when recasting the spell

Closes #1803
Closes #1786
Closes #1805
This commit is contained in:
Shauren
2011-06-03 21:30:50 +02:00
parent 87ce4988f4
commit 97a5db68c2
6 changed files with 33 additions and 25 deletions
+5 -2
View File
@@ -17130,19 +17130,22 @@ void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff)
// prevent wrong values of remaincharges // prevent wrong values of remaincharges
if (spellproto->procCharges) if (spellproto->procCharges)
{ {
if (remaincharges <= 0 || remaincharges > spellproto->procCharges) // we have no control over the order of applying auras and modifiers allow auras
// to have more charges than value in SpellEntry
if (remaincharges <= 0/* || remaincharges > spellproto->procCharges*/)
remaincharges = spellproto->procCharges; remaincharges = spellproto->procCharges;
} }
else else
remaincharges = 0; remaincharges = 0;
if (Aura * aura = Aura::TryCreate(spellproto, effmask, this, NULL, &baseDamage[0], NULL, caster_guid)) if (Aura* aura = Aura::TryCreate(spellproto, effmask, this, NULL, &baseDamage[0], NULL, caster_guid))
{ {
if (!aura->CanBeSaved()) if (!aura->CanBeSaved())
{ {
aura->Remove(); aura->Remove();
continue; continue;
} }
aura->SetLoadedState(maxduration, remaintime, remaincharges, stackcount, recalculatemask, &damage[0]); aura->SetLoadedState(maxduration, remaintime, remaincharges, stackcount, recalculatemask, &damage[0]);
aura->ApplyForTargets(); aura->ApplyForTargets();
sLog->outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask); sLog->outDetail("Added aura spellid %u, effectmask %u", spellproto->Id, effmask);
+12 -3
View File
@@ -3111,7 +3111,7 @@ void Unit::DeMorph()
SetDisplayId(GetNativeDisplayId()); SetDisplayId(GetNativeDisplayId());
} }
Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const* newAura, uint8 effMask, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, uint64 casterGUID /*= 0*/) Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const* newAura, uint8 effMask, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, uint64 casterGUID /*= 0*/)
{ {
ASSERT(casterGUID); ASSERT(casterGUID);
// passive and Incanter's Absorption and auras with different type can stack with themselves any number of times // passive and Incanter's Absorption and auras with different type can stack with themselves any number of times
@@ -3134,15 +3134,16 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const* newAura, uint
// update basepoints with new values - effect amount will be recalculated in ModStackAmount // update basepoints with new values - effect amount will be recalculated in ModStackAmount
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{ {
if (!foundAura->m_effects[i]) if (!foundAura->HasEffect(i))
continue; continue;
int bp; int bp;
if (baseAmount) if (baseAmount)
bp = *(baseAmount + i); bp = *(baseAmount + i);
else else
bp = foundAura->GetSpellProto()->EffectBasePoints[i]; bp = foundAura->GetSpellProto()->EffectBasePoints[i];
int32* oldBP = const_cast<int32*>(&(foundAura->m_effects[i]->m_baseAmount)); int32* oldBP = const_cast<int32*>(&(foundAura->GetEffect(i)->m_baseAmount));
*oldBP = bp; *oldBP = bp;
} }
@@ -3153,6 +3154,14 @@ Aura* Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const* newAura, uint
*oldGUID = castItemGUID; *oldGUID = castItemGUID;
} }
uint8 charges = foundAura->GetSpellProto()->procCharges;
if (caster)
if (Player* modOwner = caster->GetSpellModOwner())
modOwner->ApplySpellMod(foundAura->GetId(), SPELLMOD_CHARGES, charges);
// refresh charges
foundAura->SetCharges(charges);
// try to increase stack amount // try to increase stack amount
foundAura->ModStackAmount(1); foundAura->ModStackAmount(1);
return foundAura; return foundAura;
+1 -1
View File
@@ -1616,7 +1616,7 @@ class Unit : public WorldObject
bool InitTamedPet(Pet * pet, uint8 level, uint32 spell_id); bool InitTamedPet(Pet * pet, uint8 level, uint32 spell_id);
// aura apply/remove helpers - you should better not use these // aura apply/remove helpers - you should better not use these
Aura* _TryStackingOrRefreshingExistingAura(SpellEntry const* newAura, uint8 effMask, int32* baseAmount = NULL, Item* castItem = NULL, uint64 casterGUID = 0); Aura* _TryStackingOrRefreshingExistingAura(SpellEntry const* newAura, uint8 effMask, Unit* caster, int32* baseAmount = NULL, Item* castItem = NULL, uint64 casterGUID = 0);
void _AddAura(UnitAura * aura, Unit * caster); void _AddAura(UnitAura * aura, Unit * caster);
AuraApplication * _CreateAuraApplication(Aura * aura, uint8 effMask); AuraApplication * _CreateAuraApplication(Aura * aura, uint8 effMask);
void _ApplyAuraEffect(Aura * aura, uint8 effIndex); void _ApplyAuraEffect(Aura * aura, uint8 effIndex);
@@ -14,7 +14,7 @@ typedef void(AuraEffect::*pAuraEffectHandler)(AuraApplication const * aurApp, ui
class AuraEffect class AuraEffect
{ {
friend void Aura::_InitEffects(uint8 effMask, Unit * caster, int32 *baseAmount); friend void Aura::_InitEffects(uint8 effMask, Unit * caster, int32 *baseAmount);
friend Aura * Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const * newAura, uint8 effMask, int32 *baseAmount, Item * castItem, uint64 casterGUID); friend Aura * Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const* newAura, uint8 effMask, Unit* caster, int32* baseAmount, Item* castItem, uint64 casterGUID);
friend Aura::~Aura(); friend Aura::~Aura();
private: private:
~AuraEffect(); ~AuraEffect();
+11 -15
View File
@@ -276,7 +276,7 @@ Aura * Aura::TryCreate(SpellEntry const* spellproto, WorldObject * owner, Unit *
return NULL; return NULL;
} }
Aura * Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount, Item * castItem, uint64 casterGUID) Aura* Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount /*= NULL*/, Item* castItem /*= NULL*/, uint64 casterGUID /*= 0*/)
{ {
ASSERT(effMask); ASSERT(effMask);
ASSERT(spellproto); ASSERT(spellproto);
@@ -287,33 +287,29 @@ Aura * Aura::Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * o
if (casterGUID) if (casterGUID)
{ {
if (owner->GetGUID() == casterGUID) if (owner->GetGUID() == casterGUID)
caster = (Unit *)owner; caster = owner->ToUnit();
else else
caster = ObjectAccessor::GetUnit(*owner, casterGUID); caster = ObjectAccessor::GetUnit(*owner, casterGUID);
} }
else else
{
casterGUID = caster->GetGUID(); casterGUID = caster->GetGUID();
}
// check if aura can be owned by owner // check if aura can be owned by owner
if (owner->isType(TYPEMASK_UNIT)) if (owner->isType(TYPEMASK_UNIT))
{
if (!owner->IsInWorld() || ((Unit*)owner)->IsDuringRemoveFromWorld()) if (!owner->IsInWorld() || ((Unit*)owner)->IsDuringRemoveFromWorld())
{ // owner not in world so don't allow to own not self casted single target auras
// owner not in world so
// don't allow to own not self casted single target auras
if (casterGUID != owner->GetGUID() && IsSingleTargetSpell(spellproto)) if (casterGUID != owner->GetGUID() && IsSingleTargetSpell(spellproto))
return NULL; return NULL;
}
} Aura* aura = NULL;
Aura * aura = NULL; switch (owner->GetTypeId())
switch(owner->GetTypeId())
{ {
case TYPEID_UNIT: case TYPEID_UNIT:
case TYPEID_PLAYER: case TYPEID_PLAYER:
if (aura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, baseAmount, castItem, casterGUID)) if (Aura* foundAura = owner->ToUnit()->_TryStackingOrRefreshingExistingAura(spellproto, effMask, caster, baseAmount, castItem, casterGUID))
return aura; aura = foundAura;
aura = new UnitAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID); else
aura = new UnitAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
break; break;
case TYPEID_DYNAMICOBJECT: case TYPEID_DYNAMICOBJECT:
aura = new DynObjAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID); aura = new DynObjAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID);
+2 -2
View File
@@ -79,13 +79,13 @@ class AuraApplication
class Aura class Aura
{ {
friend Aura * Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const * newAura, uint8 effMask, int32 *baseAmount, Item * castItem, uint64 casterGUID); friend Aura * Unit::_TryStackingOrRefreshingExistingAura(SpellEntry const * newAura, uint8 effMask, Unit* caster, int32 *baseAmount, Item * castItem, uint64 casterGUID);
public: public:
typedef std::map<uint64, AuraApplication *> ApplicationMap; typedef std::map<uint64, AuraApplication *> ApplicationMap;
static Aura * TryCreate(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0); static Aura * TryCreate(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0);
static Aura * TryCreate(SpellEntry const* spellproto, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0); static Aura * TryCreate(SpellEntry const* spellproto, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0);
static Aura * Create(SpellEntry const* spellproto, uint8 effMask, WorldObject * owner, Unit * caster, int32 *baseAmount = NULL, Item * castItem = NULL, uint64 casterGUID = 0); static Aura* Create(SpellEntry const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32* baseAmount = NULL, Item* castItem = NULL, uint64 casterGUID = 0);
explicit Aura(SpellEntry const* spellproto, WorldObject * owner, Unit * caster, Item * castItem, uint64 casterGUID); explicit Aura(SpellEntry const* spellproto, WorldObject * owner, Unit * caster, Item * castItem, uint64 casterGUID);
void _InitEffects(uint8 effMask, Unit * caster, int32 *baseAmount); void _InitEffects(uint8 effMask, Unit * caster, int32 *baseAmount);
virtual ~Aura(); virtual ~Aura();