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.
Diffstat (limited to '')
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 |