aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework
diff options
context:
space:
mode:
authorMike Rieker2010-07-06 02:23:10 +0000
committerMike Rieker2010-07-06 02:23:10 +0000
commit6e7f1a3ac11b889175c87f59a3c5361c704363a6 (patch)
tree2ed5bebf54db3adc420e1510045b84b880ecb157 /OpenSim/Region/Framework
parentrewrote hanging llParseStringKeepNulls() (diff)
parentUndo fix is now complete. This commit repairs the special case of the root pr... (diff)
downloadopensim-SC-6e7f1a3ac11b889175c87f59a3c5361c704363a6.zip
opensim-SC-6e7f1a3ac11b889175c87f59a3c5361c704363a6.tar.gz
opensim-SC-6e7f1a3ac11b889175c87f59a3c5361c704363a6.tar.bz2
opensim-SC-6e7f1a3ac11b889175c87f59a3c5361c704363a6.tar.xz
Merge branch 'careminster-presence-refactor' of www.3dhosting.de:/var/git/careminster into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r--OpenSim/Region/Framework/Interfaces/IEmailModule.cs2
-rw-r--r--OpenSim/Region/Framework/Scenes/EventManager.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs64
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs27
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs24
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs138
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs49
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs7
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs4
-rw-r--r--OpenSim/Region/Framework/Scenes/UndoState.cs168
10 files changed, 362 insertions, 145 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs
index 3a2c423..4f1b91a 100644
--- a/OpenSim/Region/Framework/Interfaces/IEmailModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/IEmailModule.cs
@@ -38,7 +38,7 @@ namespace OpenSim.Region.Framework.Interfaces
38 public int numLeft; 38 public int numLeft;
39 } 39 }
40 40
41 public interface IEmailModule : IRegionModule 41 public interface IEmailModule
42 { 42 {
43 void SendEmail(UUID objectID, string address, string subject, string body); 43 void SendEmail(UUID objectID, string address, string subject, string body);
44 Email GetNextEmail(UUID objectID, string sender, string subject); 44 Email GetNextEmail(UUID objectID, string sender, string subject);
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs
index ef125cd..0c9759d 100644
--- a/OpenSim/Region/Framework/Scenes/EventManager.cs
+++ b/OpenSim/Region/Framework/Scenes/EventManager.cs
@@ -55,8 +55,12 @@ namespace OpenSim.Region.Framework.Scenes
55 55
56 public delegate void OnTerrainTickDelegate(); 56 public delegate void OnTerrainTickDelegate();
57 57
58 public delegate void OnTerrainUpdateDelegate();
59
58 public event OnTerrainTickDelegate OnTerrainTick; 60 public event OnTerrainTickDelegate OnTerrainTick;
59 61
62 public event OnTerrainUpdateDelegate OnTerrainUpdate;
63
60 public delegate void OnBackupDelegate(IRegionDataStore datastore, bool forceBackup); 64 public delegate void OnBackupDelegate(IRegionDataStore datastore, bool forceBackup);
61 65
62 public event OnBackupDelegate OnBackup; 66 public event OnBackupDelegate OnBackup;
@@ -716,6 +720,26 @@ namespace OpenSim.Region.Framework.Scenes
716 } 720 }
717 } 721 }
718 } 722 }
723 public void TriggerTerrainUpdate()
724 {
725 OnTerrainUpdateDelegate handlerTerrainUpdate = OnTerrainUpdate;
726 if (handlerTerrainUpdate != null)
727 {
728 foreach (OnTerrainUpdateDelegate d in handlerTerrainUpdate.GetInvocationList())
729 {
730 try
731 {
732 d();
733 }
734 catch (Exception e)
735 {
736 m_log.ErrorFormat(
737 "[EVENT MANAGER]: Delegate for TriggerTerrainUpdate failed - continuing. {0} {1}",
738 e.Message, e.StackTrace);
739 }
740 }
741 }
742 }
719 743
720 public void TriggerTerrainTick() 744 public void TriggerTerrainTick()
721 { 745 {
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 5e1798b..b859042 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -73,7 +73,7 @@ namespace OpenSim.Region.Framework.Scenes
73 IMoneyModule money=RequestModuleInterface<IMoneyModule>(); 73 IMoneyModule money=RequestModuleInterface<IMoneyModule>();
74 if (money != null) 74 if (money != null)
75 { 75 {
76 money.ApplyUploadCharge(agentID); 76 money.ApplyUploadCharge(agentID, money.UploadCharge, "Asset upload");
77 } 77 }
78 78
79 AddInventoryItem(agentID, item); 79 AddInventoryItem(agentID, item);
@@ -400,9 +400,9 @@ namespace OpenSim.Region.Framework.Scenes
400 if (Permissions.PropagatePermissions() && recipient != senderId) 400 if (Permissions.PropagatePermissions() && recipient != senderId)
401 { 401 {
402 // First, make sore base is limited to the next perms 402 // First, make sore base is limited to the next perms
403 itemCopy.BasePermissions = item.BasePermissions & item.NextPermissions; 403 itemCopy.BasePermissions = item.BasePermissions & (item.NextPermissions | (uint)PermissionMask.Move);
404 // By default, current equals base 404 // By default, current equals base
405 itemCopy.CurrentPermissions = itemCopy.BasePermissions; 405 itemCopy.CurrentPermissions = itemCopy.BasePermissions & item.CurrentPermissions;
406 406
407 // If this is an object, replace current perms 407 // If this is an object, replace current perms
408 // with folded perms 408 // with folded perms
@@ -413,7 +413,7 @@ namespace OpenSim.Region.Framework.Scenes
413 } 413 }
414 414
415 // Ensure there is no escalation 415 // Ensure there is no escalation
416 itemCopy.CurrentPermissions &= item.NextPermissions; 416 itemCopy.CurrentPermissions &= (item.NextPermissions | (uint)PermissionMask.Move);
417 417
418 // Need slam bit on xfer 418 // Need slam bit on xfer
419 itemCopy.CurrentPermissions |= 8; 419 itemCopy.CurrentPermissions |= 8;
@@ -916,14 +916,15 @@ namespace OpenSim.Region.Framework.Scenes
916 916
917 if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions()) 917 if ((part.OwnerID != destAgent) && Permissions.PropagatePermissions())
918 { 918 {
919 agentItem.BasePermissions = taskItem.BasePermissions & taskItem.NextPermissions; 919 agentItem.BasePermissions = taskItem.BasePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
920 if (taskItem.InvType == (int)InventoryType.Object) 920 if (taskItem.InvType == (int)InventoryType.Object)
921 agentItem.CurrentPermissions = agentItem.BasePermissions & ((taskItem.CurrentPermissions & 7) << 13); 921 agentItem.CurrentPermissions = agentItem.BasePermissions & (((taskItem.CurrentPermissions & 7) << 13) | (taskItem.CurrentPermissions & (uint)PermissionMask.Move));
922 agentItem.CurrentPermissions = agentItem.BasePermissions ; 922 else
923 agentItem.CurrentPermissions = agentItem.BasePermissions & taskItem.CurrentPermissions;
923 924
924 agentItem.CurrentPermissions |= 8; 925 agentItem.CurrentPermissions |= 8;
925 agentItem.NextPermissions = taskItem.NextPermissions; 926 agentItem.NextPermissions = taskItem.NextPermissions;
926 agentItem.EveryOnePermissions = taskItem.EveryonePermissions & taskItem.NextPermissions; 927 agentItem.EveryOnePermissions = taskItem.EveryonePermissions & (taskItem.NextPermissions | (uint)PermissionMask.Move);
927 agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions; 928 agentItem.GroupPermissions = taskItem.GroupPermissions & taskItem.NextPermissions;
928 } 929 }
929 else 930 else
@@ -1105,13 +1106,13 @@ namespace OpenSim.Region.Framework.Scenes
1105 if (Permissions.PropagatePermissions()) 1106 if (Permissions.PropagatePermissions())
1106 { 1107 {
1107 destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions & 1108 destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions &
1108 srcTaskItem.NextPermissions; 1109 (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
1109 destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions & 1110 destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions &
1110 srcTaskItem.NextPermissions; 1111 (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
1111 destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions & 1112 destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions &
1112 srcTaskItem.NextPermissions; 1113 (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
1113 destTaskItem.BasePermissions = srcTaskItem.BasePermissions & 1114 destTaskItem.BasePermissions = srcTaskItem.BasePermissions &
1114 srcTaskItem.NextPermissions; 1115 (srcTaskItem.NextPermissions | (uint)PermissionMask.Move);
1115 destTaskItem.CurrentPermissions |= 8; // Slam! 1116 destTaskItem.CurrentPermissions |= 8; // Slam!
1116 } 1117 }
1117 } 1118 }
@@ -1284,7 +1285,7 @@ namespace OpenSim.Region.Framework.Scenes
1284 } 1285 }
1285 if (part.Inventory.UpdateInventoryItem(itemInfo)) 1286 if (part.Inventory.UpdateInventoryItem(itemInfo))
1286 { 1287 {
1287 remoteClient.SendAgentAlertMessage("Notecard saved", false); 1288 // remoteClient.SendAgentAlertMessage("Notecard saved", false);
1288 part.GetProperties(remoteClient); 1289 part.GetProperties(remoteClient);
1289 } 1290 }
1290 } 1291 }
@@ -1377,7 +1378,7 @@ namespace OpenSim.Region.Framework.Scenes
1377 return; 1378 return;
1378 1379
1379 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, 1380 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType,
1380 Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"), 1381 Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n\n touch_start(integer num)\n {\n }\n}"),
1381 remoteClient.AgentId); 1382 remoteClient.AgentId);
1382 AssetService.Store(asset); 1383 AssetService.Store(asset);
1383 1384
@@ -1592,18 +1593,36 @@ namespace OpenSim.Region.Framework.Scenes
1592 // for when deleting the object from it 1593 // for when deleting the object from it
1593 ForceSceneObjectBackup(grp); 1594 ForceSceneObjectBackup(grp);
1594 1595
1595 if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) 1596 if (remoteClient == null)
1596 permissionToTakeCopy = false; 1597 {
1597 if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) 1598 // Autoreturn has a null client. Nothing else does. So
1598 permissionToTake = false; 1599 // allow only returns
1600 if (action != DeRezAction.Return)
1601 return;
1599 1602
1600 if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) 1603 permissionToTakeCopy = false;
1601 permissionToDelete = false; 1604 }
1605 else
1606 {
1607 if (action == DeRezAction.TakeCopy)
1608 {
1609 if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId))
1610 permissionToTakeCopy = false;
1611 }
1612 else
1613 {
1614 permissionToTakeCopy = false;
1615 }
1616 if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId))
1617 permissionToTake = false;
1602 1618
1619 if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId))
1620 permissionToDelete = false;
1621 }
1603 } 1622 }
1604 1623
1605 // Handle god perms 1624 // Handle god perms
1606 if (Permissions.IsGod(remoteClient.AgentId)) 1625 if (remoteClient != null && Permissions.IsGod(remoteClient.AgentId))
1607 { 1626 {
1608 permissionToTake = true; 1627 permissionToTake = true;
1609 permissionToTakeCopy = true; 1628 permissionToTakeCopy = true;
@@ -1614,7 +1633,7 @@ namespace OpenSim.Region.Framework.Scenes
1614 if (action == DeRezAction.SaveToExistingUserInventoryItem) 1633 if (action == DeRezAction.SaveToExistingUserInventoryItem)
1615 permissionToDelete = false; 1634 permissionToDelete = false;
1616 1635
1617 // if we want to take a copy,, we also don't want to delete 1636 // if we want to take a copy, we also don't want to delete
1618 // Note: after this point, the permissionToTakeCopy flag 1637 // Note: after this point, the permissionToTakeCopy flag
1619 // becomes irrelevant. It already includes the permissionToTake 1638 // becomes irrelevant. It already includes the permissionToTake
1620 // permission and after excluding no copy items here, we can 1639 // permission and after excluding no copy items here, we can
@@ -1625,6 +1644,7 @@ namespace OpenSim.Region.Framework.Scenes
1625 if (!permissionToTakeCopy) 1644 if (!permissionToTakeCopy)
1626 return; 1645 return;
1627 1646
1647 permissionToTake = true;
1628 // Don't delete 1648 // Don't delete
1629 permissionToDelete = false; 1649 permissionToDelete = false;
1630 } 1650 }
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index dc58d84..c5fb198 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -1770,6 +1770,7 @@ namespace OpenSim.Region.Framework.Scenes
1770 public void StoreWindlightProfile(RegionLightShareData wl) 1770 public void StoreWindlightProfile(RegionLightShareData wl)
1771 { 1771 {
1772 m_regInfo.WindlightSettings = wl; 1772 m_regInfo.WindlightSettings = wl;
1773 wl.Save();
1773 m_storageManager.DataStore.StoreRegionWindlightSettings(wl); 1774 m_storageManager.DataStore.StoreRegionWindlightSettings(wl);
1774 m_eventManager.TriggerOnSaveNewWindlightProfile(); 1775 m_eventManager.TriggerOnSaveNewWindlightProfile();
1775 } 1776 }
@@ -2183,6 +2184,15 @@ namespace OpenSim.Region.Framework.Scenes
2183 /// </summary> 2184 /// </summary>
2184 public void DeleteAllSceneObjects() 2185 public void DeleteAllSceneObjects()
2185 { 2186 {
2187 DeleteAllSceneObjects(false);
2188 }
2189
2190 /// <summary>
2191 /// Delete every object from the scene. This does not include attachments worn by avatars.
2192 /// </summary>
2193 public void DeleteAllSceneObjects(bool exceptNoCopy)
2194 {
2195 List<SceneObjectGroup> toReturn = new List<SceneObjectGroup>();
2186 lock (Entities) 2196 lock (Entities)
2187 { 2197 {
2188 ICollection<EntityBase> entities = new List<EntityBase>(Entities); 2198 ICollection<EntityBase> entities = new List<EntityBase>(Entities);
@@ -2192,11 +2202,24 @@ namespace OpenSim.Region.Framework.Scenes
2192 if (e is SceneObjectGroup) 2202 if (e is SceneObjectGroup)
2193 { 2203 {
2194 SceneObjectGroup sog = (SceneObjectGroup)e; 2204 SceneObjectGroup sog = (SceneObjectGroup)e;
2195 if (!sog.IsAttachment) 2205 if (sog != null && !sog.IsAttachment)
2196 DeleteSceneObject((SceneObjectGroup)e, false); 2206 {
2207 if (!exceptNoCopy || ((sog.GetEffectivePermissions() & (uint)PermissionMask.Copy) != 0))
2208 {
2209 DeleteSceneObject((SceneObjectGroup)e, false);
2210 }
2211 else
2212 {
2213 toReturn.Add((SceneObjectGroup)e);
2214 }
2215 }
2197 } 2216 }
2198 } 2217 }
2199 } 2218 }
2219 if (toReturn.Count > 0)
2220 {
2221 returnObjects(toReturn.ToArray(), UUID.Zero);
2222 }
2200 } 2223 }
2201 2224
2202 /// <summary> 2225 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 81ef54f..a36800b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1848,9 +1848,31 @@ namespace OpenSim.Region.Framework.Scenes
1848 { 1848 {
1849 if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition)) 1849 if (m_parentScene.Permissions.CanDuplicateObject(original.Children.Count, original.UUID, AgentID, original.AbsolutePosition))
1850 { 1850 {
1851 SceneObjectGroup copy = original.Copy(AgentID, GroupID, true); 1851 SceneObjectGroup copy = original.Copy(true);
1852 copy.AbsolutePosition = copy.AbsolutePosition + offset; 1852 copy.AbsolutePosition = copy.AbsolutePosition + offset;
1853 1853
1854 if (original.OwnerID != AgentID)
1855 {
1856 copy.SetOwnerId(AgentID);
1857 copy.SetRootPartOwner(copy.RootPart, AgentID, GroupID);
1858
1859 List<SceneObjectPart> partList =
1860 new List<SceneObjectPart>(copy.Children.Values);
1861
1862 if (m_parentScene.Permissions.PropagatePermissions())
1863 {
1864 foreach (SceneObjectPart child in partList)
1865 {
1866 child.Inventory.ChangeInventoryOwner(AgentID);
1867 child.TriggerScriptChangedEvent(Changed.OWNER);
1868 child.ApplyNextOwnerPermissions();
1869 }
1870 }
1871
1872 copy.RootPart.ObjectSaleType = 0;
1873 copy.RootPart.SalePrice = 10;
1874 }
1875
1854 Entities.Add(copy); 1876 Entities.Add(copy);
1855 1877
1856 // Since we copy from a source group that is in selected 1878 // Since we copy from a source group that is in selected
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 7081ced..f85d3d9 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -349,7 +349,21 @@ namespace OpenSim.Region.Framework.Scenes
349 public virtual Quaternion Rotation 349 public virtual Quaternion Rotation
350 { 350 {
351 get { return m_rotation; } 351 get { return m_rotation; }
352 set { m_rotation = value; } 352 set {
353 lockPartsForRead(true);
354 try
355 {
356 foreach(SceneObjectPart p in m_parts.Values)
357 {
358 p.StoreUndoState(UndoType.STATE_GROUP_ROTATION);
359 }
360 }
361 finally
362 {
363 lockPartsForRead(false);
364 }
365 m_rotation = value;
366 }
353 } 367 }
354 368
355 public Quaternion GroupRotation 369 public Quaternion GroupRotation
@@ -431,7 +445,10 @@ namespace OpenSim.Region.Framework.Scenes
431 } 445 }
432 446
433 lockPartsForRead(true); 447 lockPartsForRead(true);
434 448 foreach (SceneObjectPart part in m_parts.Values)
449 {
450 part.IgnoreUndoUpdate = true;
451 }
435 if (RootPart.GetStatusSandbox()) 452 if (RootPart.GetStatusSandbox())
436 { 453 {
437 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10) 454 if (Util.GetDistanceTo(RootPart.StatusSandboxPos, value) > 10)
@@ -443,12 +460,12 @@ namespace OpenSim.Region.Framework.Scenes
443 return; 460 return;
444 } 461 }
445 } 462 }
446
447 foreach (SceneObjectPart part in m_parts.Values) 463 foreach (SceneObjectPart part in m_parts.Values)
448 { 464 {
465 part.IgnoreUndoUpdate = false;
466 part.StoreUndoState(UndoType.STATE_GROUP_POSITION);
449 part.GroupPosition = val; 467 part.GroupPosition = val;
450 } 468 }
451
452 lockPartsForRead(false); 469 lockPartsForRead(false);
453 470
454 //if (m_rootPart.PhysActor != null) 471 //if (m_rootPart.PhysActor != null)
@@ -724,7 +741,6 @@ namespace OpenSim.Region.Framework.Scenes
724 { 741 {
725 foreach (SceneObjectPart part in m_parts.Values) 742 foreach (SceneObjectPart part in m_parts.Values)
726 { 743 {
727
728 Vector3 partscale = part.Scale; 744 Vector3 partscale = part.Scale;
729 Vector3 partoffset = part.OffsetPosition; 745 Vector3 partoffset = part.OffsetPosition;
730 746
@@ -1471,7 +1487,7 @@ namespace OpenSim.Region.Framework.Scenes
1471 1487
1472 public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) 1488 public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient)
1473 { 1489 {
1474 part.StoreUndoState(); 1490 part.StoreUndoState(UndoType.STATE_PRIM_ALL);
1475 part.OnGrab(offsetPos, remoteClient); 1491 part.OnGrab(offsetPos, remoteClient);
1476 } 1492 }
1477 1493
@@ -1700,7 +1716,7 @@ namespace OpenSim.Region.Framework.Scenes
1700 "[SCENE]: Storing {0}, {1} in {2}", 1716 "[SCENE]: Storing {0}, {1} in {2}",
1701 Name, UUID, m_scene.RegionInfo.RegionName); 1717 Name, UUID, m_scene.RegionInfo.RegionName);
1702 1718
1703 SceneObjectGroup backup_group = Copy(OwnerID, GroupID, false); 1719 SceneObjectGroup backup_group = Copy(false);
1704 backup_group.RootPart.Velocity = RootPart.Velocity; 1720 backup_group.RootPart.Velocity = RootPart.Velocity;
1705 backup_group.RootPart.Acceleration = RootPart.Acceleration; 1721 backup_group.RootPart.Acceleration = RootPart.Acceleration;
1706 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity; 1722 backup_group.RootPart.AngularVelocity = RootPart.AngularVelocity;
@@ -1758,7 +1774,7 @@ namespace OpenSim.Region.Framework.Scenes
1758 /// Duplicates this object, including operations such as physics set up and attaching to the backup event. 1774 /// Duplicates this object, including operations such as physics set up and attaching to the backup event.
1759 /// </summary> 1775 /// </summary>
1760 /// <returns></returns> 1776 /// <returns></returns>
1761 public SceneObjectGroup Copy(UUID cAgentID, UUID cGroupID, bool userExposed) 1777 public SceneObjectGroup Copy(bool userExposed)
1762 { 1778 {
1763 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); 1779 SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone();
1764 dupe.m_isBackedUp = false; 1780 dupe.m_isBackedUp = false;
@@ -1781,7 +1797,9 @@ namespace OpenSim.Region.Framework.Scenes
1781 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); 1797 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
1782 1798
1783 if (!userExposed) 1799 if (!userExposed)
1800 {
1784 dupe.RootPart.IsAttachment = previousAttachmentStatus; 1801 dupe.RootPart.IsAttachment = previousAttachmentStatus;
1802 }
1785 1803
1786 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); 1804 dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed);
1787 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; 1805 dupe.m_rootPart.LinkNum = m_rootPart.LinkNum;
@@ -1806,16 +1824,6 @@ namespace OpenSim.Region.Framework.Scenes
1806 dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true); 1824 dupe.RootPart.DoPhysicsPropertyUpdate(dupe.RootPart.PhysActor.IsPhysical, true);
1807 } 1825 }
1808 1826
1809 // Now we've made a copy that replaces this one, we need to
1810 // switch the owner to the person who did the copying
1811 // Second Life copies an object and duplicates the first one in it's place
1812 // So, we have to make a copy of this one, set it in it's place then set the owner on this one
1813 if (userExposed)
1814 {
1815 SetRootPartOwner(m_rootPart, cAgentID, cGroupID);
1816 m_rootPart.ScheduleFullUpdate();
1817 }
1818
1819 List<SceneObjectPart> partList; 1827 List<SceneObjectPart> partList;
1820 1828
1821 lockPartsForRead(true); 1829 lockPartsForRead(true);
@@ -1837,12 +1845,6 @@ namespace OpenSim.Region.Framework.Scenes
1837 SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); 1845 SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed);
1838 1846
1839 newPart.LinkNum = part.LinkNum; 1847 newPart.LinkNum = part.LinkNum;
1840
1841 if (userExposed)
1842 {
1843 SetPartOwner(newPart, cAgentID, cGroupID);
1844 newPart.ScheduleFullUpdate();
1845 }
1846 } 1848 }
1847 } 1849 }
1848 1850
@@ -3146,7 +3148,6 @@ namespace OpenSim.Region.Framework.Scenes
3146 SceneObjectPart part = GetChildPart(localID); 3148 SceneObjectPart part = GetChildPart(localID);
3147 if (part != null) 3149 if (part != null)
3148 { 3150 {
3149 part.IgnoreUndoUpdate = true;
3150 if (scale.X > m_scene.m_maxNonphys) 3151 if (scale.X > m_scene.m_maxNonphys)
3151 scale.X = m_scene.m_maxNonphys; 3152 scale.X = m_scene.m_maxNonphys;
3152 if (scale.Y > m_scene.m_maxNonphys) 3153 if (scale.Y > m_scene.m_maxNonphys)
@@ -3232,8 +3233,7 @@ namespace OpenSim.Region.Framework.Scenes
3232 y *= a; 3233 y *= a;
3233 z *= a; 3234 z *= a;
3234 } 3235 }
3235 obPart.IgnoreUndoUpdate = false; 3236
3236 obPart.StoreUndoState();
3237 } 3237 }
3238 } 3238 }
3239 } 3239 }
@@ -3243,16 +3243,24 @@ namespace OpenSim.Region.Framework.Scenes
3243 Vector3 prevScale = part.Scale; 3243 Vector3 prevScale = part.Scale;
3244 prevScale.X *= x; 3244 prevScale.X *= x;
3245 prevScale.Y *= y; 3245 prevScale.Y *= y;
3246 prevScale.Z *= z; 3246 prevScale.Z *= z;;
3247
3248 part.IgnoreUndoUpdate = false;
3249 part.StoreUndoState(UndoType.STATE_GROUP_SCALE);
3250 part.IgnoreUndoUpdate = true;
3247 part.Resize(prevScale); 3251 part.Resize(prevScale);
3252 part.IgnoreUndoUpdate = false;
3248 3253
3249 lockPartsForRead(true); 3254 lockPartsForRead(true);
3250 { 3255 {
3251 foreach (SceneObjectPart obPart in m_parts.Values) 3256 foreach (SceneObjectPart obPart in m_parts.Values)
3252 { 3257 {
3253 obPart.IgnoreUndoUpdate = true;
3254 if (obPart.UUID != m_rootPart.UUID) 3258 if (obPart.UUID != m_rootPart.UUID)
3255 { 3259 {
3260 obPart.IgnoreUndoUpdate = false;
3261 obPart.StoreUndoState(UndoType.STATE_GROUP_SCALE);
3262 obPart.IgnoreUndoUpdate = true;
3263
3256 Vector3 currentpos = new Vector3(obPart.OffsetPosition); 3264 Vector3 currentpos = new Vector3(obPart.OffsetPosition);
3257 currentpos.X *= x; 3265 currentpos.X *= x;
3258 currentpos.Y *= y; 3266 currentpos.Y *= y;
@@ -3265,7 +3273,6 @@ namespace OpenSim.Region.Framework.Scenes
3265 obPart.UpdateOffSet(currentpos); 3273 obPart.UpdateOffSet(currentpos);
3266 } 3274 }
3267 obPart.IgnoreUndoUpdate = false; 3275 obPart.IgnoreUndoUpdate = false;
3268 obPart.StoreUndoState();
3269 } 3276 }
3270 } 3277 }
3271 lockPartsForRead(false); 3278 lockPartsForRead(false);
@@ -3277,7 +3284,6 @@ namespace OpenSim.Region.Framework.Scenes
3277 } 3284 }
3278 3285
3279 part.IgnoreUndoUpdate = false; 3286 part.IgnoreUndoUpdate = false;
3280 part.StoreUndoState();
3281 HasGroupChanged = true; 3287 HasGroupChanged = true;
3282 ScheduleGroupForTerseUpdate(); 3288 ScheduleGroupForTerseUpdate();
3283 } 3289 }
@@ -3293,14 +3299,11 @@ namespace OpenSim.Region.Framework.Scenes
3293 /// <param name="pos"></param> 3299 /// <param name="pos"></param>
3294 public void UpdateGroupPosition(Vector3 pos) 3300 public void UpdateGroupPosition(Vector3 pos)
3295 { 3301 {
3296 foreach (SceneObjectPart part in Children.Values)
3297 {
3298 part.StoreUndoState();
3299 }
3300 if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) 3302 if (m_scene.EventManager.TriggerGroupMove(UUID, pos))
3301 { 3303 {
3302 if (IsAttachment) 3304 if (IsAttachment)
3303 { 3305 {
3306 m_rootPart.StoreUndoState(UndoType.STATE_GROUP_POSITION);
3304 m_rootPart.AttachedPos = pos; 3307 m_rootPart.AttachedPos = pos;
3305 } 3308 }
3306 if (RootPart.GetStatusSandbox()) 3309 if (RootPart.GetStatusSandbox())
@@ -3333,7 +3336,7 @@ namespace OpenSim.Region.Framework.Scenes
3333 SceneObjectPart part = GetChildPart(localID); 3336 SceneObjectPart part = GetChildPart(localID);
3334 foreach (SceneObjectPart parts in Children.Values) 3337 foreach (SceneObjectPart parts in Children.Values)
3335 { 3338 {
3336 parts.StoreUndoState(); 3339 parts.StoreUndoState(UndoType.STATE_PRIM_POSITION);
3337 } 3340 }
3338 if (part != null) 3341 if (part != null)
3339 { 3342 {
@@ -3358,7 +3361,7 @@ namespace OpenSim.Region.Framework.Scenes
3358 { 3361 {
3359 foreach (SceneObjectPart part in Children.Values) 3362 foreach (SceneObjectPart part in Children.Values)
3360 { 3363 {
3361 part.StoreUndoState(); 3364 part.StoreUndoState(UndoType.STATE_PRIM_POSITION);
3362 } 3365 }
3363 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); 3366 Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z);
3364 Vector3 oldPos = 3367 Vector3 oldPos =
@@ -3383,10 +3386,27 @@ namespace OpenSim.Region.Framework.Scenes
3383 } 3386 }
3384 lockPartsForRead(false); 3387 lockPartsForRead(false);
3385 3388
3386 AbsolutePosition = newPos; 3389 //We have to set undoing here because otherwise an undo state will be saved
3390 if (!m_rootPart.Undoing)
3391 {
3392 m_rootPart.Undoing = true;
3393 AbsolutePosition = newPos;
3394 m_rootPart.Undoing = false;
3395 }
3396 else
3397 {
3398 AbsolutePosition = newPos;
3399 }
3387 3400
3388 HasGroupChanged = true; 3401 HasGroupChanged = true;
3389 ScheduleGroupForTerseUpdate(); 3402 if (m_rootPart.Undoing)
3403 {
3404 ScheduleGroupForFullUpdate();
3405 }
3406 else
3407 {
3408 ScheduleGroupForTerseUpdate();
3409 }
3390 } 3410 }
3391 3411
3392 public void OffsetForNewRegion(Vector3 offset) 3412 public void OffsetForNewRegion(Vector3 offset)
@@ -3406,7 +3426,7 @@ namespace OpenSim.Region.Framework.Scenes
3406 { 3426 {
3407 foreach (SceneObjectPart parts in Children.Values) 3427 foreach (SceneObjectPart parts in Children.Values)
3408 { 3428 {
3409 parts.StoreUndoState(); 3429 parts.StoreUndoState(UndoType.STATE_GROUP_ROTATION);
3410 } 3430 }
3411 m_rootPart.UpdateRotation(rot); 3431 m_rootPart.UpdateRotation(rot);
3412 3432
@@ -3430,7 +3450,7 @@ namespace OpenSim.Region.Framework.Scenes
3430 { 3450 {
3431 foreach (SceneObjectPart parts in Children.Values) 3451 foreach (SceneObjectPart parts in Children.Values)
3432 { 3452 {
3433 parts.StoreUndoState(); 3453 parts.StoreUndoState(UndoType.STATE_GROUP_ROTATION);
3434 } 3454 }
3435 m_rootPart.UpdateRotation(rot); 3455 m_rootPart.UpdateRotation(rot);
3436 3456
@@ -3457,7 +3477,7 @@ namespace OpenSim.Region.Framework.Scenes
3457 SceneObjectPart part = GetChildPart(localID); 3477 SceneObjectPart part = GetChildPart(localID);
3458 foreach (SceneObjectPart parts in Children.Values) 3478 foreach (SceneObjectPart parts in Children.Values)
3459 { 3479 {
3460 parts.StoreUndoState(); 3480 parts.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3461 } 3481 }
3462 if (part != null) 3482 if (part != null)
3463 { 3483 {
@@ -3485,15 +3505,24 @@ namespace OpenSim.Region.Framework.Scenes
3485 if (part.UUID == m_rootPart.UUID) 3505 if (part.UUID == m_rootPart.UUID)
3486 { 3506 {
3487 UpdateRootRotation(rot); 3507 UpdateRootRotation(rot);
3488 AbsolutePosition = pos; 3508 if (!m_rootPart.Undoing)
3509 {
3510 m_rootPart.Undoing = true;
3511 AbsolutePosition = pos;
3512 m_rootPart.Undoing = false;
3513 }
3514 else
3515 {
3516 AbsolutePosition = pos;
3517 }
3489 } 3518 }
3490 else 3519 else
3491 { 3520 {
3521 part.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3492 part.IgnoreUndoUpdate = true; 3522 part.IgnoreUndoUpdate = true;
3493 part.UpdateRotation(rot); 3523 part.UpdateRotation(rot);
3494 part.OffsetPosition = pos; 3524 part.OffsetPosition = pos;
3495 part.IgnoreUndoUpdate = false; 3525 part.IgnoreUndoUpdate = false;
3496 part.StoreUndoState();
3497 } 3526 }
3498 } 3527 }
3499 } 3528 }
@@ -3507,7 +3536,13 @@ namespace OpenSim.Region.Framework.Scenes
3507 Quaternion axRot = rot; 3536 Quaternion axRot = rot;
3508 Quaternion oldParentRot = m_rootPart.RotationOffset; 3537 Quaternion oldParentRot = m_rootPart.RotationOffset;
3509 3538
3510 m_rootPart.StoreUndoState(); 3539 m_rootPart.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3540 bool cancelUndo = false;
3541 if (!m_rootPart.Undoing)
3542 {
3543 m_rootPart.Undoing = true;
3544 cancelUndo = true;
3545 }
3511 m_rootPart.UpdateRotation(rot); 3546 m_rootPart.UpdateRotation(rot);
3512 if (m_rootPart.PhysActor != null) 3547 if (m_rootPart.PhysActor != null)
3513 { 3548 {
@@ -3531,18 +3566,13 @@ namespace OpenSim.Region.Framework.Scenes
3531 newRot *= Quaternion.Inverse(axRot); 3566 newRot *= Quaternion.Inverse(axRot);
3532 prim.RotationOffset = newRot; 3567 prim.RotationOffset = newRot;
3533 prim.ScheduleTerseUpdate(); 3568 prim.ScheduleTerseUpdate();
3569 prim.IgnoreUndoUpdate = false;
3534 } 3570 }
3535 } 3571 }
3536 3572 if (cancelUndo == true)
3537 foreach (SceneObjectPart childpart in Children.Values)
3538 { 3573 {
3539 if (childpart != m_rootPart) 3574 m_rootPart.Undoing = false;
3540 {
3541 childpart.IgnoreUndoUpdate = false;
3542 childpart.StoreUndoState();
3543 }
3544 } 3575 }
3545
3546 lockPartsForRead(false); 3576 lockPartsForRead(false);
3547 3577
3548 m_rootPart.ScheduleTerseUpdate(); 3578 m_rootPart.ScheduleTerseUpdate();
@@ -3911,7 +3941,7 @@ namespace OpenSim.Region.Framework.Scenes
3911 3941
3912 public virtual ISceneObject CloneForNewScene() 3942 public virtual ISceneObject CloneForNewScene()
3913 { 3943 {
3914 SceneObjectGroup sog = Copy(this.OwnerID, this.GroupID, false); 3944 SceneObjectGroup sog = Copy(false);
3915 sog.m_isDeleted = false; 3945 sog.m_isDeleted = false;
3916 return sog; 3946 return sog;
3917 } 3947 }
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 09c945b..3327b1e 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -358,7 +358,7 @@ namespace OpenSim.Region.Framework.Scenes
358 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition, 358 UUID ownerID, PrimitiveBaseShape shape, Vector3 groupPosition,
359 Quaternion rotationOffset, Vector3 offsetPosition) 359 Quaternion rotationOffset, Vector3 offsetPosition)
360 { 360 {
361 m_name = "Primitive"; 361 m_name = "Object";
362 362
363 Rezzed = DateTime.UtcNow; 363 Rezzed = DateTime.UtcNow;
364 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed); 364 _creationDate = (int)Utils.DateTimeToUnixTime(Rezzed);
@@ -697,7 +697,7 @@ namespace OpenSim.Region.Framework.Scenes
697 get { return m_offsetPosition; } 697 get { return m_offsetPosition; }
698 set 698 set
699 { 699 {
700 StoreUndoState(); 700 StoreUndoState(UndoType.STATE_PRIM_POSITION);
701 m_offsetPosition = value; 701 m_offsetPosition = value;
702 702
703 if (ParentGroup != null && !ParentGroup.IsDeleted) 703 if (ParentGroup != null && !ParentGroup.IsDeleted)
@@ -759,7 +759,7 @@ namespace OpenSim.Region.Framework.Scenes
759 759
760 set 760 set
761 { 761 {
762 StoreUndoState(); 762 StoreUndoState(UndoType.STATE_PRIM_ROTATION);
763 m_rotationOffset = value; 763 m_rotationOffset = value;
764 764
765 PhysicsActor actor = PhysActor; 765 PhysicsActor actor = PhysActor;
@@ -958,7 +958,7 @@ namespace OpenSim.Region.Framework.Scenes
958 get { return m_shape.Scale; } 958 get { return m_shape.Scale; }
959 set 959 set
960 { 960 {
961 StoreUndoState(); 961 StoreUndoState(UndoType.STATE_PRIM_SCALE);
962 if (m_shape != null) 962 if (m_shape != null)
963 { 963 {
964 m_shape.Scale = value; 964 m_shape.Scale = value;
@@ -1522,7 +1522,7 @@ namespace OpenSim.Region.Framework.Scenes
1522 { 1522 {
1523 m_redo.Clear(); 1523 m_redo.Clear();
1524 } 1524 }
1525 StoreUndoState(); 1525 StoreUndoState(UndoType.STATE_ALL);
1526 } 1526 }
1527 1527
1528 public byte ConvertScriptUintToByte(uint indata) 1528 public byte ConvertScriptUintToByte(uint indata)
@@ -1625,7 +1625,7 @@ namespace OpenSim.Region.Framework.Scenes
1625 PrimitiveBaseShape shape = PrimitiveBaseShape.Create(); 1625 PrimitiveBaseShape shape = PrimitiveBaseShape.Create();
1626 part.Shape = shape; 1626 part.Shape = shape;
1627 1627
1628 part.Name = "Primitive"; 1628 part.Name = "Object";
1629 part._ownerID = UUID.Random(); 1629 part._ownerID = UUID.Random();
1630 1630
1631 return part; 1631 return part;
@@ -2721,7 +2721,7 @@ namespace OpenSim.Region.Framework.Scenes
2721 /// <param name="scale"></param> 2721 /// <param name="scale"></param>
2722 public void Resize(Vector3 scale) 2722 public void Resize(Vector3 scale)
2723 { 2723 {
2724 StoreUndoState(); 2724 StoreUndoState(UndoType.STATE_PRIM_SCALE);
2725 m_shape.Scale = scale; 2725 m_shape.Scale = scale;
2726 2726
2727 ParentGroup.HasGroupChanged = true; 2727 ParentGroup.HasGroupChanged = true;
@@ -3504,10 +3504,9 @@ namespace OpenSim.Region.Framework.Scenes
3504 m_parentGroup.ScheduleGroupForTerseUpdate(); 3504 m_parentGroup.ScheduleGroupForTerseUpdate();
3505 //m_parentGroup.ScheduleGroupForFullUpdate(); 3505 //m_parentGroup.ScheduleGroupForFullUpdate();
3506 } 3506 }
3507 3507 public void StoreUndoState(UndoType type)
3508 public void StoreUndoState()
3509 { 3508 {
3510 if (!Undoing) 3509 if (!Undoing && (m_parentGroup == null || m_parentGroup.RootPart == null || !m_parentGroup.RootPart.Undoing))
3511 { 3510 {
3512 if (!IgnoreUndoUpdate) 3511 if (!IgnoreUndoUpdate)
3513 { 3512 {
@@ -3518,17 +3517,25 @@ namespace OpenSim.Region.Framework.Scenes
3518 if (m_undo.Count > 0) 3517 if (m_undo.Count > 0)
3519 { 3518 {
3520 UndoState last = m_undo.Peek(); 3519 UndoState last = m_undo.Peek();
3521 if (last != null) 3520
3522 {
3523 if (last.Compare(this))
3524 return;
3525 }
3526 } 3521 }
3527 3522
3528 if (m_parentGroup.GetSceneMaxUndo() > 0) 3523 if (m_parentGroup.GetSceneMaxUndo() > 0)
3529 { 3524 {
3530 UndoState nUndo = new UndoState(this); 3525 UndoState lastUndo = m_undo.Peek();
3526
3527 UndoState nUndo = new UndoState(this, type);
3531 3528
3529 if (lastUndo != null)
3530 {
3531 TimeSpan ts = DateTime.Now.Subtract(lastUndo.LastUpdated);
3532 if (ts.TotalMilliseconds < 500)
3533 {
3534 //Delete the last entry since it was less than 500 milliseconds ago
3535 nUndo.Merge(lastUndo);
3536 m_undo.Pop();
3537 }
3538 }
3532 m_undo.Push(nUndo); 3539 m_undo.Push(nUndo);
3533 } 3540 }
3534 3541
@@ -4005,11 +4012,13 @@ namespace OpenSim.Region.Framework.Scenes
4005 if (m_undo.Count > 0) 4012 if (m_undo.Count > 0)
4006 { 4013 {
4007 UndoState nUndo = null; 4014 UndoState nUndo = null;
4015 UndoState goback = m_undo.Pop();
4008 if (m_parentGroup.GetSceneMaxUndo() > 0) 4016 if (m_parentGroup.GetSceneMaxUndo() > 0)
4009 { 4017 {
4010 nUndo = new UndoState(this); 4018 nUndo = new UndoState(this, goback.Type);
4011 } 4019 }
4012 UndoState goback = m_undo.Pop(); 4020
4021
4013 if (goback != null) 4022 if (goback != null)
4014 { 4023 {
4015 goback.PlaybackState(this); 4024 goback.PlaybackState(this);
@@ -4024,13 +4033,13 @@ namespace OpenSim.Region.Framework.Scenes
4024 { 4033 {
4025 lock (m_redo) 4034 lock (m_redo)
4026 { 4035 {
4036 UndoState gofwd = m_redo.Pop();
4027 if (m_parentGroup.GetSceneMaxUndo() > 0) 4037 if (m_parentGroup.GetSceneMaxUndo() > 0)
4028 { 4038 {
4029 UndoState nUndo = new UndoState(this); 4039 UndoState nUndo = new UndoState(this, gofwd.Type);
4030 4040
4031 m_undo.Push(nUndo); 4041 m_undo.Push(nUndo);
4032 } 4042 }
4033 UndoState gofwd = m_redo.Pop();
4034 if (gofwd != null) 4043 if (gofwd != null)
4035 gofwd.PlayfwdState(this); 4044 gofwd.PlayfwdState(this);
4036 } 4045 }
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4a4cac9..e51d9ee 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -3730,8 +3730,11 @@ Console.WriteLine("Scripted Sit ofset {0}", m_pos);
3730 { 3730 {
3731 CollidingMessage.Colliders = colliding; 3731 CollidingMessage.Colliders = colliding;
3732 3732
3733 foreach (SceneObjectGroup att in Attachments) 3733 lock (m_attachments)
3734 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); 3734 {
3735 foreach (SceneObjectGroup att in m_attachments)
3736 Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage);
3737 }
3735 } 3738 }
3736 } 3739 }
3737 3740
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 5bdaa17..77e477f 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -105,7 +105,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
105 sceneObject.AddPart(part); 105 sceneObject.AddPart(part);
106 part.LinkNum = linkNum; 106 part.LinkNum = linkNum;
107 part.TrimPermissions(); 107 part.TrimPermissions();
108 part.StoreUndoState(); 108 part.StoreUndoState(UndoType.STATE_ALL);
109 reader.Close(); 109 reader.Close();
110 sr.Close(); 110 sr.Close();
111 } 111 }
@@ -231,7 +231,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
231 if (originalLinkNum != 0) 231 if (originalLinkNum != 0)
232 part.LinkNum = originalLinkNum; 232 part.LinkNum = originalLinkNum;
233 233
234 part.StoreUndoState(); 234 part.StoreUndoState(UndoType.STATE_ALL);
235 reader.Close(); 235 reader.Close();
236 sr.Close(); 236 sr.Close();
237 } 237 }
diff --git a/OpenSim/Region/Framework/Scenes/UndoState.cs b/OpenSim/Region/Framework/Scenes/UndoState.cs
index 55e407e..f71b507 100644
--- a/OpenSim/Region/Framework/Scenes/UndoState.cs
+++ b/OpenSim/Region/Framework/Scenes/UndoState.cs
@@ -27,48 +27,125 @@
27 27
28using OpenMetaverse; 28using OpenMetaverse;
29using OpenSim.Region.Framework.Interfaces; 29using OpenSim.Region.Framework.Interfaces;
30using System;
30 31
31namespace OpenSim.Region.Framework.Scenes 32namespace OpenSim.Region.Framework.Scenes
32{ 33{
34 [Flags]
35 public enum UndoType
36 {
37 STATE_PRIM_POSITION = 1,
38 STATE_PRIM_ROTATION = 2,
39 STATE_PRIM_SCALE = 4,
40 STATE_PRIM_ALL = 7,
41 STATE_GROUP_POSITION = 8,
42 STATE_GROUP_ROTATION = 16,
43 STATE_GROUP_SCALE = 32,
44 STATE_GROUP_ALL = 56,
45 STATE_ALL = 63
46 }
47
33 public class UndoState 48 public class UndoState
34 { 49 {
35 public Vector3 Position = Vector3.Zero; 50 public Vector3 Position = Vector3.Zero;
36 public Vector3 Scale = Vector3.Zero; 51 public Vector3 Scale = Vector3.Zero;
37 public Quaternion Rotation = Quaternion.Identity; 52 public Quaternion Rotation = Quaternion.Identity;
53 public Vector3 GroupPosition = Vector3.Zero;
54 public Quaternion GroupRotation = Quaternion.Identity;
55 public Vector3 GroupScale = Vector3.Zero;
56 public DateTime LastUpdated = DateTime.Now;
57 public UndoType Type;
38 58
39 public UndoState(SceneObjectPart part) 59 public UndoState(SceneObjectPart part, UndoType type)
40 { 60 {
61 Type = type;
41 if (part != null) 62 if (part != null)
42 { 63 {
43 if (part.ParentID == 0) 64 if (part.ParentID == 0)
44 { 65 {
45 Position = part.ParentGroup.AbsolutePosition; 66 GroupScale = part.ParentGroup.RootPart.Shape.Scale;
67
68 //FUBAR WARNING: Do NOT get the group's absoluteposition here
69 //or you'll experience a loop and/or a stack issue
70 GroupPosition = part.ParentGroup.RootPart.AbsolutePosition;
71 GroupRotation = part.ParentGroup.GroupRotation;
72 Position = part.ParentGroup.RootPart.AbsolutePosition;
46 Rotation = part.RotationOffset; 73 Rotation = part.RotationOffset;
47 Scale = part.Shape.Scale; 74 Scale = part.Shape.Scale;
75 LastUpdated = DateTime.Now;
48 } 76 }
49 else 77 else
50 { 78 {
79 GroupScale = part.Shape.Scale;
80
81 //FUBAR WARNING: Do NOT get the group's absoluteposition here
82 //or you'll experience a loop and/or a stack issue
83 GroupPosition = part.ParentGroup.RootPart.AbsolutePosition;
84 GroupRotation = part.ParentGroup.Rotation;
51 Position = part.OffsetPosition; 85 Position = part.OffsetPosition;
52 Rotation = part.RotationOffset; 86 Rotation = part.RotationOffset;
53 Scale = part.Shape.Scale; 87 Scale = part.Shape.Scale;
88 LastUpdated = DateTime.Now;
54 } 89 }
55 } 90 }
56 } 91 }
57 92 public void Merge(UndoState last)
93 {
94 if ((Type & UndoType.STATE_GROUP_POSITION) == 0 || ((last.Type & UndoType.STATE_GROUP_POSITION) >= (Type & UndoType.STATE_GROUP_POSITION)))
95 {
96 GroupPosition = last.GroupPosition;
97 Position = last.Position;
98 }
99 if ((Type & UndoType.STATE_GROUP_SCALE) == 0 || ((last.Type & UndoType.STATE_GROUP_SCALE) >= (Type & UndoType.STATE_GROUP_SCALE)))
100 {
101 GroupScale = last.GroupScale;
102 Scale = last.Scale;
103 }
104 if ((Type & UndoType.STATE_GROUP_ROTATION) == 0 || ((last.Type & UndoType.STATE_GROUP_ROTATION) >= (Type & UndoType.STATE_GROUP_ROTATION)))
105 {
106 GroupRotation = last.GroupRotation;
107 Rotation = last.Rotation;
108 }
109 if ((Type & UndoType.STATE_PRIM_POSITION) == 0 || ((last.Type & UndoType.STATE_PRIM_POSITION) >= (Type & UndoType.STATE_PRIM_POSITION)))
110 {
111 Position = last.Position;
112 }
113 if ((Type & UndoType.STATE_PRIM_SCALE) == 0 || ((last.Type & UndoType.STATE_PRIM_SCALE) >= (Type & UndoType.STATE_PRIM_SCALE)))
114 {
115 Scale = last.Scale;
116 }
117 if ((Type & UndoType.STATE_PRIM_ROTATION) == 0 || ((last.Type & UndoType.STATE_PRIM_ROTATION) >= (Type & UndoType.STATE_PRIM_ROTATION)))
118 {
119 Rotation = last.Rotation;
120 }
121 Type = Type | last.Type;
122 }
123 public bool Compare(UndoState undo)
124 {
125 if (undo == null || Position == null) return false;
126 if (undo.Position == Position && undo.Rotation == Rotation && undo.Scale == Scale && undo.GroupPosition == GroupPosition && undo.GroupScale == GroupScale && undo.GroupRotation == GroupRotation)
127 {
128 return true;
129 }
130 else
131 {
132 return false;
133 }
134 }
58 public bool Compare(SceneObjectPart part) 135 public bool Compare(SceneObjectPart part)
59 { 136 {
60 if (part != null) 137 if (part != null)
61 { 138 {
62 if (part.ParentID == 0) 139 if (part.ParentID == 0)
63 { 140 {
64 if (Position == part.ParentGroup.AbsolutePosition && Rotation == part.ParentGroup.Rotation) 141 if (Position == part.ParentGroup.RootPart.AbsolutePosition && Rotation == part.ParentGroup.Rotation && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale)
65 return true; 142 return true;
66 else 143 else
67 return false; 144 return false;
68 } 145 }
69 else 146 else
70 { 147 {
71 if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale) 148 if (Position == part.OffsetPosition && Rotation == part.RotationOffset && Scale == part.Shape.Scale && GroupPosition == part.ParentGroup.RootPart.AbsolutePosition && part.ParentGroup.Rotation == GroupRotation && part.Shape.Scale == GroupScale)
72 return true; 149 return true;
73 else 150 else
74 return false; 151 return false;
@@ -78,62 +155,70 @@ namespace OpenSim.Region.Framework.Scenes
78 return false; 155 return false;
79 } 156 }
80 157
81 public void PlaybackState(SceneObjectPart part) 158 private void RestoreState(SceneObjectPart part)
82 { 159 {
160 bool GroupChange = false;
161 if ((Type & UndoType.STATE_GROUP_POSITION) != 0
162 || (Type & UndoType.STATE_GROUP_ROTATION) != 0
163 || (Type & UndoType.STATE_GROUP_SCALE) != 0)
164 {
165 GroupChange = true;
166 }
167
83 if (part != null) 168 if (part != null)
84 { 169 {
85 part.Undoing = true; 170 part.Undoing = true;
86 171
87 if (part.ParentID == 0) 172 if (part.ParentID == 0 && GroupChange == false)
88 { 173 {
89 if (Position != Vector3.Zero) 174 if (Position != Vector3.Zero)
90 part.ParentGroup.AbsolutePosition = Position; 175
91 part.RotationOffset = Rotation; 176 part.ParentGroup.UpdateSinglePosition(Position, part.LocalId);
177 part.ParentGroup.UpdateSingleRotation(Rotation, part.LocalId);
92 if (Scale != Vector3.Zero) 178 if (Scale != Vector3.Zero)
93 part.Resize(Scale); 179 part.Resize(Scale);
94 part.ParentGroup.ScheduleGroupForTerseUpdate(); 180 part.ParentGroup.ScheduleGroupForTerseUpdate();
95 } 181 }
96 else 182 else
97 { 183 {
98 if (Position != Vector3.Zero) 184 if (GroupChange)
99 part.OffsetPosition = Position; 185 {
100 part.UpdateRotation(Rotation); 186 part.ParentGroup.RootPart.Undoing = true;
101 if (Scale != Vector3.Zero) 187 if (GroupPosition != Vector3.Zero)
102 part.Resize(Scale); part.ScheduleTerseUpdate(); 188 {
189 //Calculate the scale...
190 Vector3 gs = part.Shape.Scale;
191 float scale = GroupScale.Z / gs.Z;
192
193 //Scale first since it can affect our position
194 part.ParentGroup.GroupResize(gs * scale, part.LocalId);
195 part.ParentGroup.AbsolutePosition = GroupPosition;
196 part.ParentGroup.UpdateGroupRotationR(GroupRotation);
197
198 }
199 part.ParentGroup.RootPart.Undoing = false;
200 }
201 else
202 {
203 if (Position != Vector3.Zero) //We can use this for all the updates since all are set
204 {
205 part.OffsetPosition = Position;
206 part.UpdateRotation(Rotation);
207 part.Resize(Scale); part.ScheduleTerseUpdate();
208 }
209 }
103 } 210 }
104 part.Undoing = false; 211 part.Undoing = false;
105 212
106 } 213 }
107 } 214 }
215 public void PlaybackState(SceneObjectPart part)
216 {
217 RestoreState(part);
218 }
108 public void PlayfwdState(SceneObjectPart part) 219 public void PlayfwdState(SceneObjectPart part)
109 { 220 {
110 if (part != null) 221 RestoreState(part);
111 {
112 part.Undoing = true;
113
114 if (part.ParentID == 0)
115 {
116 if (Position != Vector3.Zero)
117 part.ParentGroup.AbsolutePosition = Position;
118 if (Rotation != Quaternion.Identity)
119 part.UpdateRotation(Rotation);
120 if (Scale != Vector3.Zero)
121 part.Resize(Scale);
122 part.ParentGroup.ScheduleGroupForTerseUpdate();
123 }
124 else
125 {
126 if (Position != Vector3.Zero)
127 part.OffsetPosition = Position;
128 if (Rotation != Quaternion.Identity)
129 part.UpdateRotation(Rotation);
130 if (Scale != Vector3.Zero)
131 part.Resize(Scale);
132 part.ScheduleTerseUpdate();
133 }
134 part.Undoing = false;
135
136 }
137 } 222 }
138 } 223 }
139 public class LandUndoState 224 public class LandUndoState
@@ -161,3 +246,4 @@ namespace OpenSim.Region.Framework.Scenes
161 } 246 }
162 } 247 }
163} 248}
249