aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMelanie2012-02-14 23:16:20 +0100
committerMelanie2012-02-14 23:16:20 +0100
commit2d3381b795611a8857077d1effb41323c2cb8658 (patch)
treea1b8a6d7832858d14bfb08eac29fcf3e643ef17c
parentPrevent object loss and positioning outside the region with failed object sim (diff)
downloadopensim-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.
-rw-r--r--OpenSim/Framework/ChildAgentDataUpdate.cs11
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs3
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs140
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs89
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs139
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
36namespace OpenSim.Region.Framework.Interfaces 36namespace 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