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();
+}
+}