diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index e4e4a65746..7e24559180 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -1254,7 +1254,8 @@ void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint m_effects[i]->SetCanBeRecalculated(recalculateMask & (1 << i)); m_effects[i]->CalculatePeriodic(caster, false, true); m_effects[i]->CalculateSpellMod(); - m_effects[i]->RecalculateAmount(caster); + if (caster) + m_effects[i]->RecalculateAmount(caster); } } diff --git a/src/test/server/game/Spells/AuraLoadedStateTest.cpp b/src/test/server/game/Spells/AuraLoadedStateTest.cpp new file mode 100644 index 0000000000..6974d7e20b --- /dev/null +++ b/src/test/server/game/Spells/AuraLoadedStateTest.cpp @@ -0,0 +1,85 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "IntegrationTestFixture.h" +#include "SpellAuraEffects.h" +#include "SpellAuras.h" +#include "SpellInfoTestHelper.h" +#include "gtest/gtest.h" + +#ifndef TEST_F +#define TEST_F(fixture, name) void fixture##_##name() +#endif + +namespace +{ +constexpr uint32 TEST_AURA_SPELL_ID = 900001; +constexpr int32 BASE_AMOUNT = 2; +constexpr int32 SAVED_AMOUNT = 83; +constexpr int32 AURA_DURATION = 60 * MINUTE * IN_MILLISECONDS; + +class AuraLoadedStateTest : public IntegrationTestFixture +{ +protected: + void SetUp() override + { + IntegrationTestFixture::SetUp(); + + _spellInfo = SpellInfoBuilder() + .WithId(TEST_AURA_SPELL_ID) + .WithEffect(0, SPELL_EFFECT_APPLY_AURA, SPELL_AURA_MOD_RESISTANCE) + .WithEffectBasePoints(0, BASE_AMOUNT) + .WithEffectMiscValue(0, SPELL_SCHOOL_MASK_FIRE) + .BuildUnique(); + } + + std::unique_ptr _spellInfo; +}; + +TEST_F(AuraLoadedStateTest, UnresolvedCasterPreservesSavedAmount) +{ + TestPlayer* target = CreateTestPlayer(); + ObjectGuid casterGuid = ObjectGuid::Create(9098, 1); + Aura* aura = Aura::TryCreate(_spellInfo.get(), 1, target, nullptr, nullptr, nullptr, casterGuid); + ASSERT_NE(aura, nullptr); + + int32 amounts[MAX_SPELL_EFFECTS] = { SAVED_AMOUNT, 0, 0 }; + aura->SetLoadedState(AURA_DURATION, AURA_DURATION, 0, 1, 1, amounts); + + AuraEffect const* effect = aura->GetEffect(0); + ASSERT_NE(effect, nullptr); + EXPECT_EQ(effect->GetAmount(), SAVED_AMOUNT); + + aura->Remove(); +} + +TEST_F(AuraLoadedStateTest, ResolvedCasterStillRecalculatesAmount) +{ + TestPlayer* target = CreateTestPlayer(); + Aura* aura = Aura::TryCreate(_spellInfo.get(), 1, target, target); + ASSERT_NE(aura, nullptr); + + int32 amounts[MAX_SPELL_EFFECTS] = { SAVED_AMOUNT, 0, 0 }; + aura->SetLoadedState(AURA_DURATION, AURA_DURATION, 0, 1, 1, amounts); + + AuraEffect const* effect = aura->GetEffect(0); + ASSERT_NE(effect, nullptr); + EXPECT_EQ(effect->GetAmount(), BASE_AMOUNT); + + aura->Remove(); +} +}