aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs')
-rw-r--r--OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs83
1 files changed, 49 insertions, 34 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 3ccf9f4..ab7e932 100644
--- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
@@ -221,9 +221,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
221 // If we're an NPC then skip all the item checks and manipulations since we don't have an 221 // If we're an NPC then skip all the item checks and manipulations since we don't have an
222 // inventory right now. 222 // inventory right now.
223 if (sp.PresenceType == PresenceType.Npc) 223 if (sp.PresenceType == PresenceType.Npc)
224 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); 224 RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p, true);
225 else 225 else
226 RezSingleAttachmentFromInventory(sp, attach.ItemID, p); 226 RezSingleAttachmentFromInventory(sp, attach.ItemID, p | (uint)0x80);
227 } 227 }
228 catch (Exception e) 228 catch (Exception e)
229 { 229 {
@@ -283,13 +283,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
283 283
284 sp.ClearAttachments(); 284 sp.ClearAttachments();
285 } 285 }
286 286
287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) 287 public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append)
288 { 288 {
289 if (!Enabled) 289 if (!Enabled)
290 return false; 290 return false;
291 291
292 if (AttachObjectInternal(sp, group, attachmentPt, silent, temp)) 292 if (AttachObjectInternal(sp, group, attachmentPt, silent, temp, append))
293 { 293 {
294 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); 294 m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID);
295 return true; 295 return true;
@@ -298,7 +298,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
298 return false; 298 return false;
299 } 299 }
300 300
301 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp) 301 private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append)
302 { 302 {
303// m_log.DebugFormat( 303// m_log.DebugFormat(
304// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", 304// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
@@ -313,7 +313,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
313 return false; 313 return false;
314 } 314 }
315 315
316 if (sp.GetAttachments(attachmentPt).Contains(group)) 316 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
317 if (attachments.Contains(group))
317 { 318 {
318// m_log.WarnFormat( 319// m_log.WarnFormat(
319// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached", 320// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
@@ -322,22 +323,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
322 return false; 323 return false;
323 } 324 }
324 325
325 // Remove any previous attachments 326 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
326 List<SceneObjectGroup> existingAttachments = sp.GetAttachments(attachmentPt); 327 while (attachments.Count >= 5)
327 string existingAttachmentScriptState = null; 328 {
329 if (attachments[0].FromItemID != UUID.Zero)
330 DetachSingleAttachmentToInv(sp, attachments[0]);
331 attachments.RemoveAt(0);
332 }
328 333
329 // At the moment we can only deal with a single attachment 334 // If we're not appending, remove the rest as well
330 if (existingAttachments.Count != 0 && existingAttachments[0].FromItemID != UUID.Zero) 335 if (attachments.Count != 0 && !append)
331 DetachSingleAttachmentToInv(sp, group); 336 {
337 foreach (SceneObjectGroup g in attachments)
338 {
339 if (g.FromItemID != UUID.Zero)
340 DetachSingleAttachmentToInv(sp, g);
341 }
342 }
332 343
333 lock (sp.AttachmentsSyncLock) 344 lock (sp.AttachmentsSyncLock)
334 { 345 {
335 Vector3 attachPos = group.AbsolutePosition; 346 Vector3 attachPos = group.AbsolutePosition;
336
337 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should
338 // be removed when that functionality is implemented in opensim
339 attachmentPt &= 0x7f;
340
341 // If the attachment point isn't the same as the one previously used 347 // If the attachment point isn't the same as the one previously used
342 // set it's offset position = 0 so that it appears on the attachment point 348 // set it's offset position = 0 so that it appears on the attachment point
343 // and not in a weird location somewhere unknown. 349 // and not in a weird location somewhere unknown.
@@ -365,16 +371,18 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
365 group.AbsolutePosition = attachPos; 371 group.AbsolutePosition = attachPos;
366 372
367 if (sp.PresenceType != PresenceType.Npc) 373 if (sp.PresenceType != PresenceType.Npc)
368 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); 374 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
369 375
370 AttachToAgent(sp, group, attachmentPt, attachPos, silent); 376 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
371 } 377 }
372 378
373 return true; 379 return true;
374 } 380 }
375 381
376 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) 382 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
377 { 383 {
384 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
385
378 // Add the new attachment to inventory if we don't already have it. 386 // Add the new attachment to inventory if we don't already have it.
379 if (!temp) 387 if (!temp)
380 { 388 {
@@ -382,7 +390,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
382 if (newAttachmentItemID == UUID.Zero) 390 if (newAttachmentItemID == UUID.Zero)
383 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; 391 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
384 392
385 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 393 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
386 } 394 }
387 } 395 }
388 396
@@ -395,8 +403,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
395// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", 403// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}",
396// (AttachmentPoint)AttachmentPt, itemID, sp.Name); 404// (AttachmentPoint)AttachmentPt, itemID, sp.Name);
397 405
398 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 406 bool append = (AttachmentPt & 0x80) != 0;
399 // be removed when that functionality is implemented in opensim
400 AttachmentPt &= 0x7f; 407 AttachmentPt &= 0x7f;
401 408
402 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). 409 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
@@ -425,7 +432,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
425 return null; 432 return null;
426 } 433 }
427 434
428 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); 435 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append);
429 } 436 }
430 437
431 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 438 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -821,8 +828,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
821 so.RemoveScriptInstances(true); 828 so.RemoveScriptInstances(true);
822 } 829 }
823 830
824 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 831 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
825 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 832 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append)
826 { 833 {
827 if (m_invAccessModule == null) 834 if (m_invAccessModule == null)
828 return null; 835 return null;
@@ -875,7 +882,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
875 // This will throw if the attachment fails 882 // This will throw if the attachment fails
876 try 883 try
877 { 884 {
878 AttachObjectInternal(sp, objatt, attachmentPt, false, false); 885 AttachObjectInternal(sp, objatt, attachmentPt, false, false, append);
879 } 886 }
880 catch (Exception e) 887 catch (Exception e)
881 { 888 {
@@ -911,7 +918,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
911 /// <param name="AttachmentPt"></param> 918 /// <param name="AttachmentPt"></param>
912 /// <param name="itemID"></param> 919 /// <param name="itemID"></param>
913 /// <param name="att"></param> 920 /// <param name="att"></param>
914 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 921 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att, bool append)
915 { 922 {
916// m_log.DebugFormat( 923// m_log.DebugFormat(
917// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 924// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
@@ -934,7 +941,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
934 if (item == null) 941 if (item == null)
935 return; 942 return;
936 943
937 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 944 int attFlag = append ? 0x80 : 0;
945 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID);
938 if (changed && m_scene.AvatarFactory != null) 946 if (changed && m_scene.AvatarFactory != null)
939 { 947 {
940// m_log.DebugFormat( 948// m_log.DebugFormat(
@@ -1018,12 +1026,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1018 return; 1026 return;
1019 } 1027 }
1020 1028
1021 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 1029 bool append = (AttachmentPt & 0x80) != 0;
1022 // be removed when that functionality is implemented in opensim
1023 AttachmentPt &= 0x7f; 1030 AttachmentPt &= 0x7f;
1024 1031
1025 // Calls attach with a Zero position 1032 // Calls attach with a Zero position
1026 AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); 1033 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append))
1034 {
1035// m_log.Debug(
1036// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
1037// + ", AttachmentPoint: " + AttachmentPt);
1038
1039 // Save avatar attachment information
1040 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
1041 }
1027 } 1042 }
1028 catch (Exception e) 1043 catch (Exception e)
1029 { 1044 {
@@ -1076,4 +1091,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1076 1091
1077 #endregion 1092 #endregion
1078 } 1093 }
1079} \ No newline at end of file 1094}