diff options
author | Melanie | 2012-02-14 23:16:20 +0100 |
---|---|---|
committer | Melanie | 2012-02-14 23:16:20 +0100 |
commit | 2d3381b795611a8857077d1effb41323c2cb8658 (patch) | |
tree | a1b8a6d7832858d14bfb08eac29fcf3e643ef17c | |
parent | Prevent object loss and positioning outside the region with failed object sim (diff) | |
download | opensim-SC-2d3381b795611a8857077d1effb41323c2cb8658.zip opensim-SC-2d3381b795611a8857077d1effb41323c2cb8658.tar.gz opensim-SC-2d3381b795611a8857077d1effb41323c2cb8658.tar.bz2 opensim-SC-2d3381b795611a8857077d1effb41323c2cb8658.tar.xz |
Implement region crossing of sitting avatars. Edit mode and llSetPos work
but unscripted default sit anim is lost. Still some Gfx glitching. Physical
crossing doesn't work yet.
6 files changed, 232 insertions, 157 deletions
diff --git a/OpenSim/Framework/ChildAgentDataUpdate.cs b/OpenSim/Framework/ChildAgentDataUpdate.cs index 6d048f4..fe12874 100644 --- a/OpenSim/Framework/ChildAgentDataUpdate.cs +++ b/OpenSim/Framework/ChildAgentDataUpdate.cs | |||
@@ -308,6 +308,8 @@ namespace OpenSim.Framework | |||
308 | public Animation[] Anims; | 308 | public Animation[] Anims; |
309 | 309 | ||
310 | public UUID GranterID; | 310 | public UUID GranterID; |
311 | public UUID ParentPart; | ||
312 | public Vector3 SitOffset; | ||
311 | 313 | ||
312 | // Appearance | 314 | // Appearance |
313 | public AvatarAppearance Appearance; | 315 | public AvatarAppearance Appearance; |
@@ -468,6 +470,10 @@ namespace OpenSim.Framework | |||
468 | } | 470 | } |
469 | args["attach_objects"] = attObjs; | 471 | args["attach_objects"] = attObjs; |
470 | } | 472 | } |
473 | |||
474 | args["parent_part"] = OSD.FromUUID(ParentPart); | ||
475 | args["sit_offset"] = OSD.FromString(SitOffset.ToString()); | ||
476 | |||
471 | return args; | 477 | return args; |
472 | } | 478 | } |
473 | 479 | ||
@@ -675,6 +681,11 @@ namespace OpenSim.Framework | |||
675 | } | 681 | } |
676 | } | 682 | } |
677 | } | 683 | } |
684 | |||
685 | if (args["parent_part"] != null) | ||
686 | ParentPart = args["parent_part"].AsUUID(); | ||
687 | if (args["sit_offset"] != null) | ||
688 | Vector3.TryParse(args["sit_offset"].AsString(), out SitOffset); | ||
678 | } | 689 | } |
679 | 690 | ||
680 | public AgentData() | 691 | public AgentData() |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 8ed250d..161feda 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -1549,7 +1549,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1549 | 1549 | ||
1550 | public void SendKillObject(ulong regionHandle, List<uint> localIDs) | 1550 | public void SendKillObject(ulong regionHandle, List<uint> localIDs) |
1551 | { | 1551 | { |
1552 | // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, localID, regionHandle); | 1552 | // foreach (uint id in localIDs) |
1553 | // m_log.DebugFormat("[CLIENT]: Sending KillObjectPacket to {0} for {1} in {2}", Name, id, regionHandle); | ||
1553 | 1554 | ||
1554 | KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); | 1555 | KillObjectPacket kill = (KillObjectPacket)PacketPool.Instance.GetPacket(PacketType.KillObject); |
1555 | // TODO: don't create new blocks if recycling an old packet | 1556 | // TODO: don't create new blocks if recycling an old packet |
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 4b1c0bc..9a6dfe1 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | |||
@@ -681,11 +681,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
681 | 681 | ||
682 | #region Agent Crossings | 682 | #region Agent Crossings |
683 | 683 | ||
684 | public bool Cross(ScenePresence agent, bool isFlying) | 684 | public GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos) |
685 | { | 685 | { |
686 | Scene scene = agent.Scene; | 686 | version = String.Empty; |
687 | Vector3 pos = agent.AbsolutePosition; | 687 | newpos = new Vector3(pos.X, pos.Y, pos.Z); |
688 | Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); | ||
689 | uint neighbourx = scene.RegionInfo.RegionLocX; | 688 | uint neighbourx = scene.RegionInfo.RegionLocX; |
690 | uint neighboury = scene.RegionInfo.RegionLocY; | 689 | uint neighboury = scene.RegionInfo.RegionLocY; |
691 | const float boundaryDistance = 1.7f; | 690 | const float boundaryDistance = 1.7f; |
@@ -706,53 +705,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
706 | } | 705 | } |
707 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 706 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
708 | { | 707 | { |
709 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 708 | neighboury--; |
710 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | 709 | newpos.Y = Constants.RegionSize - enterDistance; |
711 | { | ||
712 | neighboury--; | ||
713 | newpos.Y = Constants.RegionSize - enterDistance; | ||
714 | } | ||
715 | else | ||
716 | { | ||
717 | agent.IsInTransit = true; | ||
718 | |||
719 | neighboury = b.TriggerRegionY; | ||
720 | neighbourx = b.TriggerRegionX; | ||
721 | |||
722 | Vector3 newposition = pos; | ||
723 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
724 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
725 | agent.ControllingClient.SendAgentAlertMessage( | ||
726 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
727 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
728 | return true; | ||
729 | } | ||
730 | } | ||
731 | |||
732 | Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W); | ||
733 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | ||
734 | { | ||
735 | neighbourx--; | ||
736 | newpos.X = Constants.RegionSize - enterDistance; | ||
737 | } | 710 | } |
738 | else | ||
739 | { | ||
740 | agent.IsInTransit = true; | ||
741 | |||
742 | neighboury = ba.TriggerRegionY; | ||
743 | neighbourx = ba.TriggerRegionX; | ||
744 | 711 | ||
745 | 712 | neighbourx--; | |
746 | Vector3 newposition = pos; | 713 | newpos.X = Constants.RegionSize - enterDistance; |
747 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
748 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
749 | agent.ControllingClient.SendAgentAlertMessage( | ||
750 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
751 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
752 | |||
753 | |||
754 | return true; | ||
755 | } | ||
756 | 714 | ||
757 | } | 715 | } |
758 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) | 716 | else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) |
@@ -763,26 +721,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
763 | 721 | ||
764 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 722 | if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
765 | { | 723 | { |
766 | Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 724 | neighboury--; |
767 | if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) | 725 | newpos.Y = Constants.RegionSize - enterDistance; |
768 | { | ||
769 | neighboury--; | ||
770 | newpos.Y = Constants.RegionSize - enterDistance; | ||
771 | } | ||
772 | else | ||
773 | { | ||
774 | agent.IsInTransit = true; | ||
775 | |||
776 | neighboury = ba.TriggerRegionY; | ||
777 | neighbourx = ba.TriggerRegionX; | ||
778 | Vector3 newposition = pos; | ||
779 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
780 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
781 | agent.ControllingClient.SendAgentAlertMessage( | ||
782 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
783 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
784 | return true; | ||
785 | } | ||
786 | } | 726 | } |
787 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 727 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) |
788 | { | 728 | { |
@@ -790,35 +730,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
790 | neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); | 730 | neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); |
791 | newpos.Y = enterDistance; | 731 | newpos.Y = enterDistance; |
792 | } | 732 | } |
793 | |||
794 | |||
795 | } | 733 | } |
796 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) | 734 | else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) |
797 | { | 735 | { |
798 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); | 736 | Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); |
799 | if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) | 737 | neighboury--; |
800 | { | 738 | newpos.Y = Constants.RegionSize - enterDistance; |
801 | neighboury--; | ||
802 | newpos.Y = Constants.RegionSize - enterDistance; | ||
803 | } | ||
804 | else | ||
805 | { | ||
806 | agent.IsInTransit = true; | ||
807 | |||
808 | neighboury = b.TriggerRegionY; | ||
809 | neighbourx = b.TriggerRegionX; | ||
810 | Vector3 newposition = pos; | ||
811 | newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; | ||
812 | newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; | ||
813 | agent.ControllingClient.SendAgentAlertMessage( | ||
814 | String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); | ||
815 | InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); | ||
816 | return true; | ||
817 | } | ||
818 | } | 739 | } |
819 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) | 740 | else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) |
820 | { | 741 | { |
821 | |||
822 | Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); | 742 | Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); |
823 | neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); | 743 | neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); |
824 | newpos.Y = enterDistance; | 744 | newpos.Y = enterDistance; |
@@ -849,19 +769,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
849 | } | 769 | } |
850 | */ | 770 | */ |
851 | 771 | ||
852 | ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); | 772 | xDest = neighbourx; |
773 | yDest = neighboury; | ||
853 | 774 | ||
854 | int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); | 775 | int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); |
855 | 776 | ||
777 | ulong neighbourHandle = Utils.UIntsToLong((uint)x, (uint)y); | ||
778 | |||
856 | ExpiringCache<ulong, DateTime> r; | 779 | ExpiringCache<ulong, DateTime> r; |
857 | DateTime banUntil; | 780 | DateTime banUntil; |
858 | 781 | ||
859 | if (m_bannedRegions.TryGetValue(agent.ControllingClient.AgentId, out r)) | 782 | if (m_bannedRegions.TryGetValue(agentID, out r)) |
860 | { | 783 | { |
861 | if (r.TryGetValue(neighbourHandle, out banUntil)) | 784 | if (r.TryGetValue(neighbourHandle, out banUntil)) |
862 | { | 785 | { |
863 | if (DateTime.Now < banUntil) | 786 | if (DateTime.Now < banUntil) |
864 | return false; | 787 | return null; |
865 | r.Remove(neighbourHandle); | 788 | r.Remove(neighbourHandle); |
866 | } | 789 | } |
867 | } | 790 | } |
@@ -873,28 +796,43 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
873 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); | 796 | GridRegion neighbourRegion = scene.GridService.GetRegionByPosition(scene.RegionInfo.ScopeID, (int)x, (int)y); |
874 | 797 | ||
875 | string reason; | 798 | string reason; |
876 | string version; | 799 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agentID, newpos, out version, out reason)) |
877 | if (!scene.SimulationService.QueryAccess(neighbourRegion, agent.ControllingClient.AgentId, newpos, out version, out reason)) | ||
878 | { | 800 | { |
879 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
880 | if (r == null) | 801 | if (r == null) |
881 | { | 802 | { |
882 | r = new ExpiringCache<ulong, DateTime>(); | 803 | r = new ExpiringCache<ulong, DateTime>(); |
883 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 804 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
884 | 805 | ||
885 | m_bannedRegions.Add(agent.ControllingClient.AgentId, r, TimeSpan.FromSeconds(45)); | 806 | m_bannedRegions.Add(agentID, r, TimeSpan.FromSeconds(45)); |
886 | } | 807 | } |
887 | else | 808 | else |
888 | { | 809 | { |
889 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); | 810 | r.Add(neighbourHandle, DateTime.Now + TimeSpan.FromSeconds(15), TimeSpan.FromSeconds(15)); |
890 | } | 811 | } |
812 | return null; | ||
813 | } | ||
814 | |||
815 | return neighbourRegion; | ||
816 | } | ||
817 | |||
818 | public bool Cross(ScenePresence agent, bool isFlying) | ||
819 | { | ||
820 | uint x; | ||
821 | uint y; | ||
822 | Vector3 newpos; | ||
823 | string version; | ||
824 | |||
825 | GridRegion neighbourRegion = GetDestination(agent.Scene, agent.UUID, agent.AbsolutePosition, out x, out y, out version, out newpos); | ||
826 | if (neighbourRegion == null) | ||
827 | { | ||
828 | agent.ControllingClient.SendAlertMessage("Cannot region cross into banned parcel"); | ||
891 | return false; | 829 | return false; |
892 | } | 830 | } |
893 | 831 | ||
894 | agent.IsInTransit = true; | 832 | agent.IsInTransit = true; |
895 | 833 | ||
896 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; | 834 | CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; |
897 | d.BeginInvoke(agent, newpos, neighbourx, neighboury, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); | 835 | d.BeginInvoke(agent, newpos, x, y, neighbourRegion, isFlying, version, CrossAgentToNewRegionCompleted, d); |
898 | 836 | ||
899 | return true; | 837 | return true; |
900 | } | 838 | } |
@@ -951,13 +889,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer | |||
951 | icon.EndInvoke(iar); | 889 | icon.EndInvoke(iar); |
952 | } | 890 | } |
953 | 891 | ||
954 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); | ||
955 | |||
956 | /// <summary> | 892 | /// <summary> |
957 | /// This Closes child agents on neighbouring regions | 893 | /// This Closes child agents on neighbouring regions |
958 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. | 894 | /// Calls an asynchronous method to do so.. so it doesn't lag the sim. |
959 | /// </summary> | 895 | /// </summary> |
960 | protected ScenePresence CrossAgentToNewRegionAsync( | 896 | public ScenePresence CrossAgentToNewRegionAsync( |
961 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, | 897 | ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, |
962 | bool isFlying, string version) | 898 | bool isFlying, string version) |
963 | { | 899 | { |
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index c38ecd9..76f1641 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs | |||
@@ -35,6 +35,8 @@ using OpenSim.Region.Framework.Scenes; | |||
35 | 35 | ||
36 | namespace OpenSim.Region.Framework.Interfaces | 36 | namespace OpenSim.Region.Framework.Interfaces |
37 | { | 37 | { |
38 | public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); | ||
39 | |||
38 | public interface IEntityTransferModule | 40 | public interface IEntityTransferModule |
39 | { | 41 | { |
40 | void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, | 42 | void Teleport(ScenePresence agent, ulong regionHandle, Vector3 position, |
@@ -53,7 +55,12 @@ namespace OpenSim.Region.Framework.Interfaces | |||
53 | 55 | ||
54 | void EnableChildAgent(ScenePresence agent, GridRegion region); | 56 | void EnableChildAgent(ScenePresence agent, GridRegion region); |
55 | 57 | ||
58 | GridRegion GetDestination(Scene scene, UUID agentID, Vector3 pos, out uint xDest, out uint yDest, out string version, out Vector3 newpos); | ||
59 | |||
56 | void Cross(SceneObjectGroup sog, Vector3 position, bool silent); | 60 | void Cross(SceneObjectGroup sog, Vector3 position, bool silent); |
61 | |||
62 | ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version); | ||
63 | |||
57 | } | 64 | } |
58 | 65 | ||
59 | public interface IUserAgentVerificationModule | 66 | public interface IUserAgentVerificationModule |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 877fe96..a4ca0fb 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -465,10 +465,76 @@ namespace OpenSim.Region.Framework.Scenes | |||
465 | || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) | 465 | || Scene.TestBorderCross(val - Vector3.UnitY, Cardinals.N) || Scene.TestBorderCross(val + Vector3.UnitY, Cardinals.S)) |
466 | && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) | 466 | && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) |
467 | { | 467 | { |
468 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | 468 | IEntityTransferModule entityTransfer = m_scene.RequestModuleInterface<IEntityTransferModule>(); |
469 | uint x = 0; | ||
470 | uint y = 0; | ||
471 | string version = String.Empty; | ||
472 | Vector3 newpos = Vector3.Zero; | ||
473 | OpenSim.Services.Interfaces.GridRegion destination = null; | ||
474 | |||
475 | bool canCross = true; | ||
476 | foreach (ScenePresence av in m_linkedAvatars) | ||
477 | { | ||
478 | // We need to cross these agents. First, let's find | ||
479 | // out if any of them can't cross for some reason. | ||
480 | // We have to deny the crossing entirely if any | ||
481 | // of them are banned. Alternatively, we could | ||
482 | // unsit banned agents.... | ||
483 | |||
484 | |||
485 | // We set the avatar position as being the object | ||
486 | // position to get the region to send to | ||
487 | if ((destination = entityTransfer.GetDestination(m_scene, av.UUID, val, out x, out y, out version, out newpos)) == null) | ||
488 | { | ||
489 | canCross = false; | ||
490 | break; | ||
491 | } | ||
492 | |||
493 | m_log.DebugFormat("[SCENE OBJECT]: Avatar {0} needs to be crossed to {1}", av.Name, destination.RegionName); | ||
494 | } | ||
495 | |||
496 | if (canCross) | ||
497 | { | ||
498 | // We unparent the SP quietly so that it won't | ||
499 | // be made to stand up | ||
500 | foreach (ScenePresence av in m_linkedAvatars) | ||
501 | { | ||
502 | SceneObjectPart parentPart = m_scene.GetSceneObjectPart(av.ParentID); | ||
503 | if (parentPart != null) | ||
504 | av.ParentUUID = parentPart.UUID; | ||
505 | |||
506 | av.ParentID = 0; | ||
507 | } | ||
508 | |||
509 | m_scene.CrossPrimGroupIntoNewRegion(val, this, true); | ||
510 | |||
511 | // Normalize | ||
512 | if (val.X >= Constants.RegionSize) | ||
513 | val.X -= Constants.RegionSize; | ||
514 | if (val.Y >= Constants.RegionSize) | ||
515 | val.Y -= Constants.RegionSize; | ||
516 | if (val.X < 0) | ||
517 | val.X += Constants.RegionSize; | ||
518 | if (val.Y < 0) | ||
519 | val.Y += Constants.RegionSize; | ||
520 | |||
521 | // If it's deleted, crossing was successful | ||
522 | if (IsDeleted) | ||
523 | { | ||
524 | foreach (ScenePresence av in m_linkedAvatars) | ||
525 | { | ||
526 | m_log.DebugFormat("[SCENE OBJECT]: Crossing avatar {0} to {1}", av.Name, val); | ||
527 | |||
528 | av.IsInTransit = true; | ||
529 | |||
530 | CrossAgentToNewRegionDelegate d = entityTransfer.CrossAgentToNewRegionAsync; | ||
531 | d.BeginInvoke(av, val, x, y, destination, av.Flying, version, CrossAgentToNewRegionCompleted, d); | ||
532 | } | ||
533 | |||
534 | return; | ||
535 | } | ||
536 | } | ||
469 | 537 | ||
470 | if (IsDeleted) | ||
471 | return; | ||
472 | val = AbsolutePosition; | 538 | val = AbsolutePosition; |
473 | } | 539 | } |
474 | } | 540 | } |
@@ -528,6 +594,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
528 | } | 594 | } |
529 | } | 595 | } |
530 | 596 | ||
597 | private void CrossAgentToNewRegionCompleted(IAsyncResult iar) | ||
598 | { | ||
599 | CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; | ||
600 | ScenePresence agent = icon.EndInvoke(iar); | ||
601 | |||
602 | //// If the cross was successful, this agent is a child agent | ||
603 | //if (agent.IsChildAgent) | ||
604 | // agent.Reset(); | ||
605 | //else // Not successful | ||
606 | // agent.RestoreInCurrentScene(); | ||
607 | |||
608 | // In any case | ||
609 | agent.IsInTransit = false; | ||
610 | |||
611 | m_log.DebugFormat("[SCENE OBJECT]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); | ||
612 | } | ||
613 | |||
531 | public override uint LocalId | 614 | public override uint LocalId |
532 | { | 615 | { |
533 | get { return m_rootPart.LocalId; } | 616 | get { return m_rootPart.LocalId; } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index c7c90da..e44060c 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -233,6 +233,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
233 | private bool m_collisionEventFlag = false; | 233 | private bool m_collisionEventFlag = false; |
234 | private object m_collisionEventLock = new Object(); | 234 | private object m_collisionEventLock = new Object(); |
235 | 235 | ||
236 | private Vector3 m_prevSitOffset; | ||
237 | |||
236 | protected AvatarAppearance m_appearance; | 238 | protected AvatarAppearance m_appearance; |
237 | 239 | ||
238 | public AvatarAppearance Appearance | 240 | public AvatarAppearance Appearance |
@@ -647,6 +649,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
647 | } | 649 | } |
648 | private uint m_parentID; | 650 | private uint m_parentID; |
649 | 651 | ||
652 | public UUID ParentUUID | ||
653 | { | ||
654 | get { return m_parentUUID; } | ||
655 | set { m_parentUUID = value; } | ||
656 | } | ||
657 | private UUID m_parentUUID = UUID.Zero; | ||
658 | |||
650 | public float Health | 659 | public float Health |
651 | { | 660 | { |
652 | get { return m_health; } | 661 | get { return m_health; } |
@@ -868,7 +877,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
868 | "[SCENE]: Upgrading child to root agent for {0} in {1}", | 877 | "[SCENE]: Upgrading child to root agent for {0} in {1}", |
869 | Name, m_scene.RegionInfo.RegionName); | 878 | Name, m_scene.RegionInfo.RegionName); |
870 | 879 | ||
871 | //m_log.DebugFormat("[SCENE]: known regions in {0}: {1}", Scene.RegionInfo.RegionName, KnownChildRegionHandles.Count); | 880 | if (ParentUUID != UUID.Zero) |
881 | { | ||
882 | m_log.DebugFormat("[SCENE PRESENCE]: Sitting avatar back on prim {0}", ParentUUID); | ||
883 | SceneObjectPart part = m_scene.GetSceneObjectPart(ParentUUID); | ||
884 | if (part == null) | ||
885 | { | ||
886 | m_log.ErrorFormat("[SCENE PRESENCE]: Can't find prim {0} to sit on", ParentUUID); | ||
887 | } | ||
888 | else | ||
889 | { | ||
890 | part.ParentGroup.AddAvatar(UUID); | ||
891 | if (part.SitTargetPosition != Vector3.Zero) | ||
892 | part.SitTargetAvatar = UUID; | ||
893 | ParentPosition = part.GetWorldPosition(); | ||
894 | ParentID = part.LocalId; | ||
895 | m_pos = m_prevSitOffset; | ||
896 | pos = ParentPosition; | ||
897 | } | ||
898 | ParentUUID = UUID.Zero; | ||
899 | } | ||
872 | 900 | ||
873 | bool wasChild = IsChildAgent; | 901 | bool wasChild = IsChildAgent; |
874 | IsChildAgent = false; | 902 | IsChildAgent = false; |
@@ -881,62 +909,64 @@ namespace OpenSim.Region.Framework.Scenes | |||
881 | 909 | ||
882 | m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); | 910 | m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene); |
883 | 911 | ||
884 | // Moved this from SendInitialData to ensure that Appearance is initialized | 912 | if (ParentID == 0) |
885 | // before the inventory is processed in MakeRootAgent. This fixes a race condition | ||
886 | // related to the handling of attachments | ||
887 | //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); | ||
888 | if (m_scene.TestBorderCross(pos, Cardinals.E)) | ||
889 | { | 913 | { |
890 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); | 914 | // Moved this from SendInitialData to ensure that Appearance is initialized |
891 | pos.X = crossedBorder.BorderLine.Z - 1; | 915 | // before the inventory is processed in MakeRootAgent. This fixes a race condition |
892 | } | 916 | // related to the handling of attachments |
917 | //m_scene.GetAvatarAppearance(ControllingClient, out Appearance); | ||
918 | if (m_scene.TestBorderCross(pos, Cardinals.E)) | ||
919 | { | ||
920 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.E); | ||
921 | pos.X = crossedBorder.BorderLine.Z - 1; | ||
922 | } | ||
893 | 923 | ||
894 | if (m_scene.TestBorderCross(pos, Cardinals.N)) | 924 | if (m_scene.TestBorderCross(pos, Cardinals.N)) |
895 | { | 925 | { |
896 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); | 926 | Border crossedBorder = m_scene.GetCrossedBorder(pos, Cardinals.N); |
897 | pos.Y = crossedBorder.BorderLine.Z - 1; | 927 | pos.Y = crossedBorder.BorderLine.Z - 1; |
898 | } | 928 | } |
899 | 929 | ||
900 | CheckAndAdjustLandingPoint(ref pos); | 930 | CheckAndAdjustLandingPoint(ref pos); |
901 | 931 | ||
902 | if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) | 932 | if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) |
903 | { | 933 | { |
904 | m_log.WarnFormat( | 934 | m_log.WarnFormat( |
905 | "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", | 935 | "[SCENE PRESENCE]: MakeRootAgent() was given an illegal position of {0} for avatar {1}, {2}. Clamping", |
906 | pos, Name, UUID); | 936 | pos, Name, UUID); |
907 | 937 | ||
908 | if (pos.X < 0f) pos.X = 0f; | 938 | if (pos.X < 0f) pos.X = 0f; |
909 | if (pos.Y < 0f) pos.Y = 0f; | 939 | if (pos.Y < 0f) pos.Y = 0f; |
910 | if (pos.Z < 0f) pos.Z = 0f; | 940 | if (pos.Z < 0f) pos.Z = 0f; |
911 | } | 941 | } |
912 | 942 | ||
913 | float localAVHeight = 1.56f; | 943 | float localAVHeight = 1.56f; |
914 | if (Appearance.AvatarHeight > 0) | 944 | if (Appearance.AvatarHeight > 0) |
915 | localAVHeight = Appearance.AvatarHeight; | 945 | localAVHeight = Appearance.AvatarHeight; |
916 | 946 | ||
917 | float posZLimit = 0; | 947 | float posZLimit = 0; |
918 | 948 | ||
919 | if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) | 949 | if (pos.X < Constants.RegionSize && pos.Y < Constants.RegionSize) |
920 | posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; | 950 | posZLimit = (float)m_scene.Heightmap[(int)pos.X, (int)pos.Y]; |
921 | 951 | ||
922 | float newPosZ = posZLimit + localAVHeight / 2; | 952 | float newPosZ = posZLimit + localAVHeight / 2; |
923 | if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) | 953 | if (posZLimit >= (pos.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) |
924 | { | 954 | { |
925 | pos.Z = newPosZ; | 955 | pos.Z = newPosZ; |
926 | } | 956 | } |
927 | AbsolutePosition = pos; | 957 | AbsolutePosition = pos; |
928 | 958 | ||
929 | AddToPhysicalScene(isFlying); | 959 | AddToPhysicalScene(isFlying); |
930 | 960 | ||
931 | if (ForceFly) | 961 | if (ForceFly) |
932 | { | 962 | { |
933 | Flying = true; | 963 | Flying = true; |
934 | } | 964 | } |
935 | else if (FlyDisabled) | 965 | else if (FlyDisabled) |
936 | { | 966 | { |
937 | Flying = false; | 967 | Flying = false; |
968 | } | ||
938 | } | 969 | } |
939 | |||
940 | // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying | 970 | // Don't send an animation pack here, since on a region crossing this will sometimes cause a flying |
941 | // avatar to return to the standing position in mid-air. On login it looks like this is being sent | 971 | // avatar to return to the standing position in mid-air. On login it looks like this is being sent |
942 | // elsewhere anyway | 972 | // elsewhere anyway |
@@ -954,11 +984,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
954 | { | 984 | { |
955 | m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); | 985 | m_log.DebugFormat("[SCENE PRESENCE]: Restarting scripts in attachments..."); |
956 | // Resume scripts | 986 | // Resume scripts |
957 | foreach (SceneObjectGroup sog in m_attachments) | 987 | Util.FireAndForget(delegate(object x) { |
958 | { | 988 | foreach (SceneObjectGroup sog in m_attachments) |
959 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | 989 | { |
960 | sog.ResumeScripts(); | 990 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); |
961 | } | 991 | sog.ResumeScripts(); |
992 | } | ||
993 | }); | ||
962 | } | 994 | } |
963 | } | 995 | } |
964 | 996 | ||
@@ -3112,6 +3144,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3112 | cAgent.AlwaysRun = SetAlwaysRun; | 3144 | cAgent.AlwaysRun = SetAlwaysRun; |
3113 | 3145 | ||
3114 | cAgent.Appearance = new AvatarAppearance(Appearance); | 3146 | cAgent.Appearance = new AvatarAppearance(Appearance); |
3147 | |||
3148 | cAgent.ParentPart = ParentUUID; | ||
3149 | cAgent.SitOffset = m_pos; | ||
3115 | 3150 | ||
3116 | lock (scriptedcontrols) | 3151 | lock (scriptedcontrols) |
3117 | { | 3152 | { |
@@ -3171,6 +3206,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3171 | CameraAtAxis = cAgent.AtAxis; | 3206 | CameraAtAxis = cAgent.AtAxis; |
3172 | CameraLeftAxis = cAgent.LeftAxis; | 3207 | CameraLeftAxis = cAgent.LeftAxis; |
3173 | m_CameraUpAxis = cAgent.UpAxis; | 3208 | m_CameraUpAxis = cAgent.UpAxis; |
3209 | ParentUUID = cAgent.ParentPart; | ||
3210 | m_prevSitOffset = cAgent.SitOffset; | ||
3174 | 3211 | ||
3175 | // When we get to the point of re-computing neighbors everytime this | 3212 | // When we get to the point of re-computing neighbors everytime this |
3176 | // changes, then start using the agent's drawdistance rather than the | 3213 | // changes, then start using the agent's drawdistance rather than the |