Core/Players: Allow targeting a specific transport during teleports
Port From (https://github.com/TrinityCore/TrinityCore/commit/5b130cfb4253a94c08ff807e7f28e988651d2476)
This commit is contained in:
@@ -3863,15 +3863,15 @@ namespace Game.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
stmt.AddValue(index++, (ushort)GetTeleportDest().GetMapId());
|
||||
stmt.AddValue(index++, (ushort)GetTeleportDest().Location.GetMapId());
|
||||
stmt.AddValue(index++, 0);
|
||||
stmt.AddValue(index++, (byte)GetDungeonDifficultyID());
|
||||
stmt.AddValue(index++, (byte)GetRaidDifficultyID());
|
||||
stmt.AddValue(index++, (byte)GetLegacyRaidDifficultyID());
|
||||
stmt.AddValue(index++, finiteAlways(GetTeleportDest().GetPositionX()));
|
||||
stmt.AddValue(index++, finiteAlways(GetTeleportDest().GetPositionY()));
|
||||
stmt.AddValue(index++, finiteAlways(GetTeleportDest().GetPositionZ()));
|
||||
stmt.AddValue(index++, finiteAlways(GetTeleportDest().GetOrientation()));
|
||||
stmt.AddValue(index++, finiteAlways(GetTeleportDest().Location.GetPositionX()));
|
||||
stmt.AddValue(index++, finiteAlways(GetTeleportDest().Location.GetPositionY()));
|
||||
stmt.AddValue(index++, finiteAlways(GetTeleportDest().Location.GetPositionZ()));
|
||||
stmt.AddValue(index++, finiteAlways(GetTeleportDest().Location.GetOrientation()));
|
||||
}
|
||||
|
||||
stmt.AddValue(index++, finiteAlways(GetTransOffsetX()));
|
||||
|
||||
@@ -82,8 +82,7 @@ namespace Game.Entities
|
||||
public byte m_movementForceModMagnitudeChanges;
|
||||
uint m_lastFallTime;
|
||||
float m_lastFallZ;
|
||||
WorldLocation teleportDest;
|
||||
uint? m_teleport_instanceId;
|
||||
TeleportLocation teleportDest;
|
||||
TeleportToOptions m_teleport_options;
|
||||
bool mSemaphoreTeleport_Near;
|
||||
bool mSemaphoreTeleport_Far;
|
||||
|
||||
@@ -1951,33 +1951,42 @@ namespace Game.Entities
|
||||
|
||||
//Movement
|
||||
bool IsCanDelayTeleport() { return m_bCanDelayTeleport; }
|
||||
|
||||
void SetCanDelayTeleport(bool setting) { m_bCanDelayTeleport = setting; }
|
||||
|
||||
bool IsHasDelayedTeleport() { return m_bHasDelayedTeleport; }
|
||||
|
||||
void SetDelayedTeleportFlag(bool setting) { m_bHasDelayedTeleport = setting; }
|
||||
public bool TeleportTo(WorldLocation loc, TeleportToOptions options = 0, uint? instanceId = null)
|
||||
|
||||
public bool TeleportTo(uint mapid, float x, float y, float z, float orientation, TeleportToOptions options = TeleportToOptions.None, uint? instanceId = null)
|
||||
{
|
||||
return TeleportTo(loc.GetMapId(), loc.posX, loc.posY, loc.posZ, loc.Orientation, options, instanceId);
|
||||
return TeleportTo(new TeleportLocation() { Location = new WorldLocation(mapid, x, y, z, orientation), InstanceId = instanceId }, options);
|
||||
}
|
||||
public bool TeleportTo(uint mapid, float x, float y, float z, float orientation, TeleportToOptions options = 0, uint? instanceId = null)
|
||||
|
||||
public bool TeleportTo(WorldLocation loc, TeleportToOptions options = TeleportToOptions.None, uint? instanceId = null)
|
||||
{
|
||||
if (!GridDefines.IsValidMapCoord(mapid, x, y, z, orientation))
|
||||
return TeleportTo(new TeleportLocation() { Location = loc, InstanceId = instanceId }, options);
|
||||
}
|
||||
|
||||
public bool TeleportTo(TeleportLocation teleportLocation, TeleportToOptions options = TeleportToOptions.None)
|
||||
{
|
||||
if (!GridDefines.IsValidMapCoord(teleportLocation.Location))
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "TeleportTo: invalid map ({0}) or invalid coordinates (X: {1}, Y: {2}, Z: {3}, O: {4}) given when teleporting player (GUID: {5}, name: {6}, map: {7}, {8}).",
|
||||
mapid, x, y, z, orientation, GetGUID().ToString(), GetName(), GetMapId(), GetPosition().ToString());
|
||||
Log.outError(LogFilter.Maps, $"Player::TeleportTo: Invalid map ({teleportLocation.Location.GetMapId()}) or invalid coordinates ({teleportLocation.Location.ToString()}) given when teleporting player '{GetGUID()}' ({GetName()}, MapID: {GetMapId()}, {GetPosition()}).");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetSession().HasPermission(RBACPermissions.SkipCheckDisableMap) && DisableMgr.IsDisabledFor(DisableType.Map, mapid, this))
|
||||
if (!GetSession().HasPermission(RBACPermissions.SkipCheckDisableMap) && DisableMgr.IsDisabledFor(DisableType.Map, teleportLocation.Location.GetMapId(), this))
|
||||
{
|
||||
Log.outError(LogFilter.Maps, "Player (GUID: {0}, name: {1}) tried to enter a forbidden map {2}", GetGUID().ToString(), GetName(), mapid);
|
||||
SendTransferAborted(mapid, TransferAbortReason.MapNotAllowed);
|
||||
Log.outError(LogFilter.Maps, $"Player::TeleportTo: Player '{GetGUID()}' ({GetName()}) tried to enter a forbidden map (MapID: {teleportLocation.Location.GetMapId()})");
|
||||
SendTransferAborted(teleportLocation.Location.GetMapId(), TransferAbortReason.MapNotAllowed);
|
||||
return false;
|
||||
}
|
||||
|
||||
// preparing unsummon pet if lost (we must get pet before teleportation or will not find it later)
|
||||
Pet pet = GetPet();
|
||||
|
||||
MapRecord mEntry = CliDB.MapStorage.LookupByKey(mapid);
|
||||
MapRecord mEntry = CliDB.MapStorage.LookupByKey(teleportLocation.Location.GetMapId());
|
||||
|
||||
// don't let enter Battlegrounds without assigned Battlegroundid (for example through areatrigger)...
|
||||
// don't let gm level > 1 either
|
||||
@@ -1987,7 +1996,7 @@ namespace Game.Entities
|
||||
// client without expansion support
|
||||
if (GetSession().GetExpansion() < mEntry.Expansion())
|
||||
{
|
||||
Log.outDebug(LogFilter.Maps, "Player {0} using client without required expansion tried teleport to non accessible map {1}", GetName(), mapid);
|
||||
Log.outDebug(LogFilter.Maps, $"Player {GetName()} using client without required expansion tried teleport to non accessible map {teleportLocation.Location.GetMapId()}");
|
||||
|
||||
ITransport _transport = GetTransport();
|
||||
if (_transport != null)
|
||||
@@ -1996,11 +2005,11 @@ namespace Game.Entities
|
||||
RepopAtGraveyard(); // teleport to near graveyard if on transport, looks blizz like :)
|
||||
}
|
||||
|
||||
SendTransferAborted(mapid, TransferAbortReason.InsufExpanLvl, (byte)mEntry.Expansion());
|
||||
SendTransferAborted(teleportLocation.Location.GetMapId(), TransferAbortReason.InsufExpanLvl, (byte)mEntry.Expansion());
|
||||
return false; // normal client can't teleport to this map...
|
||||
}
|
||||
else
|
||||
Log.outDebug(LogFilter.Maps, "Player {0} is being teleported to map {1}", GetName(), mapid);
|
||||
Log.outDebug(LogFilter.Maps, $"Player {GetName()} is being teleported to map {teleportLocation.Location.GetMapId()}");
|
||||
|
||||
if (m_vehicle != null)
|
||||
ExitVehicle();
|
||||
@@ -2013,18 +2022,17 @@ namespace Game.Entities
|
||||
|
||||
ITransport transport = GetTransport();
|
||||
if (transport != null)
|
||||
{
|
||||
if (!options.HasAnyFlag(TeleportToOptions.NotLeaveTransport))
|
||||
transport.RemovePassenger(this);
|
||||
}
|
||||
if (!teleportLocation.TransportGuid.HasValue || teleportLocation.TransportGuid != transport.GetTransportGUID())
|
||||
if (!options.HasFlag(TeleportToOptions.NotLeaveTransport))
|
||||
transport.RemovePassenger(this);
|
||||
|
||||
// The player was ported to another map and loses the duel immediately.
|
||||
// We have to perform this check before the teleport, otherwise the
|
||||
// ObjectAccessor won't find the flag.
|
||||
if (duel != null && GetMapId() != mapid && GetMap().GetGameObject(m_playerData.DuelArbiter) != null)
|
||||
if (duel != null && GetMapId() != teleportLocation.Location.GetMapId() && GetMap().GetGameObject(m_playerData.DuelArbiter) != null)
|
||||
DuelComplete(DuelCompleteType.Fled);
|
||||
|
||||
if (GetMapId() == mapid && (!instanceId.HasValue || GetInstanceId() == instanceId))
|
||||
if (GetMapId() == teleportLocation.Location.GetMapId() && (!teleportLocation.InstanceId.HasValue || GetInstanceId() == teleportLocation.InstanceId))
|
||||
{
|
||||
//lets reset far teleport flag if it wasn't reset during chained teleports
|
||||
SetSemaphoreTeleportFar(false);
|
||||
@@ -2036,8 +2044,7 @@ namespace Game.Entities
|
||||
{
|
||||
SetSemaphoreTeleportNear(true);
|
||||
//lets save teleport destination for player
|
||||
teleportDest = new WorldLocation(mapid, x, y, z, orientation);
|
||||
m_teleport_instanceId = null;
|
||||
teleportDest = teleportLocation;
|
||||
m_teleport_options = options;
|
||||
return true;
|
||||
}
|
||||
@@ -2045,7 +2052,7 @@ namespace Game.Entities
|
||||
if (!options.HasAnyFlag(TeleportToOptions.NotUnSummonPet))
|
||||
{
|
||||
//same map, only remove pet if out of range for new position
|
||||
if (pet != null && !pet.IsWithinDist3d(x, y, z, GetMap().GetVisibilityRange()))
|
||||
if (pet != null && !pet.IsWithinDist3d(teleportLocation.Location, GetMap().GetVisibilityRange()))
|
||||
UnsummonPetTemporaryIfAny();
|
||||
}
|
||||
|
||||
@@ -2056,8 +2063,7 @@ namespace Game.Entities
|
||||
CombatStop();
|
||||
|
||||
// this will be used instead of the current location in SaveToDB
|
||||
teleportDest = new WorldLocation(mapid, x, y, z, orientation);
|
||||
m_teleport_instanceId = null;
|
||||
teleportDest = teleportLocation;
|
||||
m_teleport_options = options;
|
||||
SetFallInformation(0, GetPositionZ());
|
||||
|
||||
@@ -2072,7 +2078,7 @@ namespace Game.Entities
|
||||
{
|
||||
if (GetClass() == Class.Deathknight && GetMapId() == 609 && !IsGameMaster() && !HasSpell(50977))
|
||||
{
|
||||
SendTransferAborted(mapid, TransferAbortReason.UniqueMessage, 1);
|
||||
SendTransferAborted(teleportLocation.Location.GetMapId(), TransferAbortReason.UniqueMessage, 1);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2082,15 +2088,15 @@ namespace Game.Entities
|
||||
|
||||
// Check enter rights before map getting to avoid creating instance copy for player
|
||||
// this check not dependent from map instance copy and same for all instance copies of selected map
|
||||
TransferAbortParams abortParams = Map.PlayerCannotEnter(mapid, this);
|
||||
TransferAbortParams abortParams = Map.PlayerCannotEnter(teleportLocation.Location.GetMapId(), this);
|
||||
if (abortParams != null)
|
||||
{
|
||||
SendTransferAborted(mapid, abortParams.Reason, abortParams.Arg, abortParams.MapDifficultyXConditionId);
|
||||
SendTransferAborted(teleportLocation.Location.GetMapId(), abortParams.Reason, abortParams.Arg, abortParams.MapDifficultyXConditionId);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Seamless teleport can happen only if cosmetic maps match
|
||||
if (oldmap == null || (oldmap.GetEntry().CosmeticParentMapID != mapid && GetMapId() != mEntry.CosmeticParentMapID &&
|
||||
if (oldmap == null || (oldmap.GetEntry().CosmeticParentMapID != teleportLocation.Location.GetMapId() && GetMapId() != mEntry.CosmeticParentMapID &&
|
||||
!((oldmap.GetEntry().CosmeticParentMapID != -1) ^ (oldmap.GetEntry().CosmeticParentMapID != mEntry.CosmeticParentMapID))))
|
||||
options &= ~TeleportToOptions.Seamless;
|
||||
|
||||
@@ -2104,8 +2110,7 @@ namespace Game.Entities
|
||||
{
|
||||
SetSemaphoreTeleportFar(true);
|
||||
//lets save teleport destination for player
|
||||
teleportDest = new(mapid, x, y, z, orientation);
|
||||
m_teleport_instanceId = instanceId;
|
||||
teleportDest = teleportLocation;
|
||||
m_teleport_options = options;
|
||||
return true;
|
||||
}
|
||||
@@ -2123,7 +2128,7 @@ namespace Game.Entities
|
||||
// Note: at Battlegroundjoin Battlegroundid set before teleport
|
||||
// and we already will found "current" Battleground
|
||||
// just need check that this is targeted map or leave
|
||||
if (bg.GetMapId() != mapid)
|
||||
if (bg.GetMapId() != teleportLocation.Location.GetMapId())
|
||||
LeaveBattleground(false); // don't teleport to entry point
|
||||
}
|
||||
|
||||
@@ -2159,15 +2164,21 @@ namespace Game.Entities
|
||||
{
|
||||
// send transfer packets
|
||||
TransferPending transferPending = new();
|
||||
transferPending.MapID = (int)mapid;
|
||||
transferPending.OldMapPosition = GetPosition();
|
||||
transferPending.MapID = (int)teleportLocation.Location.GetMapId();
|
||||
transferPending.OldMapPosition = teleportLocation.Location.GetPosition();
|
||||
|
||||
Transport transport1 = (Transport)GetTransport();
|
||||
if (transport1 != null)
|
||||
if (teleportLocation.TransportGuid.HasValue)
|
||||
{
|
||||
TransferPending.ShipTransferPending shipTransferPending = new();
|
||||
shipTransferPending.Id = transport1.GetEntry();
|
||||
shipTransferPending.OriginMapID = (int)GetMapId();
|
||||
TransportSpawn transportSpawn = TransportMgr.GetTransportSpawn(teleportLocation.TransportGuid.Value.GetCounter());
|
||||
if (transportSpawn != null)
|
||||
{
|
||||
shipTransferPending.Id = transportSpawn.TransportGameObjectId;
|
||||
if (GetTransport() != null)
|
||||
shipTransferPending.OriginMapID = (int)GetMapId();
|
||||
else
|
||||
shipTransferPending.OriginMapID = -1;
|
||||
}
|
||||
transferPending.Ship = shipTransferPending;
|
||||
}
|
||||
|
||||
@@ -2181,8 +2192,7 @@ namespace Game.Entities
|
||||
if (oldmap != null)
|
||||
oldmap.RemovePlayerFromMap(this, false);
|
||||
|
||||
teleportDest = new WorldLocation(mapid, x, y, z, orientation);
|
||||
m_teleport_instanceId = instanceId;
|
||||
teleportDest = teleportLocation;
|
||||
m_teleport_options = options;
|
||||
SetFallInformation(0, GetPositionZ());
|
||||
// if the player is saved before worldportack (at logout for example)
|
||||
@@ -2203,6 +2213,7 @@ namespace Game.Entities
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool TeleportToBGEntryPoint()
|
||||
{
|
||||
if (m_bgData.joinPos.GetMapId() == 0xFFFFFFFF)
|
||||
@@ -7403,7 +7414,6 @@ namespace Game.Entities
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SetActiveCombatTraitConfigID(int traitConfigId) { SetUpdateFieldValue(m_values.ModifyValue(m_activePlayerData).ModifyValue(m_activePlayerData.ActiveCombatTraitConfigID), (uint)traitConfigId); }
|
||||
|
||||
void InitPrimaryProfessions()
|
||||
@@ -7629,16 +7639,11 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public WorldLocation GetTeleportDest()
|
||||
public TeleportLocation GetTeleportDest()
|
||||
{
|
||||
return teleportDest;
|
||||
}
|
||||
|
||||
public uint? GetTeleportDestInstanceId()
|
||||
{
|
||||
return m_teleport_instanceId;
|
||||
}
|
||||
|
||||
public WorldLocation GetHomebind()
|
||||
{
|
||||
return homebind;
|
||||
@@ -7973,4 +7978,11 @@ namespace Game.Entities
|
||||
SetUpdateFieldValue(personalTabard.ModifyValue(personalTabard.BackgroundColor), backgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
public class TeleportLocation
|
||||
{
|
||||
public WorldLocation Location;
|
||||
public uint? InstanceId;
|
||||
public ObjectGuid? TransportGuid;
|
||||
}
|
||||
}
|
||||
@@ -643,7 +643,7 @@ namespace Game.Entities
|
||||
if (oldMapId != newMapId)
|
||||
{
|
||||
UnloadStaticPassengers();
|
||||
TeleportPassengersAndHideTransport(newMapId, x, y, z, o);
|
||||
TeleportPassengersAndHideTransport(newMapId);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -673,7 +673,7 @@ namespace Game.Entities
|
||||
}
|
||||
}
|
||||
|
||||
void TeleportPassengersAndHideTransport(uint newMapid, float x, float y, float z, float o)
|
||||
void TeleportPassengersAndHideTransport(uint newMapid)
|
||||
{
|
||||
if (newMapid == GetMapId())
|
||||
{
|
||||
@@ -714,12 +714,11 @@ namespace Game.Entities
|
||||
{
|
||||
float destX, destY, destZ, destO;
|
||||
obj.m_movementInfo.transport.pos.GetPosition(out destX, out destY, out destZ, out destO);
|
||||
ITransport.CalculatePassengerPosition(ref destX, ref destY, ref destZ, ref destO, x, y, z, o);
|
||||
|
||||
switch (obj.GetTypeId())
|
||||
{
|
||||
case TypeId.Player:
|
||||
if (!obj.ToPlayer().TeleportTo(newMapid, destX, destY, destZ, destO, TeleportToOptions.NotLeaveTransport))
|
||||
if (!obj.ToPlayer().TeleportTo(new TeleportLocation() { Location = new WorldLocation(newMapid, destX, destY, destZ, destO), TransportGuid = GetTransGUID() }, TeleportToOptions.NotLeaveTransport))
|
||||
RemovePassenger(obj);
|
||||
break;
|
||||
case TypeId.DynamicObject:
|
||||
|
||||
@@ -1203,17 +1203,18 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
public void NearTeleportTo(float x, float y, float z, float orientation, bool casting = false) { NearTeleportTo(new Position(x, y, z, orientation), casting); }
|
||||
|
||||
public void NearTeleportTo(Position pos, bool casting = false)
|
||||
{
|
||||
DisableSpline();
|
||||
if (IsTypeId(TypeId.Player))
|
||||
TeleportLocation target = new() { Location = new(GetMapId(), pos) };
|
||||
if (IsPlayer())
|
||||
{
|
||||
WorldLocation target = new(GetMapId(), pos);
|
||||
ToPlayer().TeleportTo(target, (TeleportToOptions.NotLeaveTransport | TeleportToOptions.NotLeaveCombat | TeleportToOptions.NotUnSummonPet | (casting ? TeleportToOptions.Spell : 0)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SendTeleportPacket(pos);
|
||||
SendTeleportPacket(target);
|
||||
UpdatePosition(pos, true);
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
@@ -1881,7 +1882,7 @@ namespace Game.Entities
|
||||
}
|
||||
|
||||
//Teleport
|
||||
public void SendTeleportPacket(Position pos)
|
||||
public void SendTeleportPacket(TeleportLocation teleportLocation)
|
||||
{
|
||||
// SMSG_MOVE_UPDATE_TELEPORT is sent to nearby players to signal the teleport
|
||||
// SMSG_MOVE_TELEPORT is sent to self in order to trigger CMSG_MOVE_TELEPORT_ACK and update the position server side
|
||||
@@ -1896,20 +1897,11 @@ namespace Game.Entities
|
||||
Player playerMover = GetUnitBeingMoved()?.ToPlayer();
|
||||
if (playerMover != null)
|
||||
{
|
||||
float x, y, z, o;
|
||||
pos.GetPosition(out x, out y, out z, out o);
|
||||
|
||||
ITransport transportBase = GetDirectTransport();
|
||||
if (transportBase != null)
|
||||
transportBase.CalculatePassengerOffset(ref x, ref y, ref z, ref o);
|
||||
|
||||
MoveTeleport moveTeleport = new();
|
||||
moveTeleport.MoverGUID = GetGUID();
|
||||
moveTeleport.Pos = new Position(x, y, z, o);
|
||||
if (GetTransGUID() != ObjectGuid.Empty)
|
||||
moveTeleport.TransportGUID = GetTransGUID();
|
||||
|
||||
moveTeleport.Facing = o;
|
||||
moveTeleport.Pos = teleportLocation.Location;
|
||||
moveTeleport.TransportGUID = teleportLocation.TransportGuid;
|
||||
moveTeleport.Facing = teleportLocation.Location.GetOrientation();
|
||||
moveTeleport.SequenceIndex = m_movementCounter++;
|
||||
playerMover.SendPacket(moveTeleport);
|
||||
|
||||
@@ -1920,15 +1912,21 @@ namespace Game.Entities
|
||||
// This is the only packet sent for creatures which contains MovementInfo structure
|
||||
// we do not update m_movementInfo for creatures so it needs to be done manually here
|
||||
moveUpdateTeleport.Status.Guid = GetGUID();
|
||||
moveUpdateTeleport.Status.Pos.Relocate(pos);
|
||||
moveUpdateTeleport.Status.Time = Time.GetMSTime();
|
||||
var transportBase = GetDirectTransport();
|
||||
if (transportBase != null)
|
||||
|
||||
if (teleportLocation.TransportGuid.HasValue)
|
||||
{
|
||||
pos.GetPosition(out float tx, out float ty, out float tz, out float to);
|
||||
transportBase.CalculatePassengerOffset(ref tx, ref ty, ref tz, ref to);
|
||||
moveUpdateTeleport.Status.transport.pos.Relocate(tx, ty, tz, to);
|
||||
Transport transport = GetMap().GetTransport(teleportLocation.TransportGuid.Value);
|
||||
if (transport == null)
|
||||
return;
|
||||
|
||||
teleportLocation.Location.GetPosition(out float x, out float y, out float z, out float o);
|
||||
transport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
|
||||
moveUpdateTeleport.Status.Pos.Relocate(x, y, z, o);
|
||||
moveUpdateTeleport.Status.transport.pos.Relocate(teleportLocation.Location);
|
||||
}
|
||||
else
|
||||
moveUpdateTeleport.Status.Pos.Relocate(teleportLocation.Location);
|
||||
}
|
||||
|
||||
// Broadcast the packet to everyone except self.
|
||||
|
||||
@@ -246,33 +246,32 @@ namespace Game
|
||||
player.SetSemaphoreTeleportFar(false);
|
||||
|
||||
// get the teleport destination
|
||||
WorldLocation loc = player.GetTeleportDest();
|
||||
var loc = player.GetTeleportDest();
|
||||
|
||||
// possible errors in the coordinate validity check
|
||||
if (!GridDefines.IsValidMapCoord(loc))
|
||||
if (!GridDefines.IsValidMapCoord(loc.Location))
|
||||
{
|
||||
LogoutPlayer(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// get the destination map entry, not the current one, this will fix homebind and reset greeting
|
||||
MapRecord mapEntry = CliDB.MapStorage.LookupByKey(loc.GetMapId());
|
||||
MapRecord mapEntry = CliDB.MapStorage.LookupByKey(loc.Location.GetMapId());
|
||||
|
||||
// reset instance validity, except if going to an instance inside an instance
|
||||
if (!player.m_InstanceValid && !mapEntry.IsDungeon())
|
||||
player.m_InstanceValid = true;
|
||||
|
||||
Map oldMap = player.GetMap();
|
||||
Map newMap = GetPlayer().GetTeleportDestInstanceId().HasValue ? Global.MapMgr.FindMap(loc.GetMapId(), GetPlayer().GetTeleportDestInstanceId().Value) : Global.MapMgr.CreateMap(loc.GetMapId(), GetPlayer());
|
||||
Map newMap = loc.InstanceId.HasValue ? Global.MapMgr.FindMap(loc.Location.GetMapId(), loc.InstanceId.Value) : Global.MapMgr.CreateMap(loc.Location.GetMapId(), GetPlayer());
|
||||
|
||||
MovementInfo.TransportInfo transportInfo = player.m_movementInfo.transport;
|
||||
ITransport transport = player.GetTransport();
|
||||
if (transport != null)
|
||||
transport.RemovePassenger(player);
|
||||
|
||||
if (player.IsInWorld)
|
||||
{
|
||||
Log.outError(LogFilter.Network, $"Player (Name {player.GetName()}) is still in world when teleported from map {oldMap.GetId()} to new map {loc.GetMapId()}");
|
||||
Log.outError(LogFilter.Network, $"Player (Name {player.GetName()}) is still in world when teleported from map {oldMap.GetId()} to new map {loc.Location.GetMapId()}");
|
||||
oldMap.RemovePlayerFromMap(player, false);
|
||||
}
|
||||
|
||||
@@ -281,13 +280,13 @@ namespace Game
|
||||
// while the player is in transit, for example the map may get full
|
||||
if (newMap == null || newMap.CannotEnter(player) != null)
|
||||
{
|
||||
Log.outError(LogFilter.Network, $"Map {loc.GetMapId()} could not be created for {(newMap != null ? newMap.GetMapName() : "Unknown")} ({player.GetGUID()}), porting player to homebind");
|
||||
Log.outError(LogFilter.Network, $"Map {loc.Location.GetMapId()} could not be created for {(newMap != null ? newMap.GetMapName() : "Unknown")} ({player.GetGUID()}), porting player to homebind");
|
||||
player.TeleportTo(player.GetHomebind());
|
||||
return;
|
||||
}
|
||||
|
||||
float z = loc.GetPositionZ() + player.GetHoverOffset();
|
||||
player.Relocate(loc.GetPositionX(), loc.GetPositionY(), z, loc.GetOrientation());
|
||||
float zOffset = loc.Location.GetPositionZ() + player.GetHoverOffset();
|
||||
player.Relocate(loc.Location.GetPositionX(), loc.Location.GetPositionY(), zOffset, loc.Location.GetOrientation());
|
||||
player.SetFallInformation(0, player.GetPositionZ());
|
||||
|
||||
player.ResetMap();
|
||||
@@ -301,17 +300,27 @@ namespace Game
|
||||
if (!seamlessTeleport)
|
||||
player.SendInitialPacketsBeforeAddToMap();
|
||||
|
||||
// move player between transport copies on each map
|
||||
Transport newTransport = newMap.GetTransport(transportInfo.guid);
|
||||
if (newTransport != null)
|
||||
if (loc.TransportGuid.HasValue)
|
||||
{
|
||||
player.m_movementInfo.transport = transportInfo;
|
||||
newTransport.AddPassenger(player);
|
||||
Transport newTransport = newMap.GetTransport(loc.TransportGuid.Value);
|
||||
if (newTransport != null)
|
||||
{
|
||||
newTransport.AddPassenger(player);
|
||||
player.m_movementInfo.transport.pos.Relocate(loc.Location);
|
||||
loc.Location.GetPosition(out float x, out float y, out float z, out float o);
|
||||
newTransport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
|
||||
player.Relocate(x, y, z, o);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (transport != null)
|
||||
transport.RemovePassenger(player);
|
||||
}
|
||||
|
||||
if (!player.GetMap().AddPlayerToMap(player, !seamlessTeleport))
|
||||
{
|
||||
Log.outError(LogFilter.Network, $"WORLD: failed to teleport player {player.GetName()} ({player.GetGUID()}) to map {loc.GetMapId()} ({(newMap != null ? newMap.GetMapName() : "Unknown")}) because of unknown reason!");
|
||||
Log.outError(LogFilter.Network, $"WORLD: failed to teleport player {player.GetName()} ({player.GetGUID()}) to map {loc.Location.GetMapId()} ({(newMap != null ? newMap.GetMapName() : "Unknown")}) because of unknown reason!");
|
||||
player.ResetMap();
|
||||
player.SetMap(oldMap);
|
||||
player.TeleportTo(player.GetHomebind());
|
||||
@@ -440,18 +449,18 @@ namespace Game
|
||||
if (!_player.IsBeingTeleportedFar())
|
||||
return;
|
||||
|
||||
WorldLocation loc = GetPlayer().GetTeleportDest();
|
||||
var loc = GetPlayer().GetTeleportDest();
|
||||
|
||||
if (CliDB.MapStorage.LookupByKey(loc.GetMapId()).IsDungeon())
|
||||
if (CliDB.MapStorage.LookupByKey(loc.Location.GetMapId()).IsDungeon())
|
||||
{
|
||||
UpdateLastInstance updateLastInstance = new();
|
||||
updateLastInstance.MapID = loc.GetMapId();
|
||||
updateLastInstance.MapID = loc.Location.GetMapId();
|
||||
SendPacket(updateLastInstance);
|
||||
}
|
||||
|
||||
NewWorld packet = new();
|
||||
packet.MapID = loc.GetMapId();
|
||||
packet.Loc.Pos = loc;
|
||||
packet.MapID = loc.Location.GetMapId();
|
||||
packet.Loc.Pos = loc.Location;
|
||||
packet.Reason = (uint)(!_player.IsBeingTeleportedSeamlessly() ? NewWorldReason.Normal : NewWorldReason.Seamless);
|
||||
SendPacket(packet);
|
||||
|
||||
@@ -474,9 +483,21 @@ namespace Game
|
||||
|
||||
uint old_zone = plMover.GetZoneId();
|
||||
|
||||
WorldLocation dest = plMover.GetTeleportDest();
|
||||
var dest = plMover.GetTeleportDest();
|
||||
|
||||
plMover.UpdatePosition(dest, true);
|
||||
dest.Location.GetPosition(out float x, out float y, out float z, out float o);
|
||||
if (dest.TransportGuid.HasValue)
|
||||
{
|
||||
Transport transport = plMover.GetMap().GetTransport(dest.TransportGuid.Value);
|
||||
if (transport != null)
|
||||
{
|
||||
transport.AddPassenger(plMover);
|
||||
plMover.m_movementInfo.transport.pos.Relocate(dest.Location.GetPosition());
|
||||
transport.CalculatePassengerPosition(ref x, ref y, ref z, ref o);
|
||||
}
|
||||
}
|
||||
|
||||
plMover.UpdatePosition(dest.Location, true);
|
||||
plMover.SetFallInformation(0, GetPlayer().GetPositionZ());
|
||||
|
||||
uint newzone, newarea;
|
||||
|
||||
Reference in New Issue
Block a user