diff options
Merge branch 'master' into newmultiattach
Conflicts:
OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 124 | ||||
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | 263 |
2 files changed, 305 insertions, 82 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index ab7e932..2dea14d 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | |||
@@ -289,21 +289,22 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
289 | if (!Enabled) | 289 | if (!Enabled) |
290 | return false; | 290 | return false; |
291 | 291 | ||
292 | if (AttachObjectInternal(sp, group, attachmentPt, silent, temp, append)) | 292 | return AttachObjectInternal(sp, group, attachmentPt, silent, temp, append); |
293 | { | ||
294 | m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); | ||
295 | return true; | ||
296 | } | ||
297 | |||
298 | return false; | ||
299 | } | 293 | } |
300 | |||
301 | private bool AttachObjectInternal(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool append) | ||
302 | { | ||
303 | // m_log.DebugFormat( | ||
304 | // "[ATTACHMENTS MODULE]: Attaching object {0} {1} to {2} point {3} from ground (silent = {4})", | ||
305 | // group.Name, group.LocalId, sp.Name, attachmentPt, silent); | ||
306 | 294 | ||
295 | /// <summary> | ||
296 | /// Internal method which actually does all the work for attaching an object. | ||
297 | /// </summary> | ||
298 | /// <returns>The object attached.</returns> | ||
299 | /// <param name='sp'></param> | ||
300 | /// <param name='group'>The object to attach.</param> | ||
301 | /// <param name='attachmentPt'></param> | ||
302 | /// <param name='silent'></param> | ||
303 | /// <param name='temp'></param> | ||
304 | /// <param name='resumeScripts'>If true then scripts are resumed on the attached object.</param> | ||
305 | private bool AttachObjectInternal( | ||
306 | IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent, bool temp, bool resumeScripts) | ||
307 | { | ||
307 | if (group.GetSittingAvatarsCount() != 0) | 308 | if (group.GetSittingAvatarsCount() != 0) |
308 | { | 309 | { |
309 | // m_log.WarnFormat( | 310 | // m_log.WarnFormat( |
@@ -314,6 +315,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
314 | } | 315 | } |
315 | 316 | ||
316 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | 317 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); |
318 | |||
317 | if (attachments.Contains(group)) | 319 | if (attachments.Contains(group)) |
318 | { | 320 | { |
319 | // m_log.WarnFormat( | 321 | // m_log.WarnFormat( |
@@ -374,6 +376,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
374 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); | 376 | UpdateUserInventoryWithAttachment(sp, group, attachmentPt, temp, append); |
375 | 377 | ||
376 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); | 378 | AttachToAgent(sp, group, attachmentPt, attachPos, silent); |
379 | |||
380 | if (resumeScripts) | ||
381 | { | ||
382 | // Fire after attach, so we don't get messy perms dialogs | ||
383 | // 4 == AttachedRez | ||
384 | group.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | ||
385 | group.ResumeScripts(); | ||
386 | } | ||
387 | |||
388 | // Do this last so that event listeners have access to all the effects of the attachment | ||
389 | m_scene.EventManager.TriggerOnAttach(group.LocalId, group.FromItemID, sp.UUID); | ||
377 | } | 390 | } |
378 | 391 | ||
379 | return true; | 392 | return true; |
@@ -400,8 +413,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
400 | return null; | 413 | return null; |
401 | 414 | ||
402 | // m_log.DebugFormat( | 415 | // m_log.DebugFormat( |
403 | // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", | 416 | // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2} in {3}", |
404 | // (AttachmentPoint)AttachmentPt, itemID, sp.Name); | 417 | // (AttachmentPoint)AttachmentPt, itemID, sp.Name, m_scene.Name); |
405 | 418 | ||
406 | bool append = (AttachmentPt & 0x80) != 0; | 419 | bool append = (AttachmentPt & 0x80) != 0; |
407 | AttachmentPt &= 0x7f; | 420 | AttachmentPt &= 0x7f; |
@@ -533,6 +546,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
533 | return; | 546 | return; |
534 | } | 547 | } |
535 | 548 | ||
549 | // m_log.DebugFormat( | ||
550 | // "[ATTACHMENTS MODULE]: Detaching object {0} {1} for {2} in {3}", | ||
551 | // so.Name, so.LocalId, sp.Name, m_scene.Name); | ||
552 | |||
536 | // Scripts MUST be snapshotted before the object is | 553 | // Scripts MUST be snapshotted before the object is |
537 | // removed from the scene because doing otherwise will | 554 | // removed from the scene because doing otherwise will |
538 | // clobber the run flag | 555 | // clobber the run flag |
@@ -854,61 +871,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments | |||
854 | return null; | 871 | return null; |
855 | } | 872 | } |
856 | 873 | ||
857 | // Remove any previous attachments | ||
858 | List<SceneObjectGroup> attachments = sp.GetAttachments(attachmentPt); | ||
859 | string previousAttachmentScriptedState = null; | ||
860 | |||
861 | // At the moment we can only deal with a single attachment | ||
862 | if (attachments.Count != 0) | ||
863 | DetachSingleAttachmentToInv(sp, attachments[0]); | ||
864 | |||
865 | lock (sp.AttachmentsSyncLock) | ||
866 | { | ||
867 | // m_log.DebugFormat( | 874 | // m_log.DebugFormat( |
868 | // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", | 875 | // "[ATTACHMENTS MODULE]: Rezzed single object {0} for attachment to {1} on point {2} in {3}", |
869 | // objatt.Name, sp.Name, attachmentPt, m_scene.Name); | 876 | // objatt.Name, sp.Name, attachmentPt, m_scene.Name); |
870 | 877 | ||
871 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. | 878 | // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. |
872 | objatt.HasGroupChanged = false; | 879 | objatt.HasGroupChanged = false; |
873 | bool tainted = false; | 880 | bool tainted = false; |
874 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) | 881 | if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) |
875 | tainted = true; | 882 | tainted = true; |
876 | 883 | ||
877 | // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal | 884 | // FIXME: Detect whether it's really likely for AttachObject to throw an exception in the normal |
878 | // course of events. If not, then it's probably not worth trying to recover the situation | 885 | // course of events. If not, then it's probably not worth trying to recover the situation |
879 | // since this is more likely to trigger further exceptions and confuse later debugging. If | 886 | // since this is more likely to trigger further exceptions and confuse later debugging. If |
880 | // exceptions can be thrown in expected error conditions (not NREs) then make this consistent | 887 | // exceptions can be thrown in expected error conditions (not NREs) then make this consistent |
881 | // since other normal error conditions will simply return false instead. | 888 | // since other normal error conditions will simply return false instead. |
882 | // This will throw if the attachment fails | 889 | // This will throw if the attachment fails |
883 | try | 890 | try |
884 | { | 891 | { |
885 | AttachObjectInternal(sp, objatt, attachmentPt, false, false, append); | 892 | AttachObjectInternal(sp, objatt, attachmentPt, false, false, append); |
886 | } | 893 | } |
887 | catch (Exception e) | 894 | catch (Exception e) |
888 | { | 895 | { |
889 | m_log.ErrorFormat( | 896 | m_log.ErrorFormat( |
890 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", | 897 | "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", |
891 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); | 898 | objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); |
892 | |||
893 | // Make sure the object doesn't stick around and bail | ||
894 | sp.RemoveAttachment(objatt); | ||
895 | m_scene.DeleteSceneObject(objatt, false); | ||
896 | return null; | ||
897 | } | ||
898 | |||
899 | if (tainted) | ||
900 | objatt.HasGroupChanged = true; | ||
901 | 899 | ||
902 | // Fire after attach, so we don't get messy perms dialogs | 900 | // Make sure the object doesn't stick around and bail |
903 | // 4 == AttachedRez | 901 | sp.RemoveAttachment(objatt); |
904 | objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); | 902 | m_scene.DeleteSceneObject(objatt, false); |
905 | objatt.ResumeScripts(); | 903 | return null; |
904 | } | ||
906 | 905 | ||
907 | // Do this last so that event listeners have access to all the effects of the attachment | 906 | if (tainted) |
908 | m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); | 907 | objatt.HasGroupChanged = true; |
909 | 908 | ||
910 | return objatt; | 909 | return objatt; |
911 | } | ||
912 | } | 910 | } |
913 | 911 | ||
914 | /// <summary> | 912 | /// <summary> |
diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index f48bb6f..0c1df6a 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs | |||
@@ -228,6 +228,120 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
228 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | 228 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); |
229 | } | 229 | } |
230 | 230 | ||
231 | [Test] | ||
232 | public void TestWearAttachmentFromGround() | ||
233 | { | ||
234 | TestHelpers.InMethod(); | ||
235 | // TestHelpers.EnableLogging(); | ||
236 | |||
237 | Scene scene = CreateTestScene(); | ||
238 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); | ||
239 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1); | ||
240 | |||
241 | SceneObjectGroup so2 = SceneHelpers.AddSceneObject(scene, "att2", sp.UUID); | ||
242 | |||
243 | { | ||
244 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, "att1", sp.UUID); | ||
245 | |||
246 | m_numberOfAttachEventsFired = 0; | ||
247 | scene.AttachmentsModule.AttachObject(sp, so, (uint)AttachmentPoint.Default, false, false); | ||
248 | |||
249 | // Check status on scene presence | ||
250 | Assert.That(sp.HasAttachments(), Is.True); | ||
251 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
252 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
253 | SceneObjectGroup attSo = attachments[0]; | ||
254 | Assert.That(attSo.Name, Is.EqualTo(so.Name)); | ||
255 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
256 | Assert.That(attSo.IsAttachment); | ||
257 | Assert.That(attSo.UsesPhysics, Is.False); | ||
258 | Assert.That(attSo.IsTemporary, Is.False); | ||
259 | |||
260 | // Check item status | ||
261 | Assert.That( | ||
262 | sp.Appearance.GetAttachpoint(attSo.FromItemID), | ||
263 | Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
264 | |||
265 | InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); | ||
266 | Assert.That(attachmentItem, Is.Not.Null); | ||
267 | Assert.That(attachmentItem.Name, Is.EqualTo(so.Name)); | ||
268 | |||
269 | InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
270 | Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); | ||
271 | |||
272 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(2)); | ||
273 | |||
274 | // Check events | ||
275 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
276 | } | ||
277 | |||
278 | // Test wearing a different attachment from the ground. | ||
279 | { | ||
280 | scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false); | ||
281 | |||
282 | // Check status on scene presence | ||
283 | Assert.That(sp.HasAttachments(), Is.True); | ||
284 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
285 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
286 | SceneObjectGroup attSo = attachments[0]; | ||
287 | Assert.That(attSo.Name, Is.EqualTo(so2.Name)); | ||
288 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
289 | Assert.That(attSo.IsAttachment); | ||
290 | Assert.That(attSo.UsesPhysics, Is.False); | ||
291 | Assert.That(attSo.IsTemporary, Is.False); | ||
292 | |||
293 | // Check item status | ||
294 | Assert.That( | ||
295 | sp.Appearance.GetAttachpoint(attSo.FromItemID), | ||
296 | Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
297 | |||
298 | InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); | ||
299 | Assert.That(attachmentItem, Is.Not.Null); | ||
300 | Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); | ||
301 | |||
302 | InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
303 | Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); | ||
304 | |||
305 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
306 | |||
307 | // Check events | ||
308 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); | ||
309 | } | ||
310 | |||
311 | // Test rewearing an already worn attachment from ground. Nothing should happen. | ||
312 | { | ||
313 | scene.AttachmentsModule.AttachObject(sp, so2, (uint)AttachmentPoint.Default, false, false); | ||
314 | |||
315 | // Check status on scene presence | ||
316 | Assert.That(sp.HasAttachments(), Is.True); | ||
317 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
318 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
319 | SceneObjectGroup attSo = attachments[0]; | ||
320 | Assert.That(attSo.Name, Is.EqualTo(so2.Name)); | ||
321 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
322 | Assert.That(attSo.IsAttachment); | ||
323 | Assert.That(attSo.UsesPhysics, Is.False); | ||
324 | Assert.That(attSo.IsTemporary, Is.False); | ||
325 | |||
326 | // Check item status | ||
327 | Assert.That( | ||
328 | sp.Appearance.GetAttachpoint(attSo.FromItemID), | ||
329 | Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
330 | |||
331 | InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); | ||
332 | Assert.That(attachmentItem, Is.Not.Null); | ||
333 | Assert.That(attachmentItem.Name, Is.EqualTo(so2.Name)); | ||
334 | |||
335 | InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); | ||
336 | Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); | ||
337 | |||
338 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
339 | |||
340 | // Check events | ||
341 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); | ||
342 | } | ||
343 | } | ||
344 | |||
231 | /// <summary> | 345 | /// <summary> |
232 | /// Test that we do not attempt to attach an in-world object that someone else is sitting on. | 346 | /// Test that we do not attempt to attach an in-world object that someone else is sitting on. |
233 | /// </summary> | 347 | /// </summary> |
@@ -275,29 +389,140 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests | |||
275 | 389 | ||
276 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); | 390 | InventoryItemBase attItem = CreateAttachmentItem(scene, ua1.PrincipalID, "att", 0x10, 0x20); |
277 | 391 | ||
278 | m_numberOfAttachEventsFired = 0; | 392 | { |
279 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( | 393 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( |
280 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | 394 | sp, attItem.ID, (uint)AttachmentPoint.Chest); |
281 | 395 | ||
282 | // Check scene presence status | 396 | // Check scene presence status |
283 | Assert.That(sp.HasAttachments(), Is.True); | 397 | Assert.That(sp.HasAttachments(), Is.True); |
284 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | 398 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
285 | Assert.That(attachments.Count, Is.EqualTo(1)); | 399 | Assert.That(attachments.Count, Is.EqualTo(1)); |
286 | SceneObjectGroup attSo = attachments[0]; | 400 | SceneObjectGroup attSo = attachments[0]; |
287 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); | 401 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); |
288 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | 402 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); |
289 | Assert.That(attSo.IsAttachment); | 403 | Assert.That(attSo.IsAttachment); |
290 | Assert.That(attSo.UsesPhysics, Is.False); | 404 | Assert.That(attSo.UsesPhysics, Is.False); |
291 | Assert.That(attSo.IsTemporary, Is.False); | 405 | Assert.That(attSo.IsTemporary, Is.False); |
406 | |||
407 | // Check appearance status | ||
408 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
409 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
410 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
411 | |||
412 | // Check events | ||
413 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
414 | } | ||
415 | |||
416 | // Test attaching an already attached attachment | ||
417 | { | ||
418 | scene.AttachmentsModule.RezSingleAttachmentFromInventory( | ||
419 | sp, attItem.ID, (uint)AttachmentPoint.Chest); | ||
292 | 420 | ||
293 | // Check appearance status | 421 | // Check scene presence status |
294 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | 422 | Assert.That(sp.HasAttachments(), Is.True); |
295 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | 423 | List<SceneObjectGroup> attachments = sp.GetAttachments(); |
424 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
425 | SceneObjectGroup attSo = attachments[0]; | ||
426 | Assert.That(attSo.Name, Is.EqualTo(attItem.Name)); | ||
427 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.Chest)); | ||
428 | Assert.That(attSo.IsAttachment); | ||
429 | Assert.That(attSo.UsesPhysics, Is.False); | ||
430 | Assert.That(attSo.IsTemporary, Is.False); | ||
431 | |||
432 | // Check appearance status | ||
433 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
434 | Assert.That(sp.Appearance.GetAttachpoint(attItem.ID), Is.EqualTo((int)AttachmentPoint.Chest)); | ||
435 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
436 | |||
437 | // Check events | ||
438 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
439 | } | ||
440 | } | ||
296 | 441 | ||
297 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | 442 | /// <summary> |
443 | /// Test wearing an attachment from inventory, as opposed to explicit choosing the rez point | ||
444 | /// </summary> | ||
445 | [Test] | ||
446 | public void TestWearAttachmentFromInventory() | ||
447 | { | ||
448 | TestHelpers.InMethod(); | ||
449 | // TestHelpers.EnableLogging(); | ||
298 | 450 | ||
299 | // Check events | 451 | Scene scene = CreateTestScene(); |
300 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | 452 | UserAccount ua1 = UserAccountHelpers.CreateUserWithInventory(scene, 0x1); |
453 | ScenePresence sp = SceneHelpers.AddScenePresence(scene, ua1.PrincipalID); | ||
454 | |||
455 | InventoryItemBase attItem1 = CreateAttachmentItem(scene, ua1.PrincipalID, "att1", 0x10, 0x20); | ||
456 | InventoryItemBase attItem2 = CreateAttachmentItem(scene, ua1.PrincipalID, "att2", 0x11, 0x21); | ||
457 | |||
458 | { | ||
459 | m_numberOfAttachEventsFired = 0; | ||
460 | scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem1.ID, (uint)AttachmentPoint.Default); | ||
461 | |||
462 | // default attachment point is currently the left hand. | ||
463 | Assert.That(sp.HasAttachments(), Is.True); | ||
464 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
465 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
466 | SceneObjectGroup attSo = attachments[0]; | ||
467 | Assert.That(attSo.Name, Is.EqualTo(attItem1.Name)); | ||
468 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
469 | Assert.That(attSo.IsAttachment); | ||
470 | |||
471 | // Check appearance status | ||
472 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
473 | Assert.That(sp.Appearance.GetAttachpoint(attItem1.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
474 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
475 | |||
476 | // Check events | ||
477 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(1)); | ||
478 | } | ||
479 | |||
480 | // Test wearing a second attachment at the same position | ||
481 | // Until multiple attachments at one point is implemented, this will remove the first attachment | ||
482 | // This test relies on both attachments having the same default attachment point (in this case LeftHand | ||
483 | // since none other has been set). | ||
484 | { | ||
485 | scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default); | ||
486 | |||
487 | // default attachment point is currently the left hand. | ||
488 | Assert.That(sp.HasAttachments(), Is.True); | ||
489 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
490 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
491 | SceneObjectGroup attSo = attachments[0]; | ||
492 | Assert.That(attSo.Name, Is.EqualTo(attItem2.Name)); | ||
493 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
494 | Assert.That(attSo.IsAttachment); | ||
495 | |||
496 | // Check appearance status | ||
497 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
498 | Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
499 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
500 | |||
501 | // Check events | ||
502 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); | ||
503 | } | ||
504 | |||
505 | // Test wearing an already attached attachment | ||
506 | { | ||
507 | scene.AttachmentsModule.RezSingleAttachmentFromInventory(sp, attItem2.ID, (uint)AttachmentPoint.Default); | ||
508 | |||
509 | // default attachment point is currently the left hand. | ||
510 | Assert.That(sp.HasAttachments(), Is.True); | ||
511 | List<SceneObjectGroup> attachments = sp.GetAttachments(); | ||
512 | Assert.That(attachments.Count, Is.EqualTo(1)); | ||
513 | SceneObjectGroup attSo = attachments[0]; | ||
514 | Assert.That(attSo.Name, Is.EqualTo(attItem2.Name)); | ||
515 | Assert.That(attSo.AttachmentPoint, Is.EqualTo((byte)AttachmentPoint.LeftHand)); | ||
516 | Assert.That(attSo.IsAttachment); | ||
517 | |||
518 | // Check appearance status | ||
519 | Assert.That(sp.Appearance.GetAttachments().Count, Is.EqualTo(1)); | ||
520 | Assert.That(sp.Appearance.GetAttachpoint(attItem2.ID), Is.EqualTo((int)AttachmentPoint.LeftHand)); | ||
521 | Assert.That(scene.GetSceneObjectGroups().Count, Is.EqualTo(1)); | ||
522 | |||
523 | // Check events | ||
524 | Assert.That(m_numberOfAttachEventsFired, Is.EqualTo(3)); | ||
525 | } | ||
301 | } | 526 | } |
302 | 527 | ||
303 | /// <summary> | 528 | /// <summary> |