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.cs133
1 files changed, 73 insertions, 60 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
index 1c28f49..2dea14d 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 return AttachObjectInternal(sp, group, attachmentPt, silent, temp, false); 292 return AttachObjectInternal(sp, group, attachmentPt, silent, temp, append);
293 } 293 }
294 294
295 /// <summary> 295 /// <summary>
@@ -305,19 +305,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
305 private bool AttachObjectInternal( 305 private bool AttachObjectInternal(
306 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts) 306 IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts)
307 { 307 {
308 if (sp.GetAttachments().Contains(group))
309 {
310// m_log.WarnFormat(
311// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
312// group.Name, group.LocalId, sp.Name, AttachmentPt);
313
314 return false;
315 }
316
317// m_log.DebugFormat(
318// "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})",
319// group.Name, group.LocalId, sp.Name, attachmentPt, silent);
320
321 if (group.GetSittingAvatarsCount() != 0) 308 if (group.GetSittingAvatarsCount() != 0)
322 { 309 {
323// m_log.WarnFormat( 310// m_log.WarnFormat(
@@ -327,50 +314,67 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
327 return false; 314 return false;
328 } 315 }
329 316
330 Vector3 attachPos = group.AbsolutePosition; 317 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
331 318
332 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 319 if (attachments.Contains(group))
333 // be removed when that functionality is implemented in opensim
334 attachmentPt &= 0x7f;
335
336 // If the attachment point isn't the same as the one previously used
337 // set it's offset position = 0 so that it appears on the attachment point
338 // and not in a weird location somewhere unknown.
339 if (attachmentPt != (uint)AttachmentPoint.Default && attachmentPt != group.AttachmentPoint)
340 { 320 {
341 attachPos = Vector3.Zero; 321// m_log.WarnFormat(
322// "[ATTACHMENTS MODULE]: Ignoring request to attach {0} {1} to {2} on {3} since it's already attached",
323// group.Name, group.LocalId, sp.Name, AttachmentPt);
324
325 return false;
342 } 326 }
343 327
344 // AttachmentPt 0 (default) means the client chose to 'wear' the attachment. 328 // If we already have 5, remove the oldest until only 4 are left. Skip over temp ones
345 if (attachmentPt == (uint)AttachmentPoint.Default) 329 while (attachments.Count >= 5)
346 { 330 {
347 // Check object for stored attachment point 331 if (attachments[0].FromItemID != UUID.Zero)
348 attachmentPt = group.AttachmentPoint; 332 DetachSingleAttachmentToInv(sp, attachments[0]);
333 attachments.RemoveAt(0);
349 } 334 }
350 335
351 // if we still didn't find a suitable attachment point....... 336 // If we're not appending, remove the rest as well
352 if (attachmentPt == 0) 337 if (attachments.Count != 0 && !append)
353 { 338 {
354 // Stick it on left hand with Zero Offset from the attachment point. 339 foreach (SceneObjectGroup g in attachments)
355 attachmentPt = (uint)AttachmentPoint.LeftHand; 340 {
356 attachPos = Vector3.Zero; 341 if (g.FromItemID != UUID.Zero)
342 DetachSingleAttachmentToInv(sp, g);
343 }
357 } 344 }
358 345
359 // Remove any previous attachments
360 List<SceneObjectGroup> existingAttachments = sp.GetAttachments(attachmentPt);
361
362 // At the moment we can only deal with a single attachment
363 if (existingAttachments.Count != 0 && existingAttachments[0].FromItemID != UUID.Zero)
364 DetachSingleAttachmentToInv(sp, existingAttachments[0]);
365
366 lock (sp.AttachmentsSyncLock) 346 lock (sp.AttachmentsSyncLock)
367 { 347 {
348 Vector3 attachPos = group.AbsolutePosition;
349 // If the attachment point isn't the same as the one previously used
350 // set it's offset position = 0 so that it appears on the attachment point
351 // and not in a weird location somewhere unknown.
352 if (attachmentPt != 0 && attachmentPt != group.AttachmentPoint)
353 {
354 attachPos = Vector3.Zero;
355 }
356
357 // AttachmentPt 0 means the client chose to 'wear' the attachment.
358 if (attachmentPt == 0)
359 {
360 // Check object for stored attachment point
361 attachmentPt = group.AttachmentPoint;
362 }
363
364 // if we still didn't find a suitable attachment point.......
365 if (attachmentPt == 0)
366 {
367 // Stick it on left hand with Zero Offset from the attachment point.
368 attachmentPt = (uint)AttachmentPoint.LeftHand;
369 attachPos = Vector3.Zero;
370 }
371
368 group.AttachmentPoint = attachmentPt; 372 group.AttachmentPoint = attachmentPt;
369 group.AbsolutePosition = attachPos; 373 group.AbsolutePosition = attachPos;
370 374
371 if (sp.PresenceType != PresenceType.Npc) 375 if (sp.PresenceType != PresenceType.Npc)
372 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp); 376 UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append);
373 377
374 AttachToAgent(sp, group, attachmentPt, attachPos, silent); 378 AttachToAgent(sp, group, attachmentPt, attachPos, silent);
375 379
376 if (resumeScripts) 380 if (resumeScripts)
@@ -388,8 +392,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
388 return true; 392 return true;
389 } 393 }
390 394
391 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp) 395 private void UpdateUserInventoryWithAttachment(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool temp, bool append)
392 { 396 {
397 List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt);
398
393 // Add the new attachment to inventory if we don't already have it. 399 // Add the new attachment to inventory if we don't already have it.
394 if (!temp) 400 if (!temp)
395 { 401 {
@@ -397,7 +403,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
397 if (newAttachmentItemID == UUID.Zero) 403 if (newAttachmentItemID == UUID.Zero)
398 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; 404 newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID;
399 405
400 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); 406 ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group, append);
401 } 407 }
402 } 408 }
403 409
@@ -410,8 +416,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
410// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", 416// "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}",
411// (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); 417// (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name);
412 418
413 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 419 bool append = (AttachmentPt & 0x80) != 0;
414 // be removed when that functionality is implemented in opensim
415 AttachmentPt &= 0x7f; 420 AttachmentPt &= 0x7f;
416 421
417 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such). 422 // Viewer 2/3 sometimes asks to re-wear items that are already worn (and show up in it's inventory as such).
@@ -440,7 +445,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
440 return null; 445 return null;
441 } 446 }
442 447
443 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); 448 return RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt, append);
444 } 449 }
445 450
446 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist) 451 public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List<KeyValuePair<UUID, uint>> rezlist)
@@ -840,8 +845,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
840 so.RemoveScriptInstances(true); 845 so.RemoveScriptInstances(true);
841 } 846 }
842 847
843 private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( 848 protected SceneObjectGroup RezSingleAttachmentFromInventoryInternal(
844 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) 849 IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt, bool append)
845 { 850 {
846 if (m_invAccessModule == null) 851 if (m_invAccessModule == null)
847 return null; 852 return null;
@@ -884,7 +889,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
884 // This will throw if the attachment fails 889 // This will throw if the attachment fails
885 try 890 try
886 { 891 {
887 AttachObjectInternal(sp, objatt, attachmentPt, false, false, true); 892 AttachObjectInternal(sp, objatt, attachmentPt, false, false, append);
888 } 893 }
889 catch (Exception e) 894 catch (Exception e)
890 { 895 {
@@ -911,7 +916,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
911 /// <param name="AttachmentPt"></param> 916 /// <param name="AttachmentPt"></param>
912 /// <param name="itemID"></param> 917 /// <param name="itemID"></param>
913 /// <param name="att"></param> 918 /// <param name="att"></param>
914 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) 919 private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att, bool append)
915 { 920 {
916// m_log.DebugFormat( 921// m_log.DebugFormat(
917// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", 922// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
@@ -934,7 +939,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
934 if (item == null) 939 if (item == null)
935 return; 940 return;
936 941
937 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); 942 int attFlag = append ? 0x80 : 0;
943 bool changed = sp.Appearance.SetAttachment((int)AttachmentPt | attFlag, itemID, item.AssetID);
938 if (changed && m_scene.AvatarFactory != null) 944 if (changed && m_scene.AvatarFactory != null)
939 { 945 {
940// m_log.DebugFormat( 946// m_log.DebugFormat(
@@ -1018,12 +1024,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1018 return; 1024 return;
1019 } 1025 }
1020 1026
1021 // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should 1027 bool append = (AttachmentPt & 0x80) != 0;
1022 // be removed when that functionality is implemented in opensim
1023 AttachmentPt &= 0x7f; 1028 AttachmentPt &= 0x7f;
1024 1029
1025 // Calls attach with a Zero position 1030 // Calls attach with a Zero position
1026 AttachObject(sp, part.ParentGroup, AttachmentPt, false, false); 1031 if (AttachObject(sp, part.ParentGroup, AttachmentPt, false, false, append))
1032 {
1033// m_log.Debug(
1034// "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId
1035// + ", AttachmentPoint: " + AttachmentPt);
1036
1037 // Save avatar attachment information
1038 m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.FromItemID, remoteClient.AgentId);
1039 }
1027 } 1040 }
1028 catch (Exception e) 1041 catch (Exception e)
1029 { 1042 {
@@ -1076,4 +1089,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
1076 1089
1077 #endregion 1090 #endregion
1078 } 1091 }
1079} \ No newline at end of file 1092}