aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPart.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs282
1 files changed, 163 insertions, 119 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 39b109b..f0740f8 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -60,7 +60,8 @@ namespace OpenSim.Region.Framework.Scenes
60 TELEPORT = 512, 60 TELEPORT = 512,
61 REGION_RESTART = 1024, 61 REGION_RESTART = 1024,
62 MEDIA = 2048, 62 MEDIA = 2048,
63 ANIMATION = 16384 63 ANIMATION = 16384,
64 POSITION = 32768
64 } 65 }
65 66
66 // I don't really know where to put this except here. 67 // I don't really know where to put this except here.
@@ -149,8 +150,8 @@ namespace OpenSim.Region.Framework.Scenes
149 150
150 // TODO: This needs to be persisted in next XML version update! 151 // TODO: This needs to be persisted in next XML version update!
151 [XmlIgnore] 152 [XmlIgnore]
152 public readonly int[] PayPrice = {-2,-2,-2,-2,-2}; 153 public int[] PayPrice = {-2,-2,-2,-2,-2};
153 154
154 [XmlIgnore] 155 [XmlIgnore]
155 public PhysicsActor PhysActor 156 public PhysicsActor PhysActor
156 { 157 {
@@ -193,6 +194,14 @@ namespace OpenSim.Region.Framework.Scenes
193 [XmlIgnore] 194 [XmlIgnore]
194 public UUID FromFolderID; 195 public UUID FromFolderID;
195 196
197 // The following two are to hold the attachment data
198 // while an object is inworld
199 [XmlIgnore]
200 public byte AttachPoint = 0;
201
202 [XmlIgnore]
203 public Vector3 AttachOffset = Vector3.Zero;
204
196 [XmlIgnore] 205 [XmlIgnore]
197 public int STATUS_ROTATE_X; 206 public int STATUS_ROTATE_X;
198 207
@@ -288,6 +297,7 @@ namespace OpenSim.Region.Framework.Scenes
288 private Quaternion m_sitTargetOrientation = Quaternion.Identity; 297 private Quaternion m_sitTargetOrientation = Quaternion.Identity;
289 private Vector3 m_sitTargetPosition; 298 private Vector3 m_sitTargetPosition;
290 private string m_sitAnimation = "SIT"; 299 private string m_sitAnimation = "SIT";
300 private bool m_occupied; // KF if any av is sitting on this prim
291 private string m_text = String.Empty; 301 private string m_text = String.Empty;
292 private string m_touchName = String.Empty; 302 private string m_touchName = String.Empty;
293 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5); 303 private readonly UndoStack<UndoState> m_undo = new UndoStack<UndoState>(5);
@@ -377,7 +387,7 @@ namespace OpenSim.Region.Framework.Scenes
377 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 387 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
378 Quaternion rotationOffset, Vector3 offsetPosition) 388 Quaternion rotationOffset, Vector3 offsetPosition)
379 { 389 {
380 m_name = "Primitive"; 390 m_name = "Object";
381 391
382 Rezzed = DateTime.UtcNow; 392 Rezzed = DateTime.UtcNow;
383 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 393 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
@@ -433,7 +443,7 @@ namespace OpenSim.Region.Framework.Scenes
433 private uint _ownerMask = (uint)PermissionMask.All; 443 private uint _ownerMask = (uint)PermissionMask.All;
434 private uint _groupMask = (uint)PermissionMask.None; 444 private uint _groupMask = (uint)PermissionMask.None;
435 private uint _everyoneMask = (uint)PermissionMask.None; 445 private uint _everyoneMask = (uint)PermissionMask.None;
436 private uint _nextOwnerMask = (uint)PermissionMask.All; 446 private uint _nextOwnerMask = (uint)(PermissionMask.Move | PermissionMask.Modify | PermissionMask.Transfer);
437 private PrimFlags _flags = PrimFlags.None; 447 private PrimFlags _flags = PrimFlags.None;
438 private DateTime m_expires; 448 private DateTime m_expires;
439 private DateTime m_rezzed; 449 private DateTime m_rezzed;
@@ -473,12 +483,16 @@ namespace OpenSim.Region.Framework.Scenes
473 } 483 }
474 484
475 /// <value> 485 /// <value>
476 /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes 486 /// Get the inventory list
477 /// </value> 487 /// </value>
478 public TaskInventoryDictionary TaskInventory 488 public TaskInventoryDictionary TaskInventory
479 { 489 {
480 get { return m_inventory.Items; } 490 get {
481 set { m_inventory.Items = value; } 491 return m_inventory.Items;
492 }
493 set {
494 m_inventory.Items = value;
495 }
482 } 496 }
483 497
484 /// <summary> 498 /// <summary>
@@ -618,14 +632,12 @@ namespace OpenSim.Region.Framework.Scenes
618 set { m_LoopSoundSlavePrims = value; } 632 set { m_LoopSoundSlavePrims = value; }
619 } 633 }
620 634
621 [XmlIgnore]
622 public Byte[] TextureAnimation 635 public Byte[] TextureAnimation
623 { 636 {
624 get { return m_TextureAnimation; } 637 get { return m_TextureAnimation; }
625 set { m_TextureAnimation = value; } 638 set { m_TextureAnimation = value; }
626 } 639 }
627 640
628 [XmlIgnore]
629 public Byte[] ParticleSystem 641 public Byte[] ParticleSystem
630 { 642 {
631 get { return m_particleSystem; } 643 get { return m_particleSystem; }
@@ -679,7 +691,6 @@ namespace OpenSim.Region.Framework.Scenes
679 set 691 set
680 { 692 {
681 m_groupPosition = value; 693 m_groupPosition = value;
682
683 PhysicsActor actor = PhysActor; 694 PhysicsActor actor = PhysActor;
684 if (actor != null) 695 if (actor != null)
685 { 696 {
@@ -699,25 +710,13 @@ namespace OpenSim.Region.Framework.Scenes
699 710
700 // Tell the physics engines that this prim changed. 711 // Tell the physics engines that this prim changed.
701 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 712 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
713
702 } 714 }
703 catch (Exception e) 715 catch (Exception e)
704 { 716 {
705 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message); 717 m_log.Error("[SCENEOBJECTPART]: GROUP POSITION. " + e.Message);
706 } 718 }
707 } 719 }
708
709 // TODO if we decide to do sitting in a more SL compatible way (multiple avatars per prim), this has to be fixed, too
710 if (m_sitTargetAvatar != UUID.Zero)
711 {
712 if (m_parentGroup != null) // TODO can there be a SOP without a SOG?
713 {
714 ScenePresence avatar;
715 if (m_parentGroup.Scene.TryGetScenePresence(m_sitTargetAvatar, out avatar))
716 {
717 avatar.ParentPosition = GetWorldPosition();
718 }
719 }
720 }
721 } 720 }
722 } 721 }
723 722
@@ -726,7 +725,8 @@ namespace OpenSim.Region.Framework.Scenes
726 get { return m_offsetPosition; } 725 get { return m_offsetPosition; }
727 set 726 set
728 { 727 {
729 StoreUndoState(); 728 Vector3 oldpos = m_offsetPosition;
729 StoreUndoState(UndoType.STATE_PRIM_POSITION);
730 m_offsetPosition = value; 730 m_offsetPosition = value;
731 731
732 if (ParentGroup != null && !ParentGroup.IsDeleted) 732 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -740,7 +740,22 @@ namespace OpenSim.Region.Framework.Scenes
740 // Tell the physics engines that this prim changed. 740 // Tell the physics engines that this prim changed.
741 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor); 741 m_parentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
742 } 742 }
743
744 if (!m_parentGroup.m_dupeInProgress)
745 {
746 List<ScenePresence> avs = ParentGroup.GetLinkedAvatars();
747 foreach (ScenePresence av in avs)
748 {
749 if (av.LinkedPrim == m_uuid)
750 {
751 Vector3 offset = (m_offsetPosition - oldpos);
752 av.OffsetPosition += offset;
753 av.SendFullUpdateToAllClients();
754 }
755 }
756 }
743 } 757 }
758 TriggerScriptChangedEvent(Changed.POSITION);
744 } 759 }
745 } 760 }
746 761
@@ -782,7 +797,7 @@ namespace OpenSim.Region.Framework.Scenes
782 797
783 set 798 set
784 { 799 {
785 StoreUndoState(); 800 StoreUndoState(UndoType.STATE_PRIM_ROTATION);
786 m_rotationOffset = value; 801 m_rotationOffset = value;
787 802
788 PhysicsActor actor = PhysActor; 803 PhysicsActor actor = PhysActor;
@@ -866,7 +881,16 @@ namespace OpenSim.Region.Framework.Scenes
866 /// <summary></summary> 881 /// <summary></summary>
867 public Vector3 Acceleration 882 public Vector3 Acceleration
868 { 883 {
869 get { return m_acceleration; } 884 get
885 {
886 PhysicsActor actor = PhysActor;
887 if (actor != null)
888 {
889 m_acceleration = actor.Acceleration;
890 }
891 return m_acceleration;
892 }
893
870 set { m_acceleration = value; } 894 set { m_acceleration = value; }
871 } 895 }
872 896
@@ -971,7 +995,7 @@ namespace OpenSim.Region.Framework.Scenes
971 get { return m_shape.Scale; } 995 get { return m_shape.Scale; }
972 set 996 set
973 { 997 {
974 StoreUndoState(); 998 StoreUndoState(UndoType.STATE_PRIM_SCALE);
975 if (m_shape != null) 999 if (m_shape != null)
976 { 1000 {
977 m_shape.Scale = value; 1001 m_shape.Scale = value;
@@ -1041,7 +1065,8 @@ namespace OpenSim.Region.Framework.Scenes
1041 if (IsAttachment) 1065 if (IsAttachment)
1042 return GroupPosition; 1066 return GroupPosition;
1043 1067
1044 return m_offsetPosition + m_groupPosition; } 1068// return m_offsetPosition + m_groupPosition; }
1069 return m_groupPosition + (m_offsetPosition * ParentGroup.RootPart.RotationOffset) ; } //KF: Rotation was ignored!
1045 } 1070 }
1046 1071
1047 public SceneObjectGroup ParentGroup 1072 public SceneObjectGroup ParentGroup
@@ -1200,6 +1225,13 @@ namespace OpenSim.Region.Framework.Scenes
1200 _flags = value; 1225 _flags = value;
1201 } 1226 }
1202 } 1227 }
1228
1229 [XmlIgnore]
1230 public bool IsOccupied // KF If an av is sittingon this prim
1231 {
1232 get { return m_occupied; }
1233 set { m_occupied = value; }
1234 }
1203 1235
1204 [XmlIgnore] 1236 [XmlIgnore]
1205 public UUID SitTargetAvatar 1237 public UUID SitTargetAvatar
@@ -1275,14 +1307,6 @@ namespace OpenSim.Region.Framework.Scenes
1275 } 1307 }
1276 } 1308 }
1277 1309
1278 /// <summary>
1279 /// Clear all pending updates of parts to clients
1280 /// </summary>
1281 private void ClearUpdateSchedule()
1282 {
1283 m_updateFlag = 0;
1284 }
1285
1286 private void SendObjectPropertiesToClient(UUID AgentID) 1310 private void SendObjectPropertiesToClient(UUID AgentID)
1287 { 1311 {
1288 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar) 1312 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence avatar)
@@ -1533,14 +1557,21 @@ namespace OpenSim.Region.Framework.Scenes
1533 // or flexible 1557 // or flexible
1534 if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible)) 1558 if (!isPhantom && !IsAttachment && !(Shape.PathCurve == (byte) Extrusion.Flexible))
1535 { 1559 {
1536 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape( 1560 try
1537 string.Format("{0}/{1}", Name, UUID), 1561 {
1538 Shape, 1562 PhysActor = m_parentGroup.Scene.PhysicsScene.AddPrimShape(
1539 AbsolutePosition, 1563 string.Format("{0}/{1}", Name, UUID),
1540 Scale, 1564 Shape,
1541 RotationOffset, 1565 AbsolutePosition,
1542 RigidBody); 1566 Scale,
1543 1567 RotationOffset,
1568 RigidBody);
1569 }
1570 catch
1571 {
1572 m_log.ErrorFormat("[SCENE]: caught exception meshing object {0}. Object set to phantom.", m_uuid);
1573 PhysActor = null;
1574 }
1544 // Basic Physics returns null.. joy joy joy. 1575 // Basic Physics returns null.. joy joy joy.
1545 if (PhysActor != null) 1576 if (PhysActor != null)
1546 { 1577 {
@@ -1568,7 +1599,7 @@ namespace OpenSim.Region.Framework.Scenes
1568 { 1599 {
1569 m_redo.Clear(); 1600 m_redo.Clear();
1570 } 1601 }
1571 StoreUndoState(); 1602 StoreUndoState(UndoType.STATE_ALL);
1572 } 1603 }
1573 1604
1574 public byte ConvertScriptUintToByte(uint indata) 1605 public byte ConvertScriptUintToByte(uint indata)
@@ -1637,6 +1668,9 @@ namespace OpenSim.Region.Framework.Scenes
1637 1668
1638 // Move afterwards ResetIDs as it clears the localID 1669 // Move afterwards ResetIDs as it clears the localID
1639 dupe.LocalId = localID; 1670 dupe.LocalId = localID;
1671 if(dupe.PhysActor != null)
1672 dupe.PhysActor.LocalID = localID;
1673
1640 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. 1674 // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated.
1641 dupe._lastOwnerID = OwnerID; 1675 dupe._lastOwnerID = OwnerID;
1642 1676
@@ -1680,7 +1714,7 @@ namespace OpenSim.Region.Framework.Scenes
1680 PrimitiveBaseShape shape = PrimitiveBaseShape.Create(); 1714 PrimitiveBaseShape shape = PrimitiveBaseShape.Create();
1681 part.Shape = shape; 1715 part.Shape = shape;
1682 1716
1683 part.Name = "Primitive"; 1717 part.Name = "Object";
1684 part._ownerID = UUID.Random(); 1718 part._ownerID = UUID.Random();
1685 1719
1686 return part; 1720 return part;
@@ -2040,12 +2074,17 @@ namespace OpenSim.Region.Framework.Scenes
2040 public Vector3 GetWorldPosition() 2074 public Vector3 GetWorldPosition()
2041 { 2075 {
2042 Quaternion parentRot = ParentGroup.RootPart.RotationOffset; 2076 Quaternion parentRot = ParentGroup.RootPart.RotationOffset;
2043
2044 Vector3 axPos = OffsetPosition; 2077 Vector3 axPos = OffsetPosition;
2045
2046 axPos *= parentRot; 2078 axPos *= parentRot;
2047 Vector3 translationOffsetPosition = axPos; 2079 Vector3 translationOffsetPosition = axPos;
2048 return GroupPosition + translationOffsetPosition; 2080 if(_parentID == 0)
2081 {
2082 return GroupPosition;
2083 }
2084 else
2085 {
2086 return ParentGroup.AbsolutePosition + translationOffsetPosition; //KF: Fix child prim position
2087 }
2049 } 2088 }
2050 2089
2051 /// <summary> 2090 /// <summary>
@@ -2056,7 +2095,7 @@ namespace OpenSim.Region.Framework.Scenes
2056 { 2095 {
2057 Quaternion newRot; 2096 Quaternion newRot;
2058 2097
2059 if (this.LinkNum == 0) 2098 if (this.LinkNum < 2) //KF Single or root prim
2060 { 2099 {
2061 newRot = RotationOffset; 2100 newRot = RotationOffset;
2062 } 2101 }
@@ -2702,17 +2741,18 @@ namespace OpenSim.Region.Framework.Scenes
2702 //Trys to fetch sound id from prim's inventory. 2741 //Trys to fetch sound id from prim's inventory.
2703 //Prim's inventory doesn't support non script items yet 2742 //Prim's inventory doesn't support non script items yet
2704 2743
2705 lock (TaskInventory) 2744 TaskInventory.LockItemsForRead(true);
2745
2746 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
2706 { 2747 {
2707 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 2748 if (item.Value.Name == sound)
2708 { 2749 {
2709 if (item.Value.Name == sound) 2750 soundID = item.Value.ItemID;
2710 { 2751 break;
2711 soundID = item.Value.ItemID;
2712 break;
2713 }
2714 } 2752 }
2715 } 2753 }
2754
2755 TaskInventory.LockItemsForRead(false);
2716 } 2756 }
2717 2757
2718 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence sp) 2758 m_parentGroup.Scene.ForEachScenePresence(delegate(ScenePresence sp)
@@ -2772,7 +2812,7 @@ namespace OpenSim.Region.Framework.Scenes
2772 /// <param name="scale"></param> 2812 /// <param name="scale"></param>
2773 public void Resize(Vector3 scale) 2813 public void Resize(Vector3 scale)
2774 { 2814 {
2775 StoreUndoState(); 2815 StoreUndoState(UndoType.STATE_PRIM_SCALE);
2776 m_shape.Scale = scale; 2816 m_shape.Scale = scale;
2777 2817
2778 ParentGroup.HasGroupChanged = true; 2818 ParentGroup.HasGroupChanged = true;
@@ -2781,38 +2821,7 @@ namespace OpenSim.Region.Framework.Scenes
2781 2821
2782 public void RotLookAt(Quaternion target, float strength, float damping) 2822 public void RotLookAt(Quaternion target, float strength, float damping)
2783 { 2823 {
2784 rotLookAt(target, strength, damping); 2824 m_parentGroup.rotLookAt(target, strength, damping); // This calls method in SceneObjectGroup.
2785 }
2786
2787 public void rotLookAt(Quaternion target, float strength, float damping)
2788 {
2789 if (IsAttachment)
2790 {
2791 /*
2792 ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar);
2793 if (avatar != null)
2794 {
2795 Rotate the Av?
2796 } */
2797 }
2798 else
2799 {
2800 APIDDamp = damping;
2801 APIDStrength = strength;
2802 APIDTarget = target;
2803 }
2804 }
2805
2806 public void startLookAt(Quaternion rot, float damp, float strength)
2807 {
2808 APIDDamp = damp;
2809 APIDStrength = strength;
2810 APIDTarget = rot;
2811 }
2812
2813 public void stopLookAt()
2814 {
2815 APIDTarget = Quaternion.Identity;
2816 } 2825 }
2817 2826
2818 /// <summary> 2827 /// <summary>
@@ -2824,7 +2833,10 @@ namespace OpenSim.Region.Framework.Scenes
2824 2833
2825 if (m_parentGroup != null) 2834 if (m_parentGroup != null)
2826 { 2835 {
2827 m_parentGroup.QueueForUpdateCheck(); 2836 if (!m_parentGroup.areUpdatesSuspended)
2837 {
2838 m_parentGroup.QueueForUpdateCheck();
2839 }
2828 } 2840 }
2829 2841
2830 int timeNow = Util.UnixTimeSinceEpoch(); 2842 int timeNow = Util.UnixTimeSinceEpoch();
@@ -3041,8 +3053,8 @@ namespace OpenSim.Region.Framework.Scenes
3041 { 3053 {
3042 const float ROTATION_TOLERANCE = 0.01f; 3054 const float ROTATION_TOLERANCE = 0.01f;
3043 const float VELOCITY_TOLERANCE = 0.001f; 3055 const float VELOCITY_TOLERANCE = 0.001f;
3044 const float POSITION_TOLERANCE = 0.05f; 3056 const float POSITION_TOLERANCE = 0.05f; // I don't like this, but I suppose it's necessary
3045 const int TIME_MS_TOLERANCE = 3000; 3057 const int TIME_MS_TOLERANCE = 200; //llSetPos has a 200ms delay. This should NOT be 3 seconds.
3046 3058
3047 if (m_updateFlag == 1) 3059 if (m_updateFlag == 1)
3048 { 3060 {
@@ -3056,7 +3068,7 @@ namespace OpenSim.Region.Framework.Scenes
3056 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE) 3068 Environment.TickCount - m_lastTerseSent > TIME_MS_TOLERANCE)
3057 { 3069 {
3058 AddTerseUpdateToAllAvatars(); 3070 AddTerseUpdateToAllAvatars();
3059 ClearUpdateSchedule(); 3071
3060 3072
3061 // This causes the Scene to 'poll' physical objects every couple of frames 3073 // This causes the Scene to 'poll' physical objects every couple of frames
3062 // bad, so it's been replaced by an event driven method. 3074 // bad, so it's been replaced by an event driven method.
@@ -3074,16 +3086,18 @@ namespace OpenSim.Region.Framework.Scenes
3074 m_lastAngularVelocity = AngularVelocity; 3086 m_lastAngularVelocity = AngularVelocity;
3075 m_lastTerseSent = Environment.TickCount; 3087 m_lastTerseSent = Environment.TickCount;
3076 } 3088 }
3089 //Moved this outside of the if clause so updates don't get blocked.. *sigh*
3090 m_updateFlag = 0; //Why were we calling a function to do this? Inefficient! *screams*
3077 } 3091 }
3078 else 3092 else
3079 { 3093 {
3080 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes 3094 if (m_updateFlag == 2) // is a new prim, just created/reloaded or has major changes
3081 { 3095 {
3082 AddFullUpdateToAllAvatars(); 3096 AddFullUpdateToAllAvatars();
3083 ClearUpdateSchedule(); 3097 m_updateFlag = 0; //Same here
3084 } 3098 }
3085 } 3099 }
3086 ClearUpdateSchedule(); 3100 m_updateFlag = 0;
3087 } 3101 }
3088 3102
3089 /// <summary> 3103 /// <summary>
@@ -3103,6 +3117,15 @@ namespace OpenSim.Region.Framework.Scenes
3103 UUID ownerID = _ownerID; 3117 UUID ownerID = _ownerID;
3104 UUID objectID = ParentGroup.RootPart.UUID; 3118 UUID objectID = ParentGroup.RootPart.UUID;
3105 UUID parentID = GetRootPartUUID(); 3119 UUID parentID = GetRootPartUUID();
3120
3121 if (ParentGroup.IsAttachment && ParentGroup.RootPart.Shape.State > 30)
3122 {
3123 // Use the avatar as the parent for HUDs, since the prims
3124 // are not sent to other avatars
3125 objectID = _ownerID;
3126 parentID = _ownerID;
3127 }
3128
3106 UUID soundID = UUID.Zero; 3129 UUID soundID = UUID.Zero;
3107 Vector3 position = AbsolutePosition; // region local 3130 Vector3 position = AbsolutePosition; // region local
3108 ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle; 3131 ulong regionHandle = m_parentGroup.Scene.RegionInfo.RegionHandle;
@@ -3110,17 +3133,16 @@ namespace OpenSim.Region.Framework.Scenes
3110 if (!UUID.TryParse(sound, out soundID)) 3133 if (!UUID.TryParse(sound, out soundID))
3111 { 3134 {
3112 // search sound file from inventory 3135 // search sound file from inventory
3113 lock (TaskInventory) 3136 TaskInventory.LockItemsForRead(true);
3137 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory)
3114 { 3138 {
3115 foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) 3139 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound)
3116 { 3140 {
3117 if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) 3141 soundID = item.Value.ItemID;
3118 { 3142 break;
3119 soundID = item.Value.ItemID;
3120 break;
3121 }
3122 } 3143 }
3123 } 3144 }
3145 TaskInventory.LockItemsForRead(false);
3124 } 3146 }
3125 3147
3126 if (soundID == UUID.Zero) 3148 if (soundID == UUID.Zero)
@@ -3557,7 +3579,7 @@ namespace OpenSim.Region.Framework.Scenes
3557 3579
3558 public void StopLookAt() 3580 public void StopLookAt()
3559 { 3581 {
3560 m_parentGroup.stopLookAt(); 3582 m_parentGroup.stopLookAt(); // This calls method in SceneObjectGroup.
3561 3583
3562 m_parentGroup.ScheduleGroupForTerseUpdate(); 3584 m_parentGroup.ScheduleGroupForTerseUpdate();
3563 } 3585 }
@@ -3584,10 +3606,9 @@ namespace OpenSim.Region.Framework.Scenes
3584 m_parentGroup.ScheduleGroupForTerseUpdate(); 3606 m_parentGroup.ScheduleGroupForTerseUpdate();
3585 //m_parentGroup.ScheduleGroupForFullUpdate(); 3607 //m_parentGroup.ScheduleGroupForFullUpdate();
3586 } 3608 }
3587 3609 public void StoreUndoState(UndoType type)
3588 public void StoreUndoState()
3589 { 3610 {
3590 if (!Undoing) 3611 if (!Undoing && (m_parentGroup == null || m_parentGroup.RootPart == null || !m_parentGroup.RootPart.Undoing))
3591 { 3612 {
3592 if (!IgnoreUndoUpdate) 3613 if (!IgnoreUndoUpdate)
3593 { 3614 {
@@ -3598,17 +3619,25 @@ namespace OpenSim.Region.Framework.Scenes
3598 if (m_undo.Count > 0) 3619 if (m_undo.Count > 0)
3599 { 3620 {
3600 UndoState last = m_undo.Peek(); 3621 UndoState last = m_undo.Peek();
3601 if (last != null) 3622
3602 {
3603 if (last.Compare(this))
3604 return;
3605 }
3606 } 3623 }
3607 3624
3608 if (m_parentGroup.GetSceneMaxUndo() > 0) 3625 if (m_parentGroup.GetSceneMaxUndo() > 0)
3609 { 3626 {
3610 UndoState nUndo = new UndoState(this); 3627 UndoState lastUndo = m_undo.Peek();
3628
3629 UndoState nUndo = new UndoState(this, type);
3611 3630
3631 if (lastUndo != null)
3632 {
3633 TimeSpan ts = DateTime.Now.Subtract(lastUndo.LastUpdated);
3634 if (ts.TotalMilliseconds < 500)
3635 {
3636 //Delete the last entry since it was less than 500 milliseconds ago
3637 nUndo.Merge(lastUndo);
3638 m_undo.Pop();
3639 }
3640 }
3612 m_undo.Push(nUndo); 3641 m_undo.Push(nUndo);
3613 } 3642 }
3614 3643
@@ -4085,11 +4114,13 @@ namespace OpenSim.Region.Framework.Scenes
4085 if (m_undo.Count > 0) 4114 if (m_undo.Count > 0)
4086 { 4115 {
4087 UndoState nUndo = null; 4116 UndoState nUndo = null;
4117 UndoState goback = m_undo.Pop();
4088 if (m_parentGroup.GetSceneMaxUndo() > 0) 4118 if (m_parentGroup.GetSceneMaxUndo() > 0)
4089 { 4119 {
4090 nUndo = new UndoState(this); 4120 nUndo = new UndoState(this, goback.Type);
4091 } 4121 }
4092 UndoState goback = m_undo.Pop(); 4122
4123
4093 if (goback != null) 4124 if (goback != null)
4094 { 4125 {
4095 goback.PlaybackState(this); 4126 goback.PlaybackState(this);
@@ -4104,13 +4135,13 @@ namespace OpenSim.Region.Framework.Scenes
4104 { 4135 {
4105 lock (m_redo) 4136 lock (m_redo)
4106 { 4137 {
4138 UndoState gofwd = m_redo.Pop();
4107 if (m_parentGroup.GetSceneMaxUndo() > 0) 4139 if (m_parentGroup.GetSceneMaxUndo() > 0)
4108 { 4140 {
4109 UndoState nUndo = new UndoState(this); 4141 UndoState nUndo = new UndoState(this, gofwd.Type);
4110 4142
4111 m_undo.Push(nUndo); 4143 m_undo.Push(nUndo);
4112 } 4144 }
4113 UndoState gofwd = m_redo.Pop();
4114 if (gofwd != null) 4145 if (gofwd != null)
4115 gofwd.PlayfwdState(this); 4146 gofwd.PlayfwdState(this);
4116 } 4147 }
@@ -4558,8 +4589,9 @@ namespace OpenSim.Region.Framework.Scenes
4558 { 4589 {
4559 m_shape.TextureEntry = textureEntry; 4590 m_shape.TextureEntry = textureEntry;
4560 TriggerScriptChangedEvent(Changed.TEXTURE); 4591 TriggerScriptChangedEvent(Changed.TEXTURE);
4561 4592 m_updateFlag = 1;
4562 ParentGroup.HasGroupChanged = true; 4593 ParentGroup.HasGroupChanged = true;
4594
4563 //This is madness.. 4595 //This is madness..
4564 //ParentGroup.ScheduleGroupForFullUpdate(); 4596 //ParentGroup.ScheduleGroupForFullUpdate();
4565 //This is sparta 4597 //This is sparta
@@ -4792,5 +4824,17 @@ namespace OpenSim.Region.Framework.Scenes
4792 Color color = Color; 4824 Color color = Color;
4793 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A)); 4825 return new Color4(color.R, color.G, color.B, (byte)(0xFF - color.A));
4794 } 4826 }
4827
4828 public void ResetOwnerChangeFlag()
4829 {
4830 List<UUID> inv = Inventory.GetInventoryList();
4831
4832 foreach (UUID itemID in inv)
4833 {
4834 TaskInventoryItem item = Inventory.GetInventoryItem(itemID);
4835 item.OwnerChanged = false;
4836 Inventory.UpdateInventoryItem(item);
4837 }
4838 }
4795 } 4839 }
4796} 4840}