diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index feb783f74a..f0943463a7 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -192,7 +192,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.WarnFormat( "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, sp.Name, sp.UUID, emergencyPos); - + position = emergencyPos; } @@ -215,6 +215,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); + sp.Velocity = Vector3.Zero; sp.Teleport(position); foreach (SceneObjectGroup grp in sp.GetAttachments()) diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b5f789b52a..e8178ce905 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -990,23 +990,24 @@ namespace OpenSim.Region.Framework.Scenes /// public void Teleport(Vector3 pos) { - bool isFlying = Flying; - RemoveFromPhysicalScene(); - Velocity = Vector3.Zero; - CheckLandingPoint(ref pos); - AbsolutePosition = pos; - AddToPhysicalScene(isFlying); - - SendTerseUpdateToAllClients(); + TeleportWithMomentum(pos, null); } - public void TeleportWithMomentum(Vector3 pos) + public void TeleportWithMomentum(Vector3 pos, Vector3? v) { bool isFlying = Flying; + Vector3 vel = Velocity; RemoveFromPhysicalScene(); CheckLandingPoint(ref pos); AbsolutePosition = pos; AddToPhysicalScene(isFlying); + if (PhysicsActor != null) + { + if (v.HasValue) + PhysicsActor.SetMomentum((Vector3)v); + else + PhysicsActor.SetMomentum(vel); + } SendTerseUpdateToAllClients(); } diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index bebc10ca25..eb7bfbd802 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -33,6 +33,7 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Framework.Communications; using OpenSim.Framework.Servers; +using OpenSim.Region.CoreModules.Framework.EntityTransfer; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation; using OpenSim.Tests.Common; @@ -47,6 +48,41 @@ namespace OpenSim.Region.Framework.Scenes.Tests [TestFixture] public class ScenePresenceTeleportTests { + [Test] + public void TestSameRegionTeleport() + { + TestHelpers.InMethod(); +// log4net.Config.XmlConfigurator.Configure(); + + EntityTransferModule etm = new EntityTransferModule(); + + IConfigSource config = new IniConfigSource(); + config.AddConfig("Modules"); + // Not strictly necessary since FriendsModule assumes it is the default (!) + config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + + TestScene scene = SceneHelpers.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); + SceneHelpers.SetupSceneModules(scene, config, etm); + + Vector3 teleportPosition = new Vector3(10, 11, 12); + Vector3 teleportLookAt = new Vector3(20, 21, 22); + + ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); + sp.AbsolutePosition = new Vector3(30, 31, 32); + scene.RequestTeleportLocation( + sp.ControllingClient, + scene.RegionInfo.RegionHandle, + teleportPosition, + teleportLookAt, + (uint)TeleportFlags.ViaLocation); + + Assert.That(sp.AbsolutePosition, Is.EqualTo(teleportPosition)); + + // Lookat is sent to the client only - sp.Lookat does not yield the same thing (calculation from camera + // position instead). +// Assert.That(sp.Lookat, Is.EqualTo(teleportLookAt)); + } + /// /// Test a teleport between two regions that are not neighbours and do not share any neighbours in common. /// diff --git a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs index 922eaafeda..d192309dea 100644 --- a/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs +++ b/OpenSim/Region/OptionalModules/Scripting/Minimodule/SPAvatar.cs @@ -68,7 +68,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule public Vector3 WorldPosition { get { return GetSP().AbsolutePosition; } - set { GetSP().TeleportWithMomentum(value); } + set { GetSP().Teleport(value); } } public bool IsChildAgent