aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/base/characters_database.sql31
-rw-r--r--sql/updates/characters/master/2021_03_27_00_characters_aura_stored_location.sql14
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp7
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h5
-rw-r--r--src/server/game/Entities/Player/Player.cpp100
-rw-r--r--src/server/game/Entities/Player/Player.h20
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp4
-rw-r--r--src/server/game/Spells/Auras/SpellAuraDefines.h2
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp17
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h1
-rw-r--r--src/server/game/Spells/Spell.h1
-rw-r--r--src/server/game/Spells/SpellEffects.cpp12
12 files changed, 210 insertions, 4 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql
index b2fe7bb0fb0..98bee12f448 100644
--- a/sql/base/characters_database.sql
+++ b/sql/base/characters_database.sql
@@ -561,6 +561,34 @@ LOCK TABLES `character_aura_effect` WRITE;
UNLOCK TABLES;
--
+-- Table structure for table `character_aura_stored_location`
+--
+
+DROP TABLE IF EXISTS `character_aura_stored_location`;
+/*!40101 SET @saved_cs_client = @@character_set_client */;
+/*!40101 SET character_set_client = utf8 */;
+CREATE TABLE `character_aura_stored_location` (
+ `Guid` bigint(20) unsigned NOT NULL COMMENT 'Global Unique Identifier of Player',
+ `Spell` int(10) unsigned NOT NULL COMMENT 'Spell Identifier',
+ `MapId` int(10) unsigned NOT NULL COMMENT 'Map Id',
+ `PositionX` float NOT NULL COMMENT 'position x',
+ `PositionY` float NOT NULL COMMENT 'position y',
+ `PositionZ` float NOT NULL COMMENT 'position z',
+ `Orientation` float NOT NULL COMMENT 'Orientation',
+ PRIMARY KEY (`Guid`,`Spell`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Dumping data for table `character_aura_stored_location`
+--
+
+LOCK TABLES `character_aura_stored_location` WRITE;
+/*!40000 ALTER TABLE `character_aura_stored_location` DISABLE KEYS */;
+/*!40000 ALTER TABLE `character_aura_stored_location` ENABLE KEYS */;
+UNLOCK TABLES;
+
+--
-- Table structure for table `character_banned`
--
@@ -3822,7 +3850,8 @@ INSERT INTO `updates` VALUES
('2020_08_14_00_characters.sql','355685FF86EE64E2ED9D4B7D1311D53A9C2E0FA5','ARCHIVED','2020-08-14 21:41:24',0),
('2020_10_20_00_characters.sql','744F2A36865761920CE98A6DDE3A3BADF44D1E77','ARCHIVED','2020-10-20 21:36:49',0),
('2020_11_16_00_characters.sql','33D5C7539E239132923D01F4B6EAD5F3EF3EEB69','RELEASED','2020-11-16 19:16:31',0),
-('2020_12_13_00_characters.sql','6AC743240033DED2C402ECB894A59D79EF607920','RELEASED','2020-12-13 18:36:58',0);
+('2020_12_13_00_characters.sql','6AC743240033DED2C402ECB894A59D79EF607920','RELEASED','2020-12-13 18:36:58',0),
+('2021_03_27_00_characters_aura_stored_location.sql','BF772ABC2DF186AF0A5DC56D5E824A2F4813BA69','RELEASED','2021-03-27 15:53:04',0);
/*!40000 ALTER TABLE `updates` ENABLE KEYS */;
UNLOCK TABLES;
diff --git a/sql/updates/characters/master/2021_03_27_00_characters_aura_stored_location.sql b/sql/updates/characters/master/2021_03_27_00_characters_aura_stored_location.sql
new file mode 100644
index 00000000000..2a0f6e93614
--- /dev/null
+++ b/sql/updates/characters/master/2021_03_27_00_characters_aura_stored_location.sql
@@ -0,0 +1,14 @@
+--
+-- Table structure for table `character_spell_location`
+--
+DROP TABLE IF EXISTS `character_aura_stored_location`;
+CREATE TABLE `character_aura_stored_location` (
+ `Guid` bigint(20) unsigned NOT NULL COMMENT 'Global Unique Identifier of Player',
+ `Spell` int(10) unsigned NOT NULL COMMENT 'Spell Identifier',
+ `MapId` int(10) unsigned NOT NULL COMMENT 'Map Id',
+ `PositionX` float NOT NULL COMMENT 'position x',
+ `PositionY` float NOT NULL COMMENT 'position y',
+ `PositionZ` float NOT NULL COMMENT 'position z',
+ `Orientation` float NOT NULL COMMENT 'Orientation',
+ PRIMARY KEY (`Guid`,`Spell`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 7f8273170b3..3f811766ea9 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -800,6 +800,13 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_SCENARIO_INSTANCE_CRITERIA, "DELETE FROM instance_scenario_progress WHERE id = ? AND criteria = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_SCENARIO_INSTANCE_CRITERIA, "INSERT INTO instance_scenario_progress (id, criteria, counter, date) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_SCENARIO_INSTANCE_CRITERIA_FOR_INSTANCE, "DELETE FROM instance_scenario_progress WHERE id = ?", CONNECTION_ASYNC);
+
+ // Spell Location
+ PrepareStatement(CHAR_SEL_CHARACTER_AURA_STORED_LOCATIONS, "SELECT Spell, MapId, PositionX, PositionY, PositionZ, Orientation FROM character_aura_stored_location WHERE Guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHARACTER_AURA_STORED_LOCATIONS_BY_GUID, "DELETE FROM character_aura_stored_location WHERE Guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_CHARACTER_AURA_STORED_LOCATION, "DELETE FROM character_aura_stored_location WHERE Guid = ? AND Spell = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_CHARACTER_AURA_STORED_LOCATION, "INSERT INTO character_aura_stored_location (Guid, Spell, MapId, PositionX, PositionY, PositionZ, Orientation) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
}
CharacterDatabaseConnection::CharacterDatabaseConnection(MySQLConnectionInfo& connInfo) : MySQLConnection(connInfo)
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index c756578c206..d05554f1219 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -671,6 +671,11 @@ enum CharacterDatabaseStatements : uint32
CHAR_INS_SCENARIO_INSTANCE_CRITERIA,
CHAR_DEL_SCENARIO_INSTANCE_CRITERIA_FOR_INSTANCE,
+ CHAR_SEL_CHARACTER_AURA_STORED_LOCATIONS,
+ CHAR_DEL_CHARACTER_AURA_STORED_LOCATIONS_BY_GUID,
+ CHAR_DEL_CHARACTER_AURA_STORED_LOCATION,
+ CHAR_INS_CHARACTER_AURA_STORED_LOCATION,
+
MAX_CHARACTERDATABASE_STATEMENTS
};
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 565c03d0fac..21a3d787310 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -2735,6 +2735,27 @@ void Player::RemoveTalent(TalentEntry const* talent)
plrTalent->second = PLAYERSPELL_REMOVED;
}
+void Player::AddStoredAuraTeleportLocation(uint32 spellId)
+{
+ StoredAuraTeleportLocation& storedLocation = m_storedAuraTeleportLocations[spellId];
+ storedLocation.Loc.WorldRelocate(this);
+ storedLocation.State = StoredAuraTeleportLocation::CHANGED;
+}
+
+void Player::RemoveStoredAuraTeleportLocation(uint32 spellId)
+{
+ if (StoredAuraTeleportLocation* storedLocation = Trinity::Containers::MapGetValuePtr(m_storedAuraTeleportLocations, spellId))
+ storedLocation->State = StoredAuraTeleportLocation::DELETED;
+}
+
+WorldLocation const* Player::GetStoredAuraTeleportLocation(uint32 spellId) const
+{
+ if (StoredAuraTeleportLocation const* auraLocation = Trinity::Containers::MapGetValuePtr(m_storedAuraTeleportLocations, spellId))
+ return &auraLocation->Loc;
+
+ return nullptr;
+}
+
bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent, bool disabled, bool loading /*= false*/, int32 fromSkill /*= 0*/)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE);
@@ -4128,6 +4149,10 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe
stmt->setUInt64(0, guid);
trans->Append(stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_AURA_STORED_LOCATIONS_BY_GUID);
+ stmt->setUInt64(0, guid);
+ trans->Append(stmt);
+
Corpse::DeleteFromDB(playerguid, trans);
Garrison::DeleteFromDB(guid, trans);
@@ -18654,6 +18679,9 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder* holder)
if (HasPlayerFlag(PLAYER_FLAGS_GHOST))
m_deathState = DEAD;
+ // Load spell locations - must be after loading auras
+ _LoadStoredAuraTeleportLocations(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_AURA_STORED_LOCATIONS));
+
// after spell load, learn rewarded spell if need also
_LoadQuestStatus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS));
_LoadQuestStatusObjectives(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES));
@@ -19964,6 +19992,42 @@ void Player::_LoadSpells(PreparedQueryResult result)
}
}
+void Player::_LoadStoredAuraTeleportLocations(PreparedQueryResult result)
+{
+ // 0 1 2 3 4 5
+ //QueryResult* result = CharacterDatabase.PQuery("SELECT Spell, MapId, PositionX, PositionY, PositionZ, Orientation FROM character_spell_location WHERE Guid = ?", GetGUIDLow());
+
+ m_storedAuraTeleportLocations.clear();
+ if (result)
+ {
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 spellId = fields[0].GetUInt32();
+
+ if (!sSpellMgr->GetSpellInfo(spellId, DIFFICULTY_NONE))
+ {
+ TC_LOG_ERROR("spells", "Player::_LoadStoredAuraTeleportLocations: Player %s (%s) spell (ID: %u) does not exist",
+ GetName().c_str(), GetGUID().ToString().c_str(), spellId);
+ continue;
+ }
+
+ WorldLocation location(fields[1].GetUInt32(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat(), fields[5].GetFloat());
+ if (!MapManager::IsValidMapCoord(location))
+ {
+ TC_LOG_ERROR("spells", "Player::_LoadStoredAuraTeleportLocations: Player %s (%s) spell (ID: %u) has invalid position on map %u, {%s}.",
+ GetName().c_str(), GetGUID().ToString().c_str(), spellId, location.GetMapId(), location.ToString().c_str());
+ continue;
+ }
+
+ StoredAuraTeleportLocation& storedLocation = m_storedAuraTeleportLocations[spellId];
+ storedLocation.Loc = location;
+ storedLocation.State = StoredAuraTeleportLocation::UNCHANGED;
+ }
+ while (result->NextRow());
+ }
+}
+
void Player::_LoadGroup(PreparedQueryResult result)
{
//QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM group_member WHERE memberGuid=%u", GetGUIDLow());
@@ -20864,6 +20928,7 @@ void Player::SaveToDB(LoginDatabaseTransaction loginTransaction, CharacterDataba
_SaveActions(trans);
_SaveAuras(trans);
_SaveSkills(trans);
+ _SaveStoredAuraTeleportLocations(trans);
m_achievementMgr->SaveToDB(trans);
m_reputationMgr->SaveToDB(trans);
m_questObjectiveCriteriaMgr->SaveToDB(trans);
@@ -21624,6 +21689,41 @@ void Player::_SaveSpells(CharacterDatabaseTransaction& trans)
}
}
+void Player::_SaveStoredAuraTeleportLocations(CharacterDatabaseTransaction& trans)
+{
+ for (auto itr = m_storedAuraTeleportLocations.begin(); itr != m_storedAuraTeleportLocations.end(); )
+ {
+ StoredAuraTeleportLocation& storedLocation = itr->second;
+ if (storedLocation.State == StoredAuraTeleportLocation::DELETED)
+ {
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_AURA_STORED_LOCATION);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ trans->Append(stmt);
+ itr = m_storedAuraTeleportLocations.erase(itr);
+ continue;
+ }
+
+ if (storedLocation.State == StoredAuraTeleportLocation::CHANGED)
+ {
+ CharacterDatabasePreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_AURA_STORED_LOCATION);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ trans->Append(stmt);
+
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_AURA_STORED_LOCATION);
+ stmt->setUInt64(0, GetGUID().GetCounter());
+ stmt->setUInt32(1, itr->first);
+ stmt->setUInt32(2, storedLocation.Loc.GetMapId());
+ stmt->setFloat(3, storedLocation.Loc.GetPositionX());
+ stmt->setFloat(4, storedLocation.Loc.GetPositionY());
+ stmt->setFloat(5, storedLocation.Loc.GetPositionZ());
+ stmt->setFloat(6, storedLocation.Loc.GetOrientation());
+ trans->Append(stmt);
+ }
+
+ ++itr;
+ }
+}
+
// save player stats -- only for external usage
// real stats will be recalculated on player login
void Player::_SaveStats(CharacterDatabaseTransaction& trans) const
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index 8a29cc05a0c..8124399b1f3 100644
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -178,6 +178,18 @@ struct PlayerSpell
bool disabled : 1; // first rank has been learned in result talent learn but currently talent unlearned, save max learned ranks
};
+struct StoredAuraTeleportLocation
+{
+ WorldLocation Loc;
+
+ enum
+ {
+ UNCHANGED,
+ CHANGED,
+ DELETED,
+ } State;
+};
+
enum TalentSpecialization // talent tabs
{
TALENT_SPEC_MAGE_ARCANE = 62,
@@ -769,6 +781,7 @@ enum PlayerLoginQueryIndex
PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES,
PLAYER_LOGIN_QUERY_LOAD_AURAS,
PLAYER_LOGIN_QUERY_LOAD_AURA_EFFECTS,
+ PLAYER_LOGIN_QUERY_LOAD_AURA_STORED_LOCATIONS,
PLAYER_LOGIN_QUERY_LOAD_SPELLS,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS,
PLAYER_LOGIN_QUERY_LOAD_QUEST_STATUS_OBJECTIVES,
@@ -1614,6 +1627,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void RemoveSpecializationSpells();
void SendSpellCategoryCooldowns() const;
+ void AddStoredAuraTeleportLocation(uint32 spellId);
+ void RemoveStoredAuraTeleportLocation(uint32 spellId);
+ WorldLocation const* GetStoredAuraTeleportLocation(uint32 spellId) const;
+
void SetReputation(uint32 factionentry, int32 value);
int32 GetReputation(uint32 factionentry) const;
std::string GetGuildName() const;
@@ -2622,6 +2639,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _LoadGroup(PreparedQueryResult result);
void _LoadSkills(PreparedQueryResult result);
void _LoadSpells(PreparedQueryResult result);
+ void _LoadStoredAuraTeleportLocations(PreparedQueryResult result);
bool _LoadHomeBind(PreparedQueryResult result);
void _LoadDeclinedNames(PreparedQueryResult result);
void _LoadArenaTeamInfo(PreparedQueryResult result);
@@ -2652,6 +2670,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
void _SaveSeasonalQuestStatus(CharacterDatabaseTransaction& trans);
void _SaveSkills(CharacterDatabaseTransaction& trans);
void _SaveSpells(CharacterDatabaseTransaction& trans);
+ void _SaveStoredAuraTeleportLocations(CharacterDatabaseTransaction& trans);
void _SaveEquipmentSets(CharacterDatabaseTransaction& trans);
void _SaveBGData(CharacterDatabaseTransaction& trans);
void _SaveGlyphs(CharacterDatabaseTransaction& trans) const;
@@ -2732,6 +2751,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
PlayerSpellMap m_spells;
std::unordered_map<uint32 /*overridenSpellId*/, std::unordered_set<uint32> /*newSpellId*/> m_overrideSpells;
uint32 m_lastPotionId; // last used health/mana potion in combat, that block next potion use
+ std::unordered_map<uint32, StoredAuraTeleportLocation> m_storedAuraTeleportLocations;
SpecializationInfo _specializationInfo;
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index c49fcbac361..a38f7477d70 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -109,6 +109,10 @@ bool LoginQueryHolder::Initialize()
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_AURA_EFFECTS, stmt);
+ stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_AURA_STORED_LOCATIONS);
+ stmt->setUInt64(0, lowGuid);
+ res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_AURA_STORED_LOCATIONS, stmt);
+
stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_SPELL);
stmt->setUInt64(0, lowGuid);
res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_SPELLS, stmt);
diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h
index e1496fbc123..ec87dc3eb3e 100644
--- a/src/server/game/Spells/Auras/SpellAuraDefines.h
+++ b/src/server/game/Spells/Auras/SpellAuraDefines.h
@@ -149,7 +149,7 @@ enum AuraType : uint32
SPELL_AURA_MOD_STALKED = 68,
SPELL_AURA_SCHOOL_ABSORB = 69,
SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE = 70,
- SPELL_AURA_STORE_TELEPORT_RETURN_POINT = 71, // NYI
+ SPELL_AURA_STORE_TELEPORT_RETURN_POINT = 71,
SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT = 72,
SPELL_AURA_MOD_POWER_COST_SCHOOL = 73,
SPELL_AURA_REFLECT_SPELLS_SCHOOL = 74,
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
index cbd6bf70309..515badef5aa 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp
@@ -138,7 +138,7 @@ NonDefaultConstructible<pAuraEffectHandler> AuraEffectHandler[TOTAL_AURAS]=
&AuraEffect::HandleAuraModStalked, // 68 SPELL_AURA_MOD_STALKED
&AuraEffect::HandleNoImmediateEffect, // 69 SPELL_AURA_SCHOOL_ABSORB implemented in Unit::CalcAbsorbResist
&AuraEffect::HandleNoImmediateEffect, // 70 SPELL_AURA_PERIODIC_WEAPON_PERCENT_DAMAGE implemented in AuraEffect::PeriodicTick
- &AuraEffect::HandleNULL, // 71 SPELL_AURA_STORE_TELEPORT_RETURN_POINT
+ &AuraEffect::HandleStoreTeleportReturnPoint, // 71 SPELL_AURA_STORE_TELEPORT_RETURN_POINT
&AuraEffect::HandleNoImmediateEffect, // 72 SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT
&AuraEffect::HandleModPowerCost, // 73 SPELL_AURA_MOD_POWER_COST_SCHOOL
&AuraEffect::HandleNoImmediateEffect, // 74 SPELL_AURA_REFLECT_SPELLS_SCHOOL implemented in Unit::SpellHitResult
@@ -5958,6 +5958,21 @@ void AuraEffect::HandleBattlegroundPlayerPosition(AuraApplication const* aurApp,
bg->RemovePlayerPosition(target->GetGUID());
}
+void AuraEffect::HandleStoreTeleportReturnPoint(AuraApplication const* aurApp, uint8 mode, bool apply) const
+{
+ if (!(mode & AURA_EFFECT_HANDLE_REAL))
+ return;
+
+ Player* playerTarget = aurApp->GetTarget()->ToPlayer();
+ if (!playerTarget)
+ return;
+
+ if (apply)
+ playerTarget->AddStoredAuraTeleportLocation(GetSpellInfo()->Id);
+ else if (!playerTarget->GetSession()->isLogingOut())
+ playerTarget->RemoveStoredAuraTeleportLocation(GetSpellInfo()->Id);
+}
+
template TC_GAME_API void AuraEffect::GetTargetList(std::list<Unit*>&) const;
template TC_GAME_API void AuraEffect::GetTargetList(std::deque<Unit*>&) const;
template TC_GAME_API void AuraEffect::GetTargetList(std::vector<Unit*>&) const;
diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h
index 71fbfe49364..12e9547b4d6 100644
--- a/src/server/game/Spells/Auras/SpellAuraEffects.h
+++ b/src/server/game/Spells/Auras/SpellAuraEffects.h
@@ -324,6 +324,7 @@ class TC_GAME_API AuraEffect
void HandleBattlegroundPlayerPosition(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleTriggerSpellOnPowerAmount(AuraApplication const* aurApp, uint8 mode, bool apply) const;
void HandleTriggerSpellOnPowerPercent(AuraApplication const* aurApp, uint8 mode, bool apply) const;
+ void HandleStoreTeleportReturnPoint(AuraApplication const* aurApp, uint8 mode, bool apply) const;
// aura effect periodic tick handlers
void HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) const;
diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h
index dbe43173b38..2fa9b377b08 100644
--- a/src/server/game/Spells/Spell.h
+++ b/src/server/game/Spells/Spell.h
@@ -349,6 +349,7 @@ class TC_GAME_API Spell
void EffectPowerDrain(SpellEffIndex effIndex);
void EffectHeal(SpellEffIndex effIndex);
void EffectBind(SpellEffIndex effIndex);
+ void EffectTeleportToReturnPoint(SpellEffIndex effIndex);
void EffectHealthLeech(SpellEffIndex effIndex);
void EffectQuestComplete(SpellEffIndex effIndex);
void EffectCreateItem(SpellEffIndex effIndex);
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 336de46e33a..11570ee6e86 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -91,7 +91,7 @@ NonDefaultConstructible<pEffect> SpellEffects[TOTAL_SPELL_EFFECTS] =
&Spell::EffectHeal, // 10 SPELL_EFFECT_HEAL
&Spell::EffectBind, // 11 SPELL_EFFECT_BIND
&Spell::EffectNULL, // 12 SPELL_EFFECT_PORTAL
- &Spell::EffectNULL, // 13 SPELL_EFFECT_TELEPORT_TO_RETURN_POINT
+ &Spell::EffectTeleportToReturnPoint, // 13 SPELL_EFFECT_TELEPORT_TO_RETURN_POINT
&Spell::EffectNULL, // 14 SPELL_EFFECT_INCREASE_CURRENCY_CAP
&Spell::EffectNULL, // 15 SPELL_EFFECT_TELEPORT_WITH_SPELL_VISUAL_KIT_LOADING_SCREEN
&Spell::EffectQuestComplete, // 16 SPELL_EFFECT_QUEST_COMPLETE
@@ -5334,6 +5334,16 @@ void Spell::EffectBind(SpellEffIndex /*effIndex*/)
player->SendDirectMessage(packet.Write());
}
+void Spell::EffectTeleportToReturnPoint(SpellEffIndex /*effIndex*/)
+{
+ if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)
+ return;
+
+ if (Player* player = unitTarget->ToPlayer())
+ if (WorldLocation const* dest = player->GetStoredAuraTeleportLocation(effectInfo->MiscValue))
+ player->TeleportTo(*dest, unitTarget == m_caster ? TELE_TO_SPELL | TELE_TO_NOT_LEAVE_COMBAT : 0);
+}
+
void Spell::EffectSummonRaFFriend(SpellEffIndex /*effIndex*/)
{
if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET)