aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim
diff options
context:
space:
mode:
authorTom2011-09-07 09:42:18 -0700
committerTom2011-09-07 09:42:18 -0700
commit03f6734f4367b08e2b181ed68bc80b885e76148f (patch)
treefa8550771d3b5eb1a0315f107801b332f78bede5 /OpenSim
parentNow merging the core changes. (diff)
downloadopensim-SC-03f6734f4367b08e2b181ed68bc80b885e76148f.zip
opensim-SC-03f6734f4367b08e2b181ed68bc80b885e76148f.tar.gz
opensim-SC-03f6734f4367b08e2b181ed68bc80b885e76148f.tar.bz2
opensim-SC-03f6734f4367b08e2b181ed68bc80b885e76148f.tar.xz
First set of merge fixes
Diffstat (limited to 'OpenSim')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs2
-rw-r--r--OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs89
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs98
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs19
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs35
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs87
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs63
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs309
-rw-r--r--OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs202
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs3
11 files changed, 337 insertions, 585 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 5c94fba..db81fea 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -3747,7 +3747,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3747 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp)) 3747 if (!m_scene.TryGetScenePresence(part.OwnerID, out sp))
3748 continue; 3748 continue;
3749 3749
3750 List<SceneObjectGroup> atts = sp.Attachments; 3750 List<SceneObjectGroup> atts = sp.GetAttachments();
3751 bool found = false; 3751 bool found = false;
3752 foreach (SceneObjectGroup att in atts) 3752 foreach (SceneObjectGroup att in atts)
3753 { 3753 {
diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
index d9dcee7..3373bd5 100644
--- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs
@@ -172,10 +172,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
172 private void RetrieveInstantMessages(IClientAPI client) 172 private void RetrieveInstantMessages(IClientAPI client)
173 { 173 {
174 if (m_RestURL == String.Empty) 174 if (m_RestURL == String.Empty)
175 { 175 {
176 return; 176 return;
177 } 177 }
178 else 178 else
179 { 179 {
180 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId); 180 m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId);
181 181
@@ -183,64 +183,51 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage
183 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>( 183 = SynchronousRestObjectRequester.MakeRequest<UUID, List<GridInstantMessage>>(
184 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); 184 "POST", m_RestURL + "/RetrieveMessages/", client.AgentId);
185 185
186 if (msglist != null) 186 if (msglist != null)
187 {
188 foreach (GridInstantMessage im in msglist)
189 { 187 {
190 // client.SendInstantMessage(im); 188 foreach (GridInstantMessage im in msglist)
191 189 {
192 // Send through scene event manager so all modules get a chance 190 // client.SendInstantMessage(im);
193 // to look at this message before it gets delivered. 191
194 // 192 // Send through scene event manager so all modules get a chance
195 // Needed for proper state management for stored group 193 // to look at this message before it gets delivered.
196 // invitations 194 //
197 // 195 // Needed for proper state management for stored group
198 196 // invitations
199 im.offline = 1; 197 //
200 198
201 Scene s = FindScene(client.AgentId); 199 im.offline = 1;
202 if (s != null) 200
203 s.EventManager.TriggerIncomingInstantMessage(im); 201 Scene s = FindScene(client.AgentId);
202 if (s != null)
203 s.EventManager.TriggerIncomingInstantMessage(im);
204 }
204 } 205 }
205 } 206 }
206 } 207 }
207 208
208 private void UndeliveredMessage(GridInstantMessage im) 209 private void UndeliveredMessage(GridInstantMessage im)
209 { 210 {
210 if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && 211 if ((im.offline != 0)
211 im.dialog != (byte)InstantMessageDialog.MessageFromAgent && 212 && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages)))
212 im.dialog != (byte)InstantMessageDialog.GroupNotice &&
213 im.dialog != (byte)InstantMessageDialog.GroupInvitation &&
214 im.dialog != (byte)InstantMessageDialog.InventoryOffered)
215 { 213 {
216 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>( 214 bool success = SynchronousRestObjectRequester.MakeRequest<GridInstantMessage, bool>(
217 "POST", m_RestURL+"/SaveMessage/", im); 215 "POST", m_RestURL + "/SaveMessage/", im);
218 return;
219 }
220
221 // It's not delivered. Make sure the scope id is saved
222 // We don't need the imSessionID here anymore, overwrite it
223 Scene scene = FindScene(new UUID(im.fromAgentID));
224 if (scene == null)
225 scene = m_SceneList[0];
226
227 bool success = SynchronousRestObjectPoster.BeginPostObject<GridInstantMessage, bool>(
228 "POST", m_RestURL+"/SaveMessage/?scope=" +
229 scene.RegionInfo.ScopeID.ToString(), im);
230 216
231 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) 217 if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent)
232 { 218 {
233 IClientAPI client = FindClient(new UUID(im.fromAgentID)); 219 IClientAPI client = FindClient(new UUID(im.fromAgentID));
234 if (client == null) 220 if (client == null)
235 return; 221 return;
236 222
237 client.SendInstantMessage(new GridInstantMessage( 223 client.SendInstantMessage(new GridInstantMessage(
238 null, new UUID(im.toAgentID), 224 null, new UUID(im.toAgentID),
239 "System", new UUID(im.fromAgentID), 225 "System", new UUID(im.fromAgentID),
240 (byte)InstantMessageDialog.MessageFromAgent, 226 (byte)InstantMessageDialog.MessageFromAgent,
241 "User is not logged in. "+ 227 "User is not logged in. " +
242 (success ? "Message saved." : "Message not saved"), 228 (success ? "Message saved." : "Message not saved"),
243 false, new Vector3())); 229 false, new Vector3()));
230 }
244 } 231 }
245 } 232 }
246 } 233 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index 654e202..a4bb40e 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -788,7 +788,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
788 788
789 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) 789 if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
790 return null; 790 return null;
791 791 SceneObjectPart rootPart = group.RootPart;
792 for (int i = 0; i < objlist.Count; i++) 792 for (int i = 0; i < objlist.Count; i++)
793 { 793 {
794 group = objlist[i]; 794 group = objlist[i];
@@ -835,8 +835,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
835 group.AbsolutePosition = pos + veclist[i]; 835 group.AbsolutePosition = pos + veclist[i];
836 } 836 }
837 837
838 SceneObjectPart rootPart = group.RootPart;
839
840 group.SetGroup(remoteClient.ActiveGroupId, remoteClient); 838 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
841 839
842 if (!attachment) 840 if (!attachment)
@@ -861,13 +859,57 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
861 if (item != null) 859 if (item != null)
862 DoPostRezWhenFromItem(item, attachment); 860 DoPostRezWhenFromItem(item, attachment);
863 861
864 if ((rootPart.OwnerID != item.Owner) || 862 if ((rootPart.OwnerID != item.Owner) ||
865 (item.CurrentPermissions & 16) != 0 || // Magic number 863 (item.CurrentPermissions & 16) != 0 || // Magic number
866 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) 864 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
865 {
866 //Need to kill the for sale here
867 rootPart.ObjectSaleType = 0;
868 rootPart.SalePrice = 10;
869
870 if (m_Scene.Permissions.PropagatePermissions())
871 {
872 foreach (SceneObjectPart part in group.Parts)
873 {
874 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
867 { 875 {
868 //Need to kill the for sale here 876 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
869 rootPart.ObjectSaleType = 0; 877 part.EveryoneMask = item.EveryOnePermissions;
870 rootPart.SalePrice = 10; 878 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
879 part.NextOwnerMask = item.NextPermissions;
880 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
881 part.GroupMask = item.GroupPermissions;
882 }
883 }
884
885 foreach (SceneObjectPart part in group.Parts)
886 {
887 part.LastOwnerID = part.OwnerID;
888 part.OwnerID = item.Owner;
889 part.Inventory.ChangeInventoryOwner(item.Owner);
890 }
891
892 group.ApplyNextOwnerPermissions();
893 }
894 }
895 foreach (SceneObjectPart part in group.Parts)
896 {
897 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
898 part.EveryoneMask = item.EveryOnePermissions;
899 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
900 part.NextOwnerMask = item.NextPermissions;
901 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
902 part.GroupMask = item.GroupPermissions;
903 }
904
905 if ((rootPart.OwnerID != item.Owner) ||
906 (item.CurrentPermissions & 16) != 0 || // Magic number
907 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
908 {
909 //Need to kill the for sale here
910 rootPart.ObjectSaleType = 0;
911 rootPart.SalePrice = 10;
912 }
871 913
872 return group; 914 return group;
873 } 915 }
@@ -1015,48 +1057,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
1015 } 1057 }
1016 } 1058 }
1017 } 1059 }
1018 if ((rootPart.OwnerID != item.Owner) ||
1019 (item.CurrentPermissions & 16) != 0 || // Magic number
1020 (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
1021 {
1022 //Need to kill the for sale here
1023 rootPart.ObjectSaleType = 0;
1024 rootPart.SalePrice = 10;
1025
1026 if (m_Scene.Permissions.PropagatePermissions())
1027 {
1028 foreach (SceneObjectPart part in group.Parts)
1029 {
1030 if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0)
1031 {
1032 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1033 part.EveryoneMask = item.EveryOnePermissions;
1034 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1035 part.NextOwnerMask = item.NextPermissions;
1036 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
1037 part.GroupMask = item.GroupPermissions;
1038 }
1039 }
1040
1041 foreach (SceneObjectPart part in group.Parts)
1042 {
1043 part.LastOwnerID = part.OwnerID;
1044 part.OwnerID = item.Owner;
1045 part.Inventory.ChangeInventoryOwner(item.Owner);
1046 }
1047
1048 group.ApplyNextOwnerPermissions();
1049 }
1050 }
1051 foreach (SceneObjectPart part in group.Parts)
1052 {
1053 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
1054 part.EveryoneMask = item.EveryOnePermissions;
1055 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
1056 part.NextOwnerMask = item.NextPermissions;
1057 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
1058 part.GroupMask = item.GroupPermissions;
1059 }
1060 } 1060 }
1061 1061
1062 protected void AddUserData(SceneObjectGroup sog) 1062 protected void AddUserData(SceneObjectGroup sog)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 89f3683..63dd550 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -968,24 +968,25 @@ namespace OpenSim.Region.Framework.Scenes
968 if (part != null) 968 if (part != null)
969 { 969 {
970 group = part.ParentGroup; 970 group = part.ParentGroup;
971 } 971 }
972 if (part != null && group != null) 972 if (part != null && group != null)
973 { 973 {
974 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) 974 if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId))
975 return; 975 return;
976 976
977 TaskInventoryItem item = group.GetInventoryItem(localID, itemID); 977 TaskInventoryItem item = group.GetInventoryItem(localID, itemID);
978 if (item == null) 978 if (item == null)
979 return; 979 return;
980 980
981 if (item.Type == 10) 981 if (item.Type == 10)
982 { 982 {
983 part.RemoveScriptEvents(itemID); 983 part.RemoveScriptEvents(itemID);
984 EventManager.TriggerRemoveScript(localID, itemID); 984 EventManager.TriggerRemoveScript(localID, itemID);
985 }
986
987 group.RemoveInventoryItem(localID, itemID);
988 part.GetProperties(remoteClient);
985 } 989 }
986
987 group.RemoveInventoryItem(localID, itemID);
988 part.GetProperties(remoteClient);
989 } 990 }
990 991
991 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) 992 private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId)
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 26fe61d..345c2df 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -5347,41 +5347,6 @@ namespace OpenSim.Region.Framework.Scenes
5347// } 5347// }
5348// } 5348// }
5349 5349
5350 lock (m_cleaningAttachments)
5351 {
5352 ForEachSOG(delegate (SceneObjectGroup grp)
5353 {
5354 if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp)))
5355 {
5356 UUID agentID = grp.OwnerID;
5357 if (agentID == UUID.Zero)
5358 {
5359 objectsToDelete.Add(grp);
5360 return;
5361 }
5362
5363 ScenePresence sp = GetScenePresence(agentID);
5364 if (sp == null)
5365 {
5366 objectsToDelete.Add(grp);
5367 return;
5368 }
5369 }
5370 });
5371 }
5372
5373 if (objectsToDelete.Count > 0)
5374 {
5375 m_log.DebugFormat("[SCENE]: Starting delete of {0} dropped attachments", objectsToDelete.Count);
5376 foreach (SceneObjectGroup grp in objectsToDelete)
5377 {
5378 m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID);
5379 DeleteSceneObject(grp, true);
5380 }
5381 m_log.Debug("[SCENE]: Finished dropped attachment deletion");
5382 }
5383 }
5384
5385 public void ThreadAlive(int threadCode) 5350 public void ThreadAlive(int threadCode)
5386 { 5351 {
5387 switch(threadCode) 5352 switch(threadCode)
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index 29edf13..42e2502 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1437,9 +1437,9 @@ namespace OpenSim.Region.Framework.Scenes
1437 // Set the new attachment point data in the object 1437 // Set the new attachment point data in the object
1438 byte attachmentPoint = group.GetAttachmentPoint(); 1438 byte attachmentPoint = group.GetAttachmentPoint();
1439 group.UpdateGroupPosition(pos); 1439 group.UpdateGroupPosition(pos);
1440 group.RootPart.IsAttachment = false; 1440 group.IsAttachment = false;
1441 group.AbsolutePosition = group.RootPart.AttachedPos; 1441 group.AbsolutePosition = group.RootPart.AttachedPos;
1442 group.SetAttachmentPoint(attachmentPoint); 1442 group.AttachmentPoint = attachmentPoint;
1443 group.HasGroupChanged = true; 1443 group.HasGroupChanged = true;
1444 } 1444 }
1445 else 1445 else
@@ -1723,12 +1723,11 @@ namespace OpenSim.Region.Framework.Scenes
1723 // So that, on delink, no prims are unwittingly 1723 // So that, on delink, no prims are unwittingly
1724 // left for sale and sold off 1724 // left for sale and sold off
1725 1725
1726 if (child != null) 1726 if (child != null)
1727 { 1727 {
1728 child.RootPart.ObjectSaleType = 0; 1728 child.RootPart.ObjectSaleType = 0;
1729 child.RootPart.SalePrice = 10; 1729 child.RootPart.SalePrice = 10;
1730 childGroups.Add(child); 1730 childGroups.Add(child);
1731 }
1732 } 1731 }
1733 } 1732 }
1734 1733
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index 88a6232..35684e0 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -350,10 +350,6 @@ namespace OpenSim.Region.Framework.Scenes
350 { 350 {
351 get { return m_rotation; } 351 get { return m_rotation; }
352 set { 352 set {
353 foreach(SceneObjectPart p in m_parts.GetArray())
354 {
355 p.StoreUndoState(UndoType.STATE_GROUP_ROTATION);
356 }
357 m_rotation = value; 353 m_rotation = value;
358 } 354 }
359 } 355 }
@@ -487,8 +483,6 @@ namespace OpenSim.Region.Framework.Scenes
487 SceneObjectPart[] parts = m_parts.GetArray(); 483 SceneObjectPart[] parts = m_parts.GetArray();
488 foreach (SceneObjectPart part in parts) 484 foreach (SceneObjectPart part in parts)
489 { 485 {
490 part.IgnoreUndoUpdate = false;
491 part.StoreUndoState(UndoType.STATE_GROUP_POSITION);
492 part.GroupPosition = val; 486 part.GroupPosition = val;
493 if (!m_dupeInProgress) 487 if (!m_dupeInProgress)
494 { 488 {
@@ -1193,45 +1187,31 @@ namespace OpenSim.Region.Framework.Scenes
1193 /// <param name="agentID"></param> 1187 /// <param name="agentID"></param>
1194 /// <param name="attachmentpoint"></param> 1188 /// <param name="attachmentpoint"></param>
1195 /// <param name="AttachOffset"></param> 1189 /// <param name="AttachOffset"></param>
1196 public void AttachToAgent(UUID agentID, uint attachmentpoint, Vector3 AttachOffset, bool silent) 1190 private void AttachToAgent(
1191 ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent)
1197 { 1192 {
1198 ScenePresence avatar = m_scene.GetScenePresence(agentID);
1199 if (avatar != null) 1193 if (avatar != null)
1200 { 1194 {
1201 // don't attach attachments to child agents 1195 // don't attach attachments to child agents
1202 if (avatar.IsChildAgent) return; 1196 if (avatar.IsChildAgent) return;
1203 1197
1204// m_log.DebugFormat("[SOG]: Adding attachment {0} to avatar {1}", Name, avatar.Name);
1205
1206 DetachFromBackup();
1207
1208 // Remove from database and parcel prim count 1198 // Remove from database and parcel prim count
1209 m_scene.DeleteFromStorage(UUID); 1199 m_scene.DeleteFromStorage(so.UUID);
1210 m_scene.EventManager.TriggerParcelPrimCountTainted(); 1200 m_scene.EventManager.TriggerParcelPrimCountTainted();
1211 1201
1212 m_rootPart.AttachedAvatar = agentID; 1202 so.AttachedAvatar = avatar.UUID;
1213 1203
1214 //Anakin Lohner bug #3839 1204 if (so.RootPart.PhysActor != null)
1215 lock (m_parts)
1216 { 1205 {
1217 foreach (SceneObjectPart p in m_parts.GetArray()) 1206 m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor);
1218 { 1207 so.RootPart.PhysActor = null;
1219 p.AttachedAvatar = agentID;
1220 }
1221 } 1208 }
1222 1209
1223 if (m_rootPart.PhysActor != null) 1210 so.AbsolutePosition = attachOffset;
1224 { 1211 so.RootPart.AttachedPos = attachOffset;
1225 m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); 1212 so.IsAttachment = true;
1226 m_rootPart.PhysActor = null; 1213 so.RootPart.SetParentLocalId(avatar.LocalId);
1227 } 1214 so.AttachmentPoint = attachmentpoint;
1228
1229 AbsolutePosition = AttachOffset;
1230 m_rootPart.AttachedPos = AttachOffset;
1231 m_rootPart.IsAttachment = true;
1232
1233 m_rootPart.SetParentLocalId(avatar.LocalId);
1234 SetAttachmentPoint(Convert.ToByte(attachmentpoint));
1235 1215
1236 avatar.AddAttachment(this); 1216 avatar.AddAttachment(this);
1237 1217
@@ -1254,7 +1234,7 @@ namespace OpenSim.Region.Framework.Scenes
1254 { 1234 {
1255 m_log.WarnFormat( 1235 m_log.WarnFormat(
1256 "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present", 1236 "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present",
1257 UUID, agentID, Scene.RegionInfo.RegionName); 1237 UUID, avatar.ControllingClient.AgentId, Scene.RegionInfo.RegionName);
1258 } 1238 }
1259 } 1239 }
1260 1240
@@ -1263,11 +1243,6 @@ namespace OpenSim.Region.Framework.Scenes
1263 return m_rootPart.Shape.State; 1243 return m_rootPart.Shape.State;
1264 } 1244 }
1265 1245
1266 public void ClearPartAttachmentData()
1267 {
1268 SetAttachmentPoint((Byte)0);
1269 }
1270
1271 public void DetachToGround() 1246 public void DetachToGround()
1272 { 1247 {
1273 ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar); 1248 ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar);
@@ -1788,19 +1763,19 @@ namespace OpenSim.Region.Framework.Scenes
1788 1763
1789 // This is only necessary when userExposed is false! 1764 // This is only necessary when userExposed is false!
1790 1765
1791 bool previousAttachmentStatus = dupe.IsAttachment; 1766 bool previousAttachmentStatus = dupe.IsAttachment;
1792 1767
1793 if (!userExposed) 1768 if (!userExposed)
1794 dupe.IsAttachment = true; 1769 dupe.IsAttachment = true;
1795 1770
1796 if (!userExposed) 1771 if (!userExposed)
1797 dupe.RootPart.IsAttachment = true; 1772 dupe.RootPart.IsAttachment = true;
1798 1773
1799 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); 1774 dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
1800 if (!userExposed) 1775 if (!userExposed)
1801 { 1776 {
1802 dupe.IsAttachment = previousAttachmentStatus; 1777 dupe.IsAttachment = previousAttachmentStatus;
1803 } 1778 }
1804 1779
1805 if (!userExposed) 1780 if (!userExposed)
1806 { 1781 {
@@ -1855,8 +1830,8 @@ namespace OpenSim.Region.Framework.Scenes
1855 dupe.UpdateParentIDs(); 1830 dupe.UpdateParentIDs();
1856 dupe.HasGroupChanged = true; 1831 dupe.HasGroupChanged = true;
1857 dupe.AttachToBackup(); 1832 dupe.AttachToBackup();
1858 1833 }
1859 ScheduleGroupForFullUpdate(); 1834 ScheduleGroupForFullUpdate();
1860 // Need to duplicate the physics actor as well 1835 // Need to duplicate the physics actor as well
1861 if (part.PhysActor != null && userExposed) 1836 if (part.PhysActor != null && userExposed)
1862 { 1837 {
@@ -3175,7 +3150,6 @@ namespace OpenSim.Region.Framework.Scenes
3175 { 3150 {
3176 if (IsAttachment) 3151 if (IsAttachment)
3177 { 3152 {
3178 m_rootPart.StoreUndoState(UndoType.STATE_GROUP_POSITION);
3179 m_rootPart.AttachedPos = pos; 3153 m_rootPart.AttachedPos = pos;
3180 } 3154 }
3181 if (RootPart.GetStatusSandbox()) 3155 if (RootPart.GetStatusSandbox())
@@ -3207,9 +3181,9 @@ namespace OpenSim.Region.Framework.Scenes
3207 { 3181 {
3208 SceneObjectPart part = GetChildPart(localID); 3182 SceneObjectPart part = GetChildPart(localID);
3209 3183
3210// SceneObjectPart[] parts = m_parts.GetArray(); 3184 SceneObjectPart[] parts = m_parts.GetArray();
3211// for (int i = 0; i < parts.Length; i++) 3185 for (int i = 0; i < parts.Length; i++)
3212// parts[i].StoreUndoState(); 3186 parts[i].StoreUndoState();
3213 3187
3214 if (part != null) 3188 if (part != null)
3215 { 3189 {
@@ -3368,8 +3342,6 @@ namespace OpenSim.Region.Framework.Scenes
3368 { 3342 {
3369 SceneObjectPart part = GetChildPart(localID); 3343 SceneObjectPart part = GetChildPart(localID);
3370 SceneObjectPart[] parts = m_parts.GetArray(); 3344 SceneObjectPart[] parts = m_parts.GetArray();
3371 for (int i = 0; i < parts.Length; i++)
3372 parts[i].StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3373 3345
3374 if (part != null) 3346 if (part != null)
3375 { 3347 {
@@ -3440,14 +3412,7 @@ namespace OpenSim.Region.Framework.Scenes
3440 3412
3441 Quaternion axRot = rot; 3413 Quaternion axRot = rot;
3442 Quaternion oldParentRot = m_rootPart.RotationOffset; 3414 Quaternion oldParentRot = m_rootPart.RotationOffset;
3443 3415 m_rootPart.StoreUndoState();
3444 m_rootPart.StoreUndoState(UndoType.STATE_PRIM_ROTATION);
3445 bool cancelUndo = false;
3446 if (!m_rootPart.Undoing)
3447 {
3448 m_rootPart.Undoing = true;
3449 cancelUndo = true;
3450 }
3451 3416
3452 //Don't use UpdateRotation because it schedules an update prematurely 3417 //Don't use UpdateRotation because it schedules an update prematurely
3453 m_rootPart.RotationOffset = rot; 3418 m_rootPart.RotationOffset = rot;
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index 893faf8..6988718 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -852,7 +852,7 @@ namespace OpenSim.Region.Framework.Scenes
852 852
853 set 853 set
854 { 854 {
855 StoreUndoState(UndoType.STATE_PRIM_ROTATION); 855 StoreUndoState();
856 m_rotationOffset = value; 856 m_rotationOffset = value;
857 857
858 PhysicsActor actor = PhysActor; 858 PhysicsActor actor = PhysActor;
@@ -3590,7 +3590,8 @@ namespace OpenSim.Region.Framework.Scenes
3590 m_parentGroup.ScheduleGroupForTerseUpdate(); 3590 m_parentGroup.ScheduleGroupForTerseUpdate();
3591 //m_parentGroup.ScheduleGroupForFullUpdate(); 3591 //m_parentGroup.ScheduleGroupForFullUpdate();
3592 } 3592 }
3593 public void StoreUndoState(UndoType type) 3593
3594 public void StoreUndoState()
3594 { 3595 {
3595 StoreUndoState(false); 3596 StoreUndoState(false);
3596 } 3597 }
@@ -3613,57 +3614,45 @@ namespace OpenSim.Region.Framework.Scenes
3613 // TODO: May need to fix for group comparison 3614 // TODO: May need to fix for group comparison
3614 if (last.Compare(this)) 3615 if (last.Compare(this))
3615 { 3616 {
3616 // m_log.DebugFormat( 3617 // m_log.DebugFormat(
3617 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", 3618 // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}",
3618 // Name, LocalId, m_undo.Count); 3619 // Name, LocalId, m_undo.Count);
3619 3620
3620 return; 3621 return;
3621 } 3622 }
3622 } 3623 }
3623 } 3624 }
3624 3625
3625 // m_log.DebugFormat( 3626 // m_log.DebugFormat(
3626 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", 3627 // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}",
3627 // Name, LocalId, forGroup, m_undo.Count); 3628 // Name, LocalId, forGroup, m_undo.Count);
3628 3629
3629 if (m_parentGroup.GetSceneMaxUndo() > 0) 3630 if (m_parentGroup.GetSceneMaxUndo() > 0)
3630 { 3631 {
3631 UndoState nUndo = new UndoState(this, forGroup); 3632 UndoState nUndo = new UndoState(this, forGroup);
3632
3633 UndoState nUndo = new UndoState(this, type);
3634 3633
3635 if (lastUndo != null)
3636 {
3637 TimeSpan ts = DateTime.Now.Subtract(lastUndo.LastUpdated);
3638 if (ts.TotalMilliseconds < 500)
3639 {
3640 //Delete the last entry since it was less than 500 milliseconds ago
3641 nUndo.Merge(lastUndo);
3642 m_undo.Pop();
3643 }
3644 }
3645 m_undo.Push(nUndo); 3634 m_undo.Push(nUndo);
3646 3635
3647 if (m_redo.Count > 0) 3636 if (m_redo.Count > 0)
3648 m_redo.Clear(); 3637 m_redo.Clear();
3649 3638
3650 // m_log.DebugFormat( 3639 // m_log.DebugFormat(
3651 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", 3640 // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}",
3652 // Name, LocalId, forGroup, m_undo.Count); 3641 // Name, LocalId, forGroup, m_undo.Count);
3653 } 3642 }
3654 } 3643 }
3655 } 3644 }
3656 } 3645 }
3657// else 3646 // else
3658// { 3647 // {
3659// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); 3648 // m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId);
3660// } 3649 // }
3661 } 3650 }
3662// else 3651 // else
3663// { 3652 // {
3664// m_log.DebugFormat( 3653 // m_log.DebugFormat(
3665// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); 3654 // "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId);
3666// } 3655 // }
3667 } 3656 }
3668 3657
3669 /// <summary> 3658 /// <summary>
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index de9b1f3..8ee7d89 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1364,9 +1364,12 @@ namespace OpenSim.Region.Framework.Scenes
1364 /// <summary> 1364 /// <summary>
1365 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1365 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1366 /// </summary> 1366 /// </summary>
1367 /// <summary>
1368 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1369 /// </summary>
1367 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) 1370 public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
1368 { 1371 {
1369// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name); 1372 // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name);
1370 1373
1371 //if (m_isChildAgent) 1374 //if (m_isChildAgent)
1372 //{ 1375 //{
@@ -1389,7 +1392,6 @@ namespace OpenSim.Region.Framework.Scenes
1389 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); 1392 m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902");
1390 1393
1391 m_pos = m_LastFinitePos; 1394 m_pos = m_LastFinitePos;
1392
1393 if (!m_pos.IsFinite()) 1395 if (!m_pos.IsFinite())
1394 { 1396 {
1395 m_pos.X = 127f; 1397 m_pos.X = 127f;
@@ -1459,6 +1461,7 @@ namespace OpenSim.Region.Framework.Scenes
1459 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); 1461 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback);
1460 } 1462 }
1461 } 1463 }
1464
1462 lock (scriptedcontrols) 1465 lock (scriptedcontrols)
1463 { 1466 {
1464 if (scriptedcontrols.Count > 0) 1467 if (scriptedcontrols.Count > 0)
@@ -1473,9 +1476,6 @@ namespace OpenSim.Region.Framework.Scenes
1473 1476
1474 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1477 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1475 { 1478 {
1476 m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick.
1477 Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED");
1478
1479 // TODO: This doesn't prevent the user from walking yet. 1479 // TODO: This doesn't prevent the user from walking yet.
1480 // Setting parent ID would fix this, if we knew what value 1480 // Setting parent ID would fix this, if we knew what value
1481 // to use. Or we could add a m_isSitting variable. 1481 // to use. Or we could add a m_isSitting variable.
@@ -1530,20 +1530,6 @@ namespace OpenSim.Region.Framework.Scenes
1530 if (actor.Flying != oldflying) 1530 if (actor.Flying != oldflying)
1531 update_movementflag = true; 1531 update_movementflag = true;
1532 1532
1533 if (m_animator.m_jumping) // add for jumping
1534 update_movementflag = true;
1535
1536 if (q != m_bodyRot)
1537 {
1538 m_bodyRot = q;
1539 update_rotation = true;
1540 }
1541
1542 //guilty until proven innocent..
1543 bool Nudging = true;
1544 //Basically, if there is at least one non-nudge control then we don't need
1545 //to worry about stopping the avatar
1546
1547 if (m_parentID == 0) 1533 if (m_parentID == 0)
1548 { 1534 {
1549 bool bAllowUpdateMoveToPosition = false; 1535 bool bAllowUpdateMoveToPosition = false;
@@ -1557,12 +1543,10 @@ namespace OpenSim.Region.Framework.Scenes
1557 else 1543 else
1558 dirVectors = Dir_Vectors; 1544 dirVectors = Dir_Vectors;
1559 1545
1560 bool[] isNudge = GetDirectionIsNudge(); 1546 // The fact that m_movementflag is a byte needs to be fixed
1561 1547 // it really should be a uint
1562 1548 // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction.
1563 1549 uint nudgehack = 250;
1564
1565
1566 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) 1550 foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS)
1567 { 1551 {
1568 if (((uint)flags & (uint)DCF) != 0) 1552 if (((uint)flags & (uint)DCF) != 0)
@@ -1572,30 +1556,43 @@ namespace OpenSim.Region.Framework.Scenes
1572 try 1556 try
1573 { 1557 {
1574 agent_control_v3 += dirVectors[i]; 1558 agent_control_v3 += dirVectors[i];
1575 if (isNudge[i] == false) 1559 //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]);
1576 {
1577 Nudging = false;
1578 }
1579 } 1560 }
1580 catch (IndexOutOfRangeException) 1561 catch (IndexOutOfRangeException)
1581 { 1562 {
1582 // Why did I get this? 1563 // Why did I get this?
1583 } 1564 }
1584 1565
1585 if ((m_movementflag & (uint)DCF) == 0) 1566 if ((m_movementflag & (byte)(uint)DCF) == 0)
1586 { 1567 {
1568 if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1569 {
1570 m_movementflag |= (byte)nudgehack;
1571 }
1587 1572
1588// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); 1573 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF);
1589 m_movementflag += (byte)(uint)DCF; 1574 m_movementflag += (byte)(uint)DCF;
1590 update_movementflag = true; 1575 update_movementflag = true;
1591 } 1576 }
1592 } 1577 }
1593 else 1578 else
1594 { 1579 {
1595 if ((m_movementflag & (uint)DCF) != 0) 1580 if ((m_movementflag & (byte)(uint)DCF) != 0 ||
1581 ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE)
1582 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1583 ) // This or is for Nudge forward
1596 { 1584 {
1597 m_movementflag -= (byte)(uint)DCF; 1585 // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF);
1586 m_movementflag -= ((byte)(uint)DCF);
1598 update_movementflag = true; 1587 update_movementflag = true;
1588
1589 /*
1590 if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE)
1591 && ((m_movementflag & (byte)nudgehack) == nudgehack))
1592 {
1593 m_log.Debug("Removed Hack flag");
1594 }
1595 */
1599 } 1596 }
1600 else 1597 else
1601 { 1598 {
@@ -1605,128 +1602,19 @@ namespace OpenSim.Region.Framework.Scenes
1605 1602
1606 i++; 1603 i++;
1607 } 1604 }
1608 if (MovingToTarget)
1609 {
1610 m_moveToPositionTarget = Vector3.Zero;
1611 m_moveToPositionInProgress = false;
1612 update_movementflag = true;
1613 bAllowUpdateMoveToPosition = false;
1614 }
1615 1605
1616 if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) 1606 if (MovingToTarget)
1617 { 1607 {
1618/* 1608 // If the user has pressed a key then we want to cancel any move to target.
1619 bool twoD = false; 1609 if (DCFlagKeyPressed)
1620 bool there = false;
1621 if (Animator != null)
1622 {
1623 switch (Animator.CurrentMovementAnimation)
1624 {
1625 case "STAND":
1626 case "WALK":
1627 case "RUN":
1628 case "CROUCH":
1629 case "CROUCHWALK":
1630 {
1631 twoD = true;
1632 }
1633 break;
1634 }
1635 }
1636
1637 if (twoD)
1638 {
1639*/
1640 Vector3 abspos = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, 0.0f);
1641 Vector3 tgt = new Vector3(m_moveToPositionTarget.X, m_moveToPositionTarget.Y, 0.0f);
1642/* if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) there = true;
1643 }
1644 else
1645 {
1646 if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) there = true;
1647 }
1648*/
1649 //Check the error term of the current position in relation to the target position
1650// if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f)
1651// if (there)
1652 if (Util.GetDistanceTo(abspos, tgt) <= 0.5f)
1653 { 1610 {
1654 ResetMoveToTarget(); 1611 ResetMoveToTarget();
1655 update_movementflag = true; 1612 update_movementflag = true;
1656 } 1613 }
1657 else if (bAllowUpdateMoveToPosition) 1614 else if (bAllowUpdateMoveToPosition)
1658 { 1615 {
1659 try 1616 if (HandleMoveToTargetUpdate(ref agent_control_v3))
1660 { 1617 update_movementflag = true;
1661 // move avatar in 2D at one meter/second towards target, in avatar coordinate frame.
1662 // This movement vector gets added to the velocity through AddNewMovement().
1663 // Theoretically we might need a more complex PID approach here if other
1664 // unknown forces are acting on the avatar and we need to adaptively respond
1665 // to such forces, but the following simple approach seems to works fine.
1666 Vector3 LocalVectorToTarget3D =
1667// (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1668 (tgt - abspos)
1669 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords
1670 // Ignore z component of vector
1671 Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1672 LocalVectorToTarget2D.Normalize();
1673
1674 //We're not nudging
1675 Nudging = false;
1676 agent_control_v3 += LocalVectorToTarget2D;
1677
1678 // update avatar movement flags. the avatar coordinate system is as follows:
1679 //
1680 // +X (forward)
1681 //
1682 // ^
1683 // |
1684 // |
1685 // |
1686 // |
1687 // (left) +Y <--------o--------> -Y
1688 // avatar
1689 // |
1690 // |
1691 // |
1692 // |
1693 // v
1694 // -X
1695 //
1696
1697 // based on the above avatar coordinate system, classify the movement into
1698 // one of left/right/back/forward.
1699 if (LocalVectorToTarget2D.Y > 0)//MoveLeft
1700 {
1701 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1702 //AgentControlFlags
1703 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT;
1704 update_movementflag = true;
1705 }
1706 else if (LocalVectorToTarget2D.Y < 0) //MoveRight
1707 {
1708 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1709 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT;
1710 update_movementflag = true;
1711 }
1712 if (LocalVectorToTarget2D.X < 0) //MoveBack
1713 {
1714 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1715 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK;
1716 update_movementflag = true;
1717 }
1718 else if (LocalVectorToTarget2D.X > 0) //Move Forward
1719 {
1720 m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1721 AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD;
1722 update_movementflag = true;
1723 }
1724 }
1725 catch (Exception e)
1726 {
1727 //Avoid system crash, can be slower but...
1728 m_log.DebugFormat("Crash! {0}", e.ToString());
1729 }
1730 } 1618 }
1731 } 1619 }
1732 } 1620 }
@@ -1759,31 +1647,26 @@ namespace OpenSim.Region.Framework.Scenes
1759 // which occurs later in the main scene loop 1647 // which occurs later in the main scene loop
1760 if (update_movementflag || (update_rotation && DCFlagKeyPressed)) 1648 if (update_movementflag || (update_rotation && DCFlagKeyPressed))
1761 { 1649 {
1762// m_log.DebugFormat( 1650 // m_log.DebugFormat(
1763// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", 1651 // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}",
1764// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); 1652 // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation);
1765 1653
1766 AddNewMovement(agent_control_v3, q, Nudging); 1654 AddNewMovement(agent_control_v3);
1767
1768
1769 } 1655 }
1770// else 1656 // else
1771// { 1657 // {
1772// if (!update_movementflag) 1658 // if (!update_movementflag)
1773// { 1659 // {
1774// m_log.DebugFormat( 1660 // m_log.DebugFormat(
1775// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", 1661 // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false",
1776// m_scene.RegionInfo.RegionName, agent_control_v3, Name); 1662 // m_scene.RegionInfo.RegionName, agent_control_v3, Name);
1777// } 1663 // }
1778// } 1664 // }
1779 1665
1780 if (update_movementflag && m_parentID == 0) 1666 if (update_movementflag && m_parentID == 0)
1781 Animator.UpdateMovementAnimations(); 1667 Animator.UpdateMovementAnimations();
1782 } 1668 }
1783 1669
1784 if (update_movementflag && !SitGround)
1785 Animator.UpdateMovementAnimations();
1786
1787 m_scene.EventManager.TriggerOnClientMovement(this); 1670 m_scene.EventManager.TriggerOnClientMovement(this);
1788 1671
1789 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 1672 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
@@ -1799,24 +1682,20 @@ namespace OpenSim.Region.Framework.Scenes
1799 /// <returns>True if movement has been updated in some way. False otherwise.</returns> 1682 /// <returns>True if movement has been updated in some way. False otherwise.</returns>
1800 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) 1683 public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3)
1801 { 1684 {
1802// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); 1685 // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name);
1686
1803 bool updated = false; 1687 bool updated = false;
1804 1688
1805 public void StopMoveToPosition() 1689 // m_log.DebugFormat(
1806 { 1690 // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}",
1807 m_moveToPositionTarget = Vector3.Zero; 1691 // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving);
1808 m_moveToPositionInProgress = false;
1809 }
1810 1692
1811 public void DoMoveToPosition(Object sender, string method, List<String> args) 1693 if (!m_autopilotMoving)
1812 {
1813//Console.WriteLine("SP:DoMoveToPosition");
1814 try
1815 { 1694 {
1816 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); 1695 double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget);
1817// m_log.DebugFormat( 1696 // m_log.DebugFormat(
1818// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", 1697 // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}",
1819// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); 1698 // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget);
1820 1699
1821 // Check the error term of the current position in relation to the target position 1700 // Check the error term of the current position in relation to the target position
1822 if (distanceToTarget <= 1) 1701 if (distanceToTarget <= 1)
@@ -1839,7 +1718,7 @@ namespace OpenSim.Region.Framework.Scenes
1839 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords 1718 (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords
1840 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords 1719 * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords
1841 // Ignore z component of vector 1720 // Ignore z component of vector
1842// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); 1721 // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f);
1843 LocalVectorToTarget3D.Normalize(); 1722 LocalVectorToTarget3D.Normalize();
1844 1723
1845 // update avatar movement flags. the avatar coordinate system is as follows: 1724 // update avatar movement flags. the avatar coordinate system is as follows:
@@ -1905,9 +1784,9 @@ namespace OpenSim.Region.Framework.Scenes
1905 updated = true; 1784 updated = true;
1906 } 1785 }
1907 1786
1908// m_log.DebugFormat( 1787 // m_log.DebugFormat(
1909// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", 1788 // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}",
1910// LocalVectorToTarget3D, agent_control_v3, Name); 1789 // LocalVectorToTarget3D, agent_control_v3, Name);
1911 1790
1912 agent_control_v3 += LocalVectorToTarget3D; 1791 agent_control_v3 += LocalVectorToTarget3D;
1913 } 1792 }
@@ -1917,7 +1796,7 @@ namespace OpenSim.Region.Framework.Scenes
1917 m_log.DebugFormat("Crash! {0}", e.ToString()); 1796 m_log.DebugFormat("Crash! {0}", e.ToString());
1918 } 1797 }
1919 } 1798 }
1920 } 1799 }
1921 1800
1922 return updated; 1801 return updated;
1923 } 1802 }
@@ -2746,41 +2625,21 @@ namespace OpenSim.Region.Framework.Scenes
2746 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector 2625 /// Rotate the avatar to the given rotation and apply a movement in the given relative vector
2747 /// </summary> 2626 /// </summary>
2748 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param> 2627 /// <param name="vec">The vector in which to move. This is relative to the rotation argument</param>
2749 /// <param name="rotation">The direction in which this avatar should now face. 2628 public void AddNewMovement(Vector3 vec)
2750 public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging)
2751 { 2629 {
2752 if (m_isChildAgent)
2753 {
2754 // WHAT???
2755 m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent");
2756
2757 return;
2758 }
2759
2760 m_perfMonMS = Util.EnvironmentTickCount(); 2630 m_perfMonMS = Util.EnvironmentTickCount();
2761 2631
2762 Vector3 direc = vec * Rotation; 2632 Vector3 direc = vec * Rotation;
2763 direc.Normalize(); 2633 direc.Normalize();
2764 PhysicsActor actor = m_physicsActor;
2765
2766 if (actor.Flying != m_flyingOld) // add for fly velocity control
2767 {
2768 m_flyingOld = actor.Flying; // add for fly velocity control
2769 if (!actor.Flying) m_wasFlying = true; // add for fly velocity control
2770 }
2771
2772 if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control
2773
2774 if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up.
2775 2634
2776 direc *= 0.03f * 128f * m_speedModifier; 2635 direc *= 0.03f * 128f * m_speedModifier;
2777 2636
2637 PhysicsActor actor = m_physicsActor;
2778 if (actor != null) 2638 if (actor != null)
2779 { 2639 {
2780 if (actor.Flying) 2640 if (actor.Flying)
2781 { 2641 {
2782// rm speed mod direc *= 4.0f; 2642 direc *= 4.0f;
2783 direc *= 5.2f; // for speed mod
2784 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); 2643 //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0));
2785 //bool colliding = (m_physicsActor.IsColliding==true); 2644 //bool colliding = (m_physicsActor.IsColliding==true);
2786 //if (controlland) 2645 //if (controlland)
@@ -2793,34 +2652,22 @@ namespace OpenSim.Region.Framework.Scenes
2793 // m_log.Info("[AGENT]: Stop FLying"); 2652 // m_log.Info("[AGENT]: Stop FLying");
2794 //} 2653 //}
2795 } 2654 }
2796 if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add
2797 {
2798 direc *= 0.0f;
2799 }
2800 /* This jumping section removed to SPA
2801 else if (!actor.Flying && actor.IsColliding) 2655 else if (!actor.Flying && actor.IsColliding)
2802 { 2656 {
2803 if (direc.Z > 2.0f) 2657 if (direc.Z > 2.0f)
2804 { 2658 {
2805 if(m_animator.m_animTickJump == -1) 2659 direc.Z *= 3.0f;
2806 { 2660
2807 direc.Z *= 3.0f; // jump 2661 // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored.
2808 } 2662 Animator.TrySetMovementAnimation("PREJUMP");
2809 else 2663 Animator.TrySetMovementAnimation("JUMP");
2810 {
2811 direc.Z *= 0.1f; // prejump
2812 }
2813 / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs
2814 Animator.TrySetMovementAnimation("PREJUMP");
2815 Animator.TrySetMovementAnimation("JUMP");
2816 * /
2817 } 2664 }
2818 } */ 2665 }
2819 } 2666 }
2820 2667
2821 // TODO: Add the force instead of only setting it to support multiple forces per frame? 2668 // TODO: Add the force instead of only setting it to support multiple forces per frame?
2822 m_forceToApply = direc; 2669 m_forceToApply = direc;
2823 m_isNudging = Nudging; 2670
2824 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); 2671 m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS));
2825 } 2672 }
2826 2673
@@ -3961,7 +3808,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
3961 { 3808 {
3962 StartCollidingMessage.Colliders = colliding; 3809 StartCollidingMessage.Colliders = colliding;
3963 3810
3964 foreach (SceneObjectGroup att in Attachments) 3811 foreach (SceneObjectGroup att in GetAttachments())
3965 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); 3812 Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage);
3966 } 3813 }
3967 } 3814 }
@@ -3996,7 +3843,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
3996 { 3843 {
3997 EndCollidingMessage.Colliders = colliding; 3844 EndCollidingMessage.Colliders = colliding;
3998 3845
3999 foreach (SceneObjectGroup att in Attachments) 3846 foreach (SceneObjectGroup att in GetAttachments())
4000 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); 3847 Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage);
4001 } 3848 }
4002 } 3849 }
@@ -4517,7 +4364,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4517 List<AvatarAttachment> attachments = m_appearance.GetAttachments(); 4364 List<AvatarAttachment> attachments = m_appearance.GetAttachments();
4518 foreach (AvatarAttachment attach in attachments) 4365 foreach (AvatarAttachment attach in attachments)
4519 { 4366 {
4520 if (m_isDeleted) 4367 if (IsDeleted)
4521 return; 4368 return;
4522 4369
4523 int p = attach.AttachPoint; 4370 int p = attach.AttachPoint;
@@ -4603,7 +4450,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4603 public void SaveChangedAttachments() 4450 public void SaveChangedAttachments()
4604 { 4451 {
4605 // Need to copy this list because DetachToInventoryPrep mods it 4452 // Need to copy this list because DetachToInventoryPrep mods it
4606 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(Attachments.ToArray()); 4453 List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(GetAttachments().ToArray());
4607 4454
4608 IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule; 4455 IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule;
4609 if (attachmentsModule != null) 4456 if (attachmentsModule != null)
@@ -4612,12 +4459,12 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju
4612 { 4459 {
4613 if (grp.HasGroupChanged) // Resizer scripts? 4460 if (grp.HasGroupChanged) // Resizer scripts?
4614 { 4461 {
4615 grp.RootPart.IsAttachment = false; 4462 grp.IsAttachment = false;
4616 grp.AbsolutePosition = grp.RootPart.AttachedPos; 4463 grp.AbsolutePosition = grp.RootPart.AttachedPos;
4617// grp.DetachToInventoryPrep(); 4464// grp.DetachToInventoryPrep();
4618 attachmentsModule.UpdateKnownItem(ControllingClient, 4465 attachmentsModule.UpdateKnownItem(ControllingClient,
4619 grp, grp.GetFromItemID(), grp.OwnerID); 4466 grp, grp.GetFromItemID(), grp.OwnerID);
4620 grp.RootPart.IsAttachment = true; 4467 grp.IsAttachment = true;
4621 } 4468 }
4622 } 4469 }
4623 } 4470 }
diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs
index 2db718c..f9e118b 100644
--- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs
+++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs
@@ -23,104 +23,104 @@
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30 30
31 31
32namespace OpenSim.Region.OptionalModules.World.AutoBackup 32namespace OpenSim.Region.OptionalModules.World.AutoBackup
33{ 33{
34 /// <summary>AutoBackupModuleState: Auto-Backup state for one region (scene). 34 /// <summary>AutoBackupModuleState: Auto-Backup state for one region (scene).
35 /// If you use this class in any way outside of AutoBackupModule, you should treat the class as opaque. 35 /// If you use this class in any way outside of AutoBackupModule, you should treat the class as opaque.
36 /// Since it is not part of the framework, you really should not rely upon it outside of the AutoBackupModule implementation. 36 /// Since it is not part of the framework, you really should not rely upon it outside of the AutoBackupModule implementation.
37 /// </summary> 37 /// </summary>
38 /// 38 ///
39 public class AutoBackupModuleState 39 public class AutoBackupModuleState
40 { 40 {
41 private Dictionary<Guid, string> m_liveRequests = null; 41 private Dictionary<Guid, string> m_liveRequests = null;
42 42
43 public AutoBackupModuleState() 43 public AutoBackupModuleState()
44 { 44 {
45 this.Enabled = false; 45 this.Enabled = false;
46 this.BackupDir = "."; 46 this.BackupDir = ".";
47 this.BusyCheck = true; 47 this.BusyCheck = true;
48 this.Timer = null; 48 this.Timer = null;
49 this.NamingType = NamingType.Time; 49 this.NamingType = NamingType.Time;
50 this.Script = null; 50 this.Script = null;
51 } 51 }
52 52
53 public Dictionary<Guid, string> LiveRequests 53 public Dictionary<Guid, string> LiveRequests
54 { 54 {
55 get { 55 get {
56 return this.m_liveRequests ?? 56 return this.m_liveRequests ??
57 (this.m_liveRequests = new Dictionary<Guid, string>(1)); 57 (this.m_liveRequests = new Dictionary<Guid, string>(1));
58 } 58 }
59 } 59 }
60 60
61 public bool Enabled 61 public bool Enabled
62 { 62 {
63 get; 63 get;
64 set; 64 set;
65 } 65 }
66 66
67 public System.Timers.Timer Timer 67 public System.Timers.Timer Timer
68 { 68 {
69 get; 69 get;
70 set; 70 set;
71 } 71 }
72 72
73 public double IntervalMinutes 73 public double IntervalMinutes
74 { 74 {
75 get 75 get
76 { 76 {
77 if (this.Timer == null) 77 if (this.Timer == null)
78 { 78 {
79 return -1.0; 79 return -1.0;
80 } 80 }
81 else 81 else
82 { 82 {
83 return this.Timer.Interval / 60000.0; 83 return this.Timer.Interval / 60000.0;
84 } 84 }
85 } 85 }
86 } 86 }
87 87
88 public bool BusyCheck 88 public bool BusyCheck
89 { 89 {
90 get; 90 get;
91 set; 91 set;
92 } 92 }
93 93
94 public string Script 94 public string Script
95 { 95 {
96 get; 96 get;
97 set; 97 set;
98 } 98 }
99 99
100 public string BackupDir 100 public string BackupDir
101 { 101 {
102 get; 102 get;
103 set; 103 set;
104 } 104 }
105 105
106 public NamingType NamingType 106 public NamingType NamingType
107 { 107 {
108 get; 108 get;
109 set; 109 set;
110 } 110 }
111 111
112 public new string ToString() 112 public new string ToString()
113 { 113 {
114 string retval = ""; 114 string retval = "";
115 115
116 retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n"; 116 retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n";
117 retval += "[AUTO BACKUP]: Interval: " + IntervalMinutes + " minutes" + "\n"; 117 retval += "[AUTO BACKUP]: Interval: " + IntervalMinutes + " minutes" + "\n";
118 retval += "[AUTO BACKUP]: Do Busy Check: " + (BusyCheck ? "Yes" : "No") + "\n"; 118 retval += "[AUTO BACKUP]: Do Busy Check: " + (BusyCheck ? "Yes" : "No") + "\n";
119 retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n"; 119 retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n";
120 retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n"; 120 retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n";
121 retval += "[AUTO BACKUP]: Script: " + Script + "\n"; 121 retval += "[AUTO BACKUP]: Script: " + Script + "\n";
122 return retval; 122 return retval;
123 } 123 }
124 } 124 }
125} 125}
126 126
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index 9ec8a42..0c1da47 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2166,8 +2166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
2166 UUID x = module.CreateNPC(firstname, 2166 UUID x = module.CreateNPC(firstname,
2167 lastname, 2167 lastname,
2168 new Vector3((float) position.x, (float) position.y, (float) position.z), 2168 new Vector3((float) position.x, (float) position.y, (float) position.z),
2169 World, 2169 World,appearance);
2170 appearance);
2171 2170
2172 return new LSL_Key(x.ToString()); 2171 return new LSL_Key(x.ToString());
2173 } 2172 }