From 07376de9fc1752567849b775cb2dedfa4a3af5ad Mon Sep 17 00:00:00 2001 From: Shauren Date: Thu, 29 Jun 2023 20:31:45 +0200 Subject: [PATCH] Core/Spells: Always remove spell target from transport on teleport spells if spell destination does not target a position on the transport --- .../Battlegrounds/Zones/BattlegroundSA.cpp | 8 ++--- src/server/game/Entities/Player/Player.cpp | 8 ++--- src/server/game/Entities/Player/Player.h | 11 +++--- src/server/game/Entities/Unit/Unit.cpp | 2 +- src/server/game/Spells/SpellEffects.cpp | 36 ++++++++++++++----- src/server/game/Tickets/TicketMgr.cpp | 2 +- src/server/scripts/Commands/cs_group.cpp | 2 +- src/server/scripts/Commands/cs_misc.cpp | 2 +- 8 files changed, 47 insertions(+), 24 deletions(-) diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index ef6bcbaf5a..c96f5fdf22 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -488,15 +488,15 @@ void BattlegroundSA::TeleportToEntrancePosition(Player* player) //player->AddUnitMovementFlag(MOVEMENTFLAG_ONTRANSPORT); if (urand(0, 1)) - player->TeleportTo(607, 2682.936f, -830.368f, 15.0f, 2.895f, 0); + player->TeleportTo(607, 2682.936f, -830.368f, 15.0f, 2.895f); else - player->TeleportTo(607, 2577.003f, 980.261f, 15.0f, 0.807f, 0); + player->TeleportTo(607, 2577.003f, 980.261f, 15.0f, 0.807f); } else - player->TeleportTo(607, 1600.381f, -106.263f, 8.8745f, 3.78f, 0); + player->TeleportTo(607, 1600.381f, -106.263f, 8.8745f, 3.78f); } else - player->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0); + player->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f); } void BattlegroundSA::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker /*= nullptr*/) diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index cf75836436..5ac0c15ed4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -209,7 +209,7 @@ Player::Player(WorldSession* session): Unit(true) m_DelayedOperations = 0; m_bCanDelayTeleport = false; m_bHasDelayedTeleport = false; - m_teleport_options = 0; + m_teleport_options = TELE_TO_NONE; m_trade = nullptr; @@ -1420,7 +1420,7 @@ uint8 Player::GetChatTag() const return tag; } -bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options /*= 0*/, Optional instanceId /*= {}*/) +bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options /*= TELE_TO_NONE*/, Optional instanceId /*= {}*/) { if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation)) { @@ -1670,7 +1670,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return true; } -bool Player::TeleportTo(WorldLocation const& loc, uint32 options /*= 0*/, Optional instanceId /*= {}*/) +bool Player::TeleportTo(WorldLocation const& loc, TeleportToOptions options /*= TELE_TO_NONE*/, Optional instanceId /*= {}*/) { return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options, instanceId); } @@ -23748,7 +23748,7 @@ void Player::SummonIfPossible(bool agree) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ACCEPTED_SUMMONINGS, 1); RemoveAurasWithInterruptFlags(SpellAuraInterruptFlags::Summon); - TeleportTo(m_summon_location, 0, m_summon_instanceId); + TeleportTo(m_summon_location, TELE_TO_NONE, m_summon_instanceId); } void Player::RemoveItemDurations(Item* item) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index ca3f1e3d23..377d54c53a 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -716,6 +716,7 @@ enum RestFlag enum TeleportToOptions { + TELE_TO_NONE = 0x00, TELE_TO_GM_MODE = 0x01, TELE_TO_NOT_LEAVE_TRANSPORT = 0x02, TELE_TO_NOT_LEAVE_COMBAT = 0x04, @@ -723,6 +724,8 @@ enum TeleportToOptions TELE_TO_SPELL = 0x10 }; +DEFINE_ENUM_FLAG(TeleportToOptions); + /// Type of environmental damages enum EnviromentalDamage { @@ -1029,8 +1032,8 @@ class TC_GAME_API Player : public Unit, public GridObject void SetObjectScale(float scale) override; - bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0, Optional instanceId = {}); - bool TeleportTo(WorldLocation const& loc, uint32 options = 0, Optional instanceId = {}); + bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, TeleportToOptions options = TELE_TO_NONE, Optional instanceId = {}); + bool TeleportTo(WorldLocation const& loc, TeleportToOptions options = TELE_TO_NONE, Optional instanceId = {}); bool TeleportToBGEntryPoint(); bool HasSummonPending() const; @@ -2166,7 +2169,7 @@ class TC_GAME_API Player : public Unit, public GridObject m_recall_location.WorldRelocate(*this); m_recall_instanceId = GetInstanceId(); } - void Recall() { TeleportTo(m_recall_location, 0, m_recall_instanceId); } + void Recall() { TeleportTo(m_recall_location, TELE_TO_NONE, m_recall_instanceId); } void SetHomebind(WorldLocation const& loc, uint32 areaId); void SendBindPointUpdate() const; @@ -2722,7 +2725,7 @@ class TC_GAME_API Player : public Unit, public GridObject // Current teleport data WorldLocation m_teleport_dest; Optional m_teleport_instanceId; - uint32 m_teleport_options; + TeleportToOptions m_teleport_options; bool mSemaphoreTeleport_Near; bool mSemaphoreTeleport_Far; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b9f9a98c7e..0676c8a980 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -12969,7 +12969,7 @@ void Unit::NearTeleportTo(Position const& pos, bool casting /*= false*/) if (GetTypeId() == TYPEID_PLAYER) { WorldLocation target(GetMapId(), pos); - ToPlayer()->TeleportTo(target, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : 0)); + ToPlayer()->TeleportTo(target, TELE_TO_NOT_LEAVE_TRANSPORT | TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET | (casting ? TELE_TO_SPELL : TELE_TO_NONE)); } else { diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 024f3de5db..5668722160 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -818,7 +818,24 @@ void Spell::CalculateJumpSpeeds(uint8 i, float dist, float & speedXY, float & sp speedZ = std::sqrt(2 * Movement::gravity * height); } -void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) +TeleportToOptions GetTeleportOptions(WorldObject const* caster, Unit const* unitTarget, SpellDestination const& targetDest) +{ + TeleportToOptions options = TELE_TO_NONE; + if (caster == unitTarget) + options |= TELE_TO_SPELL; + + if (targetDest._position.GetMapId() == unitTarget->GetMapId()) + { + options |= TELE_TO_NOT_LEAVE_COMBAT | TELE_TO_NOT_UNSUMMON_PET; + + if (unitTarget->GetTransGUID() == targetDest._transportGUID) + options |= TELE_TO_NOT_LEAVE_TRANSPORT; + } + + return options; +} + +void Spell::EffectTeleportUnits(SpellEffIndex effIndex) { if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT_TARGET) return; @@ -841,15 +858,18 @@ void Spell::EffectTeleportUnits(SpellEffIndex /*effIndex*/) if (!targetDest.GetOrientation() && m_targets.GetUnitTarget()) targetDest.SetOrientation(m_targets.GetUnitTarget()->GetOrientation()); - if (targetDest.GetMapId() == unitTarget->GetMapId()) - unitTarget->NearTeleportTo(targetDest, unitTarget == m_caster); - else if (unitTarget->GetTypeId() == TYPEID_PLAYER) - unitTarget->ToPlayer()->TeleportTo(targetDest, unitTarget == m_caster ? TELE_TO_SPELL : 0); - else + Player* player = unitTarget->ToPlayer(); + + if (player) { - TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - spellId %u attempted to teleport creature to a different map.", m_spellInfo->Id); - return; + TeleportToOptions options = GetTeleportOptions(m_caster, unitTarget, m_destTargets[effIndex]); + + player->TeleportTo(targetDest, options); } + else if (targetDest.GetMapId() == unitTarget->GetMapId()) + unitTarget->NearTeleportTo(targetDest, unitTarget == m_caster); + else + TC_LOG_ERROR("spells", "Spell::EffectTeleportUnits - spellId %u attempted to teleport creature to a different map.", m_spellInfo->Id); // post effects for TARGET_DEST_DB /// @todo: awful hacks, move this to spellscripts diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index 5188f1ce24..364630955f 100644 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -255,7 +255,7 @@ void GmTicket::SetGmAction(uint32 needResponse, bool needMoreHelp) void GmTicket::TeleportTo(Player* player) const { - player->TeleportTo(_mapId, _posX, _posY, _posZ, 0.0f, 0); + player->TeleportTo(_mapId, _posX, _posY, _posZ, 0.0f); } void GmTicket::SetChatLog(std::list time, std::string const& log) diff --git a/src/server/scripts/Commands/cs_group.cpp b/src/server/scripts/Commands/cs_group.cpp index f5ed94dd74..c3e48c01bc 100644 --- a/src/server/scripts/Commands/cs_group.cpp +++ b/src/server/scripts/Commands/cs_group.cpp @@ -155,7 +155,7 @@ public: // before GM float x, y, z; gmPlayer->GetClosePoint(x, y, z, player->GetCombatReach()); - player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation(), 0, gmPlayer->GetInstanceId()); + player->TeleportTo(gmPlayer->GetMapId(), x, y, z, player->GetOrientation(), TELE_TO_NONE, gmPlayer->GetInstanceId()); } return true; diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index 4fdd34a871..407176a71a 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -592,7 +592,7 @@ public: // before GM float x, y, z; _player->GetPosition(x, y, z); - target->TeleportTo(_player->GetMapId(), x, y, z, target->GetOrientation(), 0, map->GetInstanceId()); + target->TeleportTo(_player->GetMapId(), x, y, z, target->GetOrientation(), TELE_TO_NONE, map->GetInstanceId()); PhasingHandler::InheritPhaseShift(target, handler->GetSession()->GetPlayer()); target->UpdateObjectVisibility(); }