From 7371c7662a05d2c1dae1c110905817bb873cf934 Mon Sep 17 00:00:00 2001 From: CasperW Date: Sat, 26 Dec 2009 18:14:12 +0100 Subject: [PATCH] Fix for landing points. Only one scenario is not fully covered by this change, and that is people who teleport from neighbouring regions, who won't get affected by the landing point. --- OpenSim/Region/Framework/Scenes/Scene.cs | 2 + .../Scenes/SceneCommunicationService.cs | 47 ++++++++++++++----- .../Region/Framework/Scenes/ScenePresence.cs | 25 ++++++++-- 3 files changed, 59 insertions(+), 15 deletions(-) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 265129c5c1..37734f40eb 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -3460,6 +3460,7 @@ namespace OpenSim.Region.Framework.Scenes } } // Honor parcel landing type and position. + /* ILandObject land = LandChannel.GetLandObject(agent.startpos.X, agent.startpos.Y); if (land != null) { @@ -3468,6 +3469,7 @@ namespace OpenSim.Region.Framework.Scenes agent.startpos = land.LandData.UserLocation; } } + */// This is now handled properly in ScenePresence.MakeRootAgent } m_authenticateHandler.AddNewCircuit(agent.circuitcode, agent); diff --git a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs index e649139332..0a02d3942f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs +++ b/OpenSim/Region/Framework/Scenes/SceneCommunicationService.cs @@ -706,17 +706,42 @@ namespace OpenSim.Region.Framework.Scenes { m_log.DebugFormat( "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation {0} within {1}", - position, m_regionInfo.RegionName); - - // Teleport within the same region - if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) - { - Vector3 emergencyPos = new Vector3(128, 128, 128); - - m_log.WarnFormat( - "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - position, avatar.Name, avatar.UUID, emergencyPos); - position = emergencyPos; + position, m_regionInfo.RegionName); + + // Teleport within the same region + if (IsOutsideRegion(avatar.Scene, position) || position.Z < 0) + { + Vector3 emergencyPos = new Vector3(128, 128, 128); + + m_log.WarnFormat( + "[SCENE COMMUNICATION SERVICE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + position, avatar.Name, avatar.UUID, emergencyPos); + position = emergencyPos; + } + + Vector3 currentPos = avatar.AbsolutePosition; + ILandObject srcLand = m_scene.LandChannel.GetLandObject(currentPos.X, currentPos.Y); + ILandObject destLand = m_scene.LandChannel.GetLandObject(position.X, position.Y); + if (srcLand != null && destLand != null && (teleportFlags & (uint)TeleportFlags.ViaLure) == 0 && (teleportFlags & (uint)TeleportFlags.ViaGodlikeLure) == 0) + { + if (srcLand.LandData.LocalID == destLand.LandData.LocalID) + { + //TPing within the same parcel. If the landing point is restricted, block the TP. + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) + { + avatar.ControllingClient.SendAgentAlertMessage("Can't TP to the destination; landing point set.", false); + position = currentPos; + } + } + else + { + //Tping to a different parcel. Respect the landing point on the destination parcel. + if (destLand.LandData.LandingType == (byte)1 && destLand.LandData.UserLocation != Vector3.Zero && avatar.GodLevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(avatar.UUID) && destLand.LandData.OwnerID != avatar.UUID) + { + position = destLand.LandData.UserLocation; + } + } } // TODO: Get proper AVG Height diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index a3ad7ca94f..c3bc96ae4a 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -836,9 +836,24 @@ namespace OpenSim.Region.Framework.Scenes { Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); pos.Y = crossedBorder.BorderLine.Z - 1; + } + + //If they're TP'ing in or logging in, we haven't had time to add any known child regions yet. + //This has the unfortunate consequence that if somebody is TP'ing who is already a child agent, + //they'll bypass the landing point. But I can't think of any decent way of fixing this. + if (KnownChildRegionHandles.Count == 0) + { + ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); + if (land != null) + { + //Don't restrict gods, estate managers, or land owners to the TP point. This behaviour mimics agni. + if (land.LandData.LandingType == (byte)1 && land.LandData.UserLocation != Vector3.Zero && m_godlevel < 200 && !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid) && land.LandData.OwnerID != m_uuid) + { + pos = land.LandData.UserLocation; + } + } } - if (pos.X < 0 || pos.Y < 0 || pos.Z < 0) { Vector3 emergencyPos = new Vector3(((int)Constants.RegionSize * 0.5f), ((int)Constants.RegionSize * 0.5f), 128); @@ -973,9 +988,10 @@ namespace OpenSim.Region.Framework.Scenes public void Teleport(Vector3 pos) { bool isFlying = false; - if (m_physicsActor != null) - isFlying = m_physicsActor.Flying; + if (m_physicsActor != null) + isFlying = m_physicsActor.Flying; + RemoveFromPhysicalScene(); Velocity = Vector3.Zero; AbsolutePosition = pos; @@ -986,7 +1002,8 @@ namespace OpenSim.Region.Framework.Scenes SetHeight(m_appearance.AvatarHeight); } - SendTerseUpdateToAllClients(); + SendTerseUpdateToAllClients(); + } public void TeleportWithMomentum(Vector3 pos)