diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Framework/Interfaces/IEntityInventory.cs | 13 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Interfaces/IWorldComm.cs | 39 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/EventManager.cs | 39 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 14 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | 40 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 1 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneGraph.cs | 80 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 7 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 203 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 26 |
10 files changed, 411 insertions, 51 deletions
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index eeb5102..fa9bf19 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs | |||
@@ -71,7 +71,8 @@ namespace OpenSim.Region.Framework.Interfaces | |||
71 | /// <summary> | 71 | /// <summary> |
72 | /// Start all the scripts contained in this entity's inventory | 72 | /// Start all the scripts contained in this entity's inventory |
73 | /// </summary> | 73 | /// </summary> |
74 | void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource); | 74 | void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource); |
75 | |||
75 | ArrayList GetScriptErrors(UUID itemID); | 76 | ArrayList GetScriptErrors(UUID itemID); |
76 | 77 | ||
77 | /// <summary> | 78 | /// <summary> |
@@ -143,6 +144,16 @@ namespace OpenSim.Region.Framework.Interfaces | |||
143 | TaskInventoryItem GetInventoryItem(UUID itemId); | 144 | TaskInventoryItem GetInventoryItem(UUID itemId); |
144 | 145 | ||
145 | /// <summary> | 146 | /// <summary> |
147 | /// Get inventory items by name. | ||
148 | /// </summary> | ||
149 | /// <param name="name"></param> | ||
150 | /// <returns> | ||
151 | /// A list of inventory items with that name. | ||
152 | /// If no inventory item has that name then an empty list is returned. | ||
153 | /// </returns> | ||
154 | IList<TaskInventoryItem> GetInventoryItems(string name); | ||
155 | |||
156 | /// <summary> | ||
146 | /// Update an existing inventory item. | 157 | /// Update an existing inventory item. |
147 | /// </summary> | 158 | /// </summary> |
148 | /// <param name="item">The updated item. An item with the same id must already exist | 159 | /// <param name="item">The updated item. An item with the same id must already exist |
diff --git a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs index 74526c4..948b9dc 100644 --- a/OpenSim/Region/Framework/Interfaces/IWorldComm.cs +++ b/OpenSim/Region/Framework/Interfaces/IWorldComm.cs | |||
@@ -49,10 +49,49 @@ namespace OpenSim.Region.Framework.Interfaces | |||
49 | 49 | ||
50 | public interface IWorldComm | 50 | public interface IWorldComm |
51 | { | 51 | { |
52 | /// <summary> | ||
53 | /// Create a listen event callback with the specified filters. | ||
54 | /// The parameters localID,itemID are needed to uniquely identify | ||
55 | /// the script during 'peek' time. Parameter hostID is needed to | ||
56 | /// determine the position of the script. | ||
57 | /// </summary> | ||
58 | /// <param name="localID">localID of the script engine</param> | ||
59 | /// <param name="itemID">UUID of the script engine</param> | ||
60 | /// <param name="hostID">UUID of the SceneObjectPart</param> | ||
61 | /// <param name="channel">channel to listen on</param> | ||
62 | /// <param name="name">name to filter on</param> | ||
63 | /// <param name="id">key to filter on (user given, could be totally faked)</param> | ||
64 | /// <param name="msg">msg to filter on</param> | ||
65 | /// <returns>number of the scripts handle</returns> | ||
52 | int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg); | 66 | int Listen(uint LocalID, UUID itemID, UUID hostID, int channel, string name, UUID id, string msg); |
67 | |||
68 | /// <summary> | ||
69 | /// This method scans over the objects which registered an interest in listen callbacks. | ||
70 | /// For everyone it finds, it checks if it fits the given filter. If it does, then | ||
71 | /// enqueue the message for delivery to the objects listen event handler. | ||
72 | /// The enqueued ListenerInfo no longer has filter values, but the actually trigged values. | ||
73 | /// Objects that do an llSay have their messages delivered here and for nearby avatars, | ||
74 | /// the OnChatFromClient event is used. | ||
75 | /// </summary> | ||
76 | /// <param name="type">type of delvery (whisper,say,shout or regionwide)</param> | ||
77 | /// <param name="channel">channel to sent on</param> | ||
78 | /// <param name="name">name of sender (object or avatar)</param> | ||
79 | /// <param name="id">key of sender (object or avatar)</param> | ||
80 | /// <param name="msg">msg to sent</param> | ||
53 | void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg); | 81 | void DeliverMessage(ChatTypeEnum type, int channel, string name, UUID id, string msg); |
82 | |||
83 | /// <summary> | ||
84 | /// Are there any listen events ready to be dispatched? | ||
85 | /// </summary> | ||
86 | /// <returns>boolean indication</returns> | ||
54 | bool HasMessages(); | 87 | bool HasMessages(); |
88 | |||
89 | /// <summary> | ||
90 | /// Pop the first availlable listen event from the queue | ||
91 | /// </summary> | ||
92 | /// <returns>ListenerInfo with filter filled in</returns> | ||
55 | IWorldCommListenerInfo GetNextMessage(); | 93 | IWorldCommListenerInfo GetNextMessage(); |
94 | |||
56 | void ListenControl(UUID itemID, int handle, int active); | 95 | void ListenControl(UUID itemID, int handle, int active); |
57 | void ListenRemove(UUID itemID, int handle); | 96 | void ListenRemove(UUID itemID, int handle); |
58 | void DeleteListener(UUID itemID); | 97 | void DeleteListener(UUID itemID); |
diff --git a/OpenSim/Region/Framework/Scenes/EventManager.cs b/OpenSim/Region/Framework/Scenes/EventManager.cs index 8f0b866..fe40f52 100644 --- a/OpenSim/Region/Framework/Scenes/EventManager.cs +++ b/OpenSim/Region/Framework/Scenes/EventManager.cs | |||
@@ -92,8 +92,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
92 | public delegate void OnShutdownDelegate(); | 92 | public delegate void OnShutdownDelegate(); |
93 | 93 | ||
94 | public event OnShutdownDelegate OnShutdown; | 94 | public event OnShutdownDelegate OnShutdown; |
95 | 95 | ||
96 | public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs); | ||
97 | public delegate void ObjectDeGrabDelegate(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs); | 96 | public delegate void ObjectDeGrabDelegate(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs); |
98 | public delegate void ScriptResetDelegate(uint localID, UUID itemID); | 97 | public delegate void ScriptResetDelegate(uint localID, UUID itemID); |
99 | 98 | ||
@@ -103,62 +102,57 @@ namespace OpenSim.Region.Framework.Scenes | |||
103 | 102 | ||
104 | public event OnSetRootAgentSceneDelegate OnSetRootAgentScene; | 103 | public event OnSetRootAgentSceneDelegate OnSetRootAgentScene; |
105 | 104 | ||
105 | /// <summary> | ||
106 | /// Called when an object is touched/grabbed. | ||
107 | /// </summary> | ||
108 | /// The originalID is the local ID of the part that was actually touched. The localID itself is always that of | ||
109 | /// the root part. | ||
110 | public delegate void ObjectGrabDelegate(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs); | ||
106 | public event ObjectGrabDelegate OnObjectGrab; | 111 | public event ObjectGrabDelegate OnObjectGrab; |
112 | |||
113 | public event ObjectGrabDelegate OnObjectGrabbing; | ||
107 | public event ObjectDeGrabDelegate OnObjectDeGrab; | 114 | public event ObjectDeGrabDelegate OnObjectDeGrab; |
108 | public event ScriptResetDelegate OnScriptReset; | 115 | public event ScriptResetDelegate OnScriptReset; |
109 | 116 | ||
110 | public event OnPermissionErrorDelegate OnPermissionError; | 117 | public event OnPermissionErrorDelegate OnPermissionError; |
111 | 118 | ||
112 | public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource); | 119 | public delegate void NewRezScript(uint localID, UUID itemID, string script, int startParam, bool postOnRez, string engine, int stateSource); |
113 | |||
114 | public event NewRezScript OnRezScript; | 120 | public event NewRezScript OnRezScript; |
115 | 121 | ||
116 | public delegate void RemoveScript(uint localID, UUID itemID); | 122 | public delegate void RemoveScript(uint localID, UUID itemID); |
117 | |||
118 | public event RemoveScript OnRemoveScript; | 123 | public event RemoveScript OnRemoveScript; |
119 | 124 | ||
120 | public delegate void StartScript(uint localID, UUID itemID); | 125 | public delegate void StartScript(uint localID, UUID itemID); |
121 | |||
122 | public event StartScript OnStartScript; | 126 | public event StartScript OnStartScript; |
123 | 127 | ||
124 | public delegate void StopScript(uint localID, UUID itemID); | 128 | public delegate void StopScript(uint localID, UUID itemID); |
125 | |||
126 | public event StopScript OnStopScript; | 129 | public event StopScript OnStopScript; |
127 | 130 | ||
128 | public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta); | 131 | public delegate bool SceneGroupMoved(UUID groupID, Vector3 delta); |
129 | |||
130 | public event SceneGroupMoved OnSceneGroupMove; | 132 | public event SceneGroupMoved OnSceneGroupMove; |
131 | 133 | ||
132 | public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID); | 134 | public delegate void SceneGroupGrabed(UUID groupID, Vector3 offset, UUID userID); |
133 | |||
134 | public event SceneGroupGrabed OnSceneGroupGrab; | 135 | public event SceneGroupGrabed OnSceneGroupGrab; |
135 | 136 | ||
136 | public delegate bool SceneGroupSpinStarted(UUID groupID); | 137 | public delegate bool SceneGroupSpinStarted(UUID groupID); |
137 | |||
138 | public event SceneGroupSpinStarted OnSceneGroupSpinStart; | 138 | public event SceneGroupSpinStarted OnSceneGroupSpinStart; |
139 | 139 | ||
140 | public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation); | 140 | public delegate bool SceneGroupSpun(UUID groupID, Quaternion rotation); |
141 | |||
142 | public event SceneGroupSpun OnSceneGroupSpin; | 141 | public event SceneGroupSpun OnSceneGroupSpin; |
143 | 142 | ||
144 | public delegate void LandObjectAdded(ILandObject newParcel); | 143 | public delegate void LandObjectAdded(ILandObject newParcel); |
145 | |||
146 | public event LandObjectAdded OnLandObjectAdded; | 144 | public event LandObjectAdded OnLandObjectAdded; |
147 | 145 | ||
148 | public delegate void LandObjectRemoved(UUID globalID); | 146 | public delegate void LandObjectRemoved(UUID globalID); |
149 | |||
150 | public event LandObjectRemoved OnLandObjectRemoved; | 147 | public event LandObjectRemoved OnLandObjectRemoved; |
151 | 148 | ||
152 | public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID); | 149 | public delegate void AvatarEnteringNewParcel(ScenePresence avatar, int localLandID, UUID regionID); |
153 | |||
154 | public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; | 150 | public event AvatarEnteringNewParcel OnAvatarEnteringNewParcel; |
155 | 151 | ||
156 | public delegate void SignificantClientMovement(IClientAPI remote_client); | 152 | public delegate void SignificantClientMovement(IClientAPI remote_client); |
157 | |||
158 | public event SignificantClientMovement OnSignificantClientMovement; | 153 | public event SignificantClientMovement OnSignificantClientMovement; |
159 | 154 | ||
160 | public delegate void IncomingInstantMessage(GridInstantMessage message); | 155 | public delegate void IncomingInstantMessage(GridInstantMessage message); |
161 | |||
162 | public event IncomingInstantMessage OnIncomingInstantMessage; | 156 | public event IncomingInstantMessage OnIncomingInstantMessage; |
163 | 157 | ||
164 | public event IncomingInstantMessage OnUnhandledInstantMessage; | 158 | public event IncomingInstantMessage OnUnhandledInstantMessage; |
@@ -316,9 +310,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
316 | public event EmptyScriptCompileQueue OnEmptyScriptCompileQueue; | 310 | public event EmptyScriptCompileQueue OnEmptyScriptCompileQueue; |
317 | 311 | ||
318 | /// <summary> | 312 | /// <summary> |
319 | /// Called whenever an object is attached, or detached | 313 | /// Called whenever an object is attached, or detached from an in-world presence. |
320 | /// from an in-world presence. | ||
321 | /// </summary> | 314 | /// </summary> |
315 | /// If the object is being attached, then the avatarID will be present. If the object is being detached then | ||
316 | /// the avatarID is UUID.Zero (I know, this doesn't make much sense but now it's historical). | ||
322 | public delegate void Attach(uint localID, UUID itemID, UUID avatarID); | 317 | public delegate void Attach(uint localID, UUID itemID, UUID avatarID); |
323 | public event Attach OnAttach; | 318 | public event Attach OnAttach; |
324 | 319 | ||
@@ -412,6 +407,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
412 | private OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = null; //OnParcelPrimCountAdd; | 407 | private OnParcelPrimCountAddDelegate handlerParcelPrimCountAdd = null; //OnParcelPrimCountAdd; |
413 | private OnShutdownDelegate handlerShutdown = null; //OnShutdown; | 408 | private OnShutdownDelegate handlerShutdown = null; //OnShutdown; |
414 | private ObjectGrabDelegate handlerObjectGrab = null; //OnObjectGrab; | 409 | private ObjectGrabDelegate handlerObjectGrab = null; //OnObjectGrab; |
410 | private ObjectGrabDelegate handlerObjectGrabbing = null; //OnObjectGrabbing; | ||
415 | private ObjectDeGrabDelegate handlerObjectDeGrab = null; //OnObjectDeGrab; | 411 | private ObjectDeGrabDelegate handlerObjectDeGrab = null; //OnObjectDeGrab; |
416 | private ScriptResetDelegate handlerScriptReset = null; // OnScriptReset | 412 | private ScriptResetDelegate handlerScriptReset = null; // OnScriptReset |
417 | private NewRezScript handlerRezScript = null; //OnRezScript; | 413 | private NewRezScript handlerRezScript = null; //OnRezScript; |
@@ -626,6 +622,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
626 | } | 622 | } |
627 | } | 623 | } |
628 | 624 | ||
625 | public void TriggerObjectGrabbing(uint localID, uint originalID, Vector3 offsetPos, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) | ||
626 | { | ||
627 | handlerObjectGrabbing = OnObjectGrabbing; | ||
628 | if (handlerObjectGrabbing != null) | ||
629 | { | ||
630 | handlerObjectGrabbing(localID, originalID, offsetPos, remoteClient, surfaceArgs); | ||
631 | } | ||
632 | } | ||
633 | |||
629 | public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) | 634 | public void TriggerObjectDeGrab(uint localID, uint originalID, IClientAPI remoteClient, SurfaceTouchEventArgs surfaceArgs) |
630 | { | 635 | { |
631 | handlerObjectDeGrab = OnObjectDeGrab; | 636 | handlerObjectDeGrab = OnObjectDeGrab; |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index a18bf76..7b852a2 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -2385,9 +2385,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
2385 | } | 2385 | } |
2386 | } | 2386 | } |
2387 | 2387 | ||
2388 | public void AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent) | 2388 | /// <summary> |
2389 | /// Attach an object. | ||
2390 | /// </summary> | ||
2391 | /// <param name="controllingClient"></param> | ||
2392 | /// <param name="localID"></param> | ||
2393 | /// <param name="attachPoint"></param> | ||
2394 | /// <param name="rot"></param> | ||
2395 | /// <param name="pos"></param> | ||
2396 | /// <param name="silent"></param> | ||
2397 | /// <returns>true if the object was successfully attached, false otherwise</returns> | ||
2398 | public bool AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent) | ||
2389 | { | 2399 | { |
2390 | m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent); | 2400 | return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent); |
2391 | } | 2401 | } |
2392 | 2402 | ||
2393 | public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) | 2403 | public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att) |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs index 47fbeb4..ac04dc7 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.PacketHandlers.cs | |||
@@ -292,6 +292,46 @@ namespace OpenSim.Region.Framework.Scenes | |||
292 | } | 292 | } |
293 | } | 293 | } |
294 | 294 | ||
295 | public virtual void ProcessObjectGrabUpdate(UUID objectID, Vector3 offset, Vector3 pos, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) | ||
296 | { | ||
297 | List<EntityBase> EntityList = GetEntities(); | ||
298 | |||
299 | SurfaceTouchEventArgs surfaceArg = null; | ||
300 | if (surfaceArgs != null && surfaceArgs.Count > 0) | ||
301 | surfaceArg = surfaceArgs[0]; | ||
302 | |||
303 | foreach (EntityBase ent in EntityList) | ||
304 | { | ||
305 | if (ent is SceneObjectGroup) | ||
306 | { | ||
307 | SceneObjectGroup obj = ent as SceneObjectGroup; | ||
308 | if (obj != null) | ||
309 | { | ||
310 | // Is this prim part of the group | ||
311 | if (obj.HasChildPrim(objectID)) | ||
312 | { | ||
313 | SceneObjectPart part = obj.GetChildPart(objectID); | ||
314 | |||
315 | // If the touched prim handles touches, deliver it | ||
316 | // If not, deliver to root prim | ||
317 | if ((part.ScriptEvents & scriptEvents.touch) != 0) | ||
318 | EventManager.TriggerObjectGrabbing(part.LocalId, 0, part.OffsetPosition, remoteClient, surfaceArg); | ||
319 | // Deliver to the root prim if the touched prim doesn't handle touches | ||
320 | // or if we're meant to pass on touches anyway. Don't send to root prim | ||
321 | // if prim touched is the root prim as we just did it | ||
322 | if (((part.ScriptEvents & scriptEvents.touch) == 0) || | ||
323 | (part.PassTouches && (part.LocalId != obj.RootPart.LocalId))) | ||
324 | { | ||
325 | EventManager.TriggerObjectGrabbing(obj.RootPart.LocalId, part.LocalId, part.OffsetPosition, remoteClient, surfaceArg); | ||
326 | } | ||
327 | |||
328 | return; | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | } | ||
333 | } | ||
334 | |||
295 | public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) | 335 | public virtual void ProcessObjectDeGrab(uint localID, IClientAPI remoteClient, List<SurfaceTouchEventArgs> surfaceArgs) |
296 | { | 336 | { |
297 | List<EntityBase> EntityList = GetEntities(); | 337 | List<EntityBase> EntityList = GetEntities(); |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 23db482..d2f33b0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -2702,6 +2702,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2702 | client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily; | 2702 | client.OnRequestObjectPropertiesFamily += m_sceneGraph.RequestObjectPropertiesFamily; |
2703 | client.OnObjectPermissions += HandleObjectPermissionsUpdate; | 2703 | client.OnObjectPermissions += HandleObjectPermissionsUpdate; |
2704 | client.OnGrabObject += ProcessObjectGrab; | 2704 | client.OnGrabObject += ProcessObjectGrab; |
2705 | client.OnGrabUpdate += ProcessObjectGrabUpdate; | ||
2705 | client.OnDeGrabObject += ProcessObjectDeGrab; | 2706 | client.OnDeGrabObject += ProcessObjectDeGrab; |
2706 | client.OnUndo += m_sceneGraph.HandleUndo; | 2707 | client.OnUndo += m_sceneGraph.HandleUndo; |
2707 | client.OnObjectDescription += m_sceneGraph.PrimDescription; | 2708 | client.OnObjectDescription += m_sceneGraph.PrimDescription; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 34a92fe..2c66719 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -502,46 +502,62 @@ namespace OpenSim.Region.Framework.Scenes | |||
502 | if (part == null) | 502 | if (part == null) |
503 | return; | 503 | return; |
504 | 504 | ||
505 | if (!m_parentScene.Permissions.CanTakeObject( | 505 | if (!m_parentScene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) |
506 | part.UUID, remoteClient.AgentId)) | ||
507 | return; | 506 | return; |
508 | 507 | ||
509 | // Calls attach with a Zero position | 508 | // Calls attach with a Zero position |
510 | AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false); | 509 | if (AttachObject(remoteClient, objectLocalID, AttachmentPt, rot, Vector3.Zero, false)) |
511 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); | ||
512 | |||
513 | // Save avatar attachment information | ||
514 | ScenePresence presence; | ||
515 | if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence)) | ||
516 | { | 510 | { |
517 | m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", AttachmentPoint: " + AttachmentPt); | 511 | m_parentScene.SendAttachEvent(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); |
518 | m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | 512 | |
513 | // Save avatar attachment information | ||
514 | ScenePresence presence; | ||
515 | if (m_parentScene.AvatarFactory != null && m_parentScene.TryGetAvatar(remoteClient.AgentId, out presence)) | ||
516 | { | ||
517 | m_log.Info( | ||
518 | "[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId | ||
519 | + ", AttachmentPoint: " + AttachmentPt); | ||
520 | |||
521 | m_parentScene.AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance); | ||
522 | } | ||
519 | } | 523 | } |
520 | } | 524 | } |
521 | 525 | ||
522 | public SceneObjectGroup RezSingleAttachment( | 526 | /// <summary> |
523 | IClientAPI remoteClient, UUID itemID, uint AttachmentPt) | 527 | /// Rez an attachment |
528 | /// </summary> | ||
529 | /// <param name="remoteClient"></param> | ||
530 | /// <param name="itemID"></param> | ||
531 | /// <param name="AttachmentPt"></param> | ||
532 | /// <returns>The scene object that was attached. Null if the scene object could not be found</returns> | ||
533 | public SceneObjectGroup RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) | ||
524 | { | 534 | { |
525 | SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient, | 535 | SceneObjectGroup objatt = m_parentScene.RezObject(remoteClient, |
526 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, | 536 | itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, |
527 | false, false, remoteClient.AgentId, true); | 537 | false, false, remoteClient.AgentId, true); |
528 | 538 | ||
529 | |||
530 | if (objatt != null) | 539 | if (objatt != null) |
531 | { | 540 | { |
532 | bool tainted = false; | 541 | bool tainted = false; |
533 | if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) | 542 | if (AttachmentPt != 0 && AttachmentPt != objatt.GetAttachmentPoint()) |
534 | tainted = true; | 543 | tainted = true; |
535 | 544 | ||
536 | AttachObject(remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false); | 545 | if (AttachObject( |
537 | objatt.ScheduleGroupForFullUpdate(); | 546 | remoteClient, objatt.LocalId, AttachmentPt, Quaternion.Identity, objatt.AbsolutePosition, false)) |
538 | if (tainted) | 547 | { |
539 | objatt.HasGroupChanged = true; | 548 | objatt.ScheduleGroupForFullUpdate(); |
540 | 549 | if (tainted) | |
541 | // Fire after attach, so we don't get messy perms dialogs | 550 | objatt.HasGroupChanged = true; |
542 | // 3 == AttachedRez | 551 | |
543 | objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); | 552 | // Fire after attach, so we don't get messy perms dialogs |
553 | // 3 == AttachedRez | ||
554 | objatt.CreateScriptInstances(0, true, m_parentScene.DefaultScriptEngine, 3); | ||
555 | |||
556 | // Do this last so that event listeners have access to all the effects of the attachment | ||
557 | m_parentScene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, remoteClient.AgentId); | ||
558 | } | ||
544 | } | 559 | } |
560 | |||
545 | return objatt; | 561 | return objatt; |
546 | } | 562 | } |
547 | 563 | ||
@@ -590,7 +606,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
590 | } | 606 | } |
591 | } | 607 | } |
592 | 608 | ||
593 | protected internal void AttachObject( | 609 | /// <summary> |
610 | /// Attach a scene object to an avatar. | ||
611 | /// </summary> | ||
612 | /// <param name="remoteClient"></param> | ||
613 | /// <param name="objectLocalID"></param> | ||
614 | /// <param name="AttachmentPt"></param> | ||
615 | /// <param name="rot"></param> | ||
616 | /// <param name="attachPos"></param> | ||
617 | /// <param name="silent"></param> | ||
618 | /// <returns>true if the attachment was successful, false otherwise</returns> | ||
619 | protected internal bool AttachObject( | ||
594 | IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) | 620 | IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, Quaternion rot, Vector3 attachPos, bool silent) |
595 | { | 621 | { |
596 | SceneObjectGroup group = GetGroupByPrim(objectLocalID); | 622 | SceneObjectGroup group = GetGroupByPrim(objectLocalID); |
@@ -619,10 +645,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
619 | // Stick it on left hand with Zero Offset from the attachment point. | 645 | // Stick it on left hand with Zero Offset from the attachment point. |
620 | AttachmentPt = (uint)AttachmentPoint.LeftHand; | 646 | AttachmentPt = (uint)AttachmentPoint.LeftHand; |
621 | attachPos = Vector3.Zero; | 647 | attachPos = Vector3.Zero; |
622 | |||
623 | } | 648 | } |
624 | 649 | ||
625 | |||
626 | group.SetAttachmentPoint((byte)AttachmentPt); | 650 | group.SetAttachmentPoint((byte)AttachmentPt); |
627 | group.AbsolutePosition = attachPos; | 651 | group.AbsolutePosition = attachPos; |
628 | 652 | ||
@@ -645,15 +669,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
645 | // it get cleaned up | 669 | // it get cleaned up |
646 | // | 670 | // |
647 | group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); | 671 | group.RootPart.RemFlag(PrimFlags.TemporaryOnRez); |
648 | group.HasGroupChanged = false; | 672 | group.HasGroupChanged = false; |
649 | } | 673 | } |
650 | else | 674 | else |
651 | { | 675 | { |
652 | remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false); | 676 | remoteClient.SendAgentAlertMessage("You don't have sufficient permissions to attach this object", false); |
677 | return false; | ||
653 | } | 678 | } |
654 | } | 679 | } |
655 | else | 680 | else |
681 | { | ||
656 | m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID); | 682 | m_log.DebugFormat("[SCENE GRAPH]: AttachObject found no such scene object {0}", objectLocalID); |
683 | return false; | ||
684 | } | ||
685 | |||
686 | return true; | ||
657 | } | 687 | } |
658 | 688 | ||
659 | protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) | 689 | protected internal ScenePresence CreateAndAddChildScenePresence(IClientAPI client, AvatarAppearance appearance) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 768ceb5..9cb1398 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -301,6 +301,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
301 | set { m_rootPart.GroupID = value; } | 301 | set { m_rootPart.GroupID = value; } |
302 | } | 302 | } |
303 | 303 | ||
304 | /// <value> | ||
305 | /// The parts of this scene object group. You must lock this property before using it. | ||
306 | /// </value> | ||
304 | public Dictionary<UUID, SceneObjectPart> Children | 307 | public Dictionary<UUID, SceneObjectPart> Children |
305 | { | 308 | { |
306 | get { return m_parts; } | 309 | get { return m_parts; } |
@@ -2239,7 +2242,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2239 | } | 2242 | } |
2240 | 2243 | ||
2241 | /// <summary> | 2244 | /// <summary> |
2242 | /// Get a child part with a given UUID | 2245 | /// Get a part with a given UUID |
2243 | /// </summary> | 2246 | /// </summary> |
2244 | /// <param name="primID"></param> | 2247 | /// <param name="primID"></param> |
2245 | /// <returns>null if a child part with the primID was not found</returns> | 2248 | /// <returns>null if a child part with the primID was not found</returns> |
@@ -2254,7 +2257,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2254 | } | 2257 | } |
2255 | 2258 | ||
2256 | /// <summary> | 2259 | /// <summary> |
2257 | /// Get a child part with a given local ID | 2260 | /// Get a part with a given local ID |
2258 | /// </summary> | 2261 | /// </summary> |
2259 | /// <param name="localID"></param> | 2262 | /// <param name="localID"></param> |
2260 | /// <returns>null if a child part with the local ID was not found</returns> | 2263 | /// <returns>null if a child part with the local ID was not found</returns> |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index da7ec44..fe1e218 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -90,10 +90,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
90 | SCALE = 0x40 | 90 | SCALE = 0x40 |
91 | } | 91 | } |
92 | 92 | ||
93 | public enum PrimType : int | ||
94 | { | ||
95 | BOX = 0, | ||
96 | CYLINDER = 1, | ||
97 | PRISM = 2, | ||
98 | SPHERE = 3, | ||
99 | TORUS = 4, | ||
100 | TUBE = 5, | ||
101 | RING = 6, | ||
102 | SCULPT = 7 | ||
103 | } | ||
104 | |||
93 | #endregion Enumerations | 105 | #endregion Enumerations |
94 | 106 | ||
95 | public class SceneObjectPart : IScriptHost | 107 | public class SceneObjectPart : IScriptHost |
96 | { | 108 | { |
109 | /// <value> | ||
110 | /// Denote all sides of the prim | ||
111 | /// </value> | ||
112 | public const int ALL_SIDES = -1; | ||
113 | |||
97 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 114 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
98 | 115 | ||
99 | // use only one serializer to give the runtime a chance to optimize it (it won't do that if you | 116 | // use only one serializer to give the runtime a chance to optimize it (it won't do that if you |
@@ -741,6 +758,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
741 | } | 758 | } |
742 | } | 759 | } |
743 | 760 | ||
761 | /// <value> | ||
762 | /// Text color. | ||
763 | /// </value> | ||
744 | public Color Color | 764 | public Color Color |
745 | { | 765 | { |
746 | get { return m_color; } | 766 | get { return m_color; } |
@@ -1910,7 +1930,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1910 | foreach (uint localId in startedColliders) | 1930 | foreach (uint localId in startedColliders) |
1911 | { | 1931 | { |
1912 | if (localId == 0) | 1932 | if (localId == 0) |
1913 | return; | 1933 | continue; |
1914 | // always running this check because if the user deletes the object it would return a null reference. | 1934 | // always running this check because if the user deletes the object it would return a null reference. |
1915 | if (m_parentGroup == null) | 1935 | if (m_parentGroup == null) |
1916 | return; | 1936 | return; |
@@ -2046,7 +2066,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2046 | { | 2066 | { |
2047 | // always running this check because if the user deletes the object it would return a null reference. | 2067 | // always running this check because if the user deletes the object it would return a null reference. |
2048 | if (localId == 0) | 2068 | if (localId == 0) |
2049 | return; | 2069 | continue; |
2050 | 2070 | ||
2051 | if (m_parentGroup == null) | 2071 | if (m_parentGroup == null) |
2052 | return; | 2072 | return; |
@@ -2178,7 +2198,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2178 | foreach (uint localId in endedColliders) | 2198 | foreach (uint localId in endedColliders) |
2179 | { | 2199 | { |
2180 | if (localId == 0) | 2200 | if (localId == 0) |
2181 | return; | 2201 | continue; |
2182 | 2202 | ||
2183 | // always running this check because if the user deletes the object it would return a null reference. | 2203 | // always running this check because if the user deletes the object it would return a null reference. |
2184 | if (m_parentGroup == null) | 2204 | if (m_parentGroup == null) |
@@ -2981,6 +3001,178 @@ namespace OpenSim.Region.Framework.Scenes | |||
2981 | PhysActor.VehicleFlagsRemove(flags); | 3001 | PhysActor.VehicleFlagsRemove(flags); |
2982 | } | 3002 | } |
2983 | } | 3003 | } |
3004 | |||
3005 | /// <summary> | ||
3006 | /// Set the color of prim faces | ||
3007 | /// </summary> | ||
3008 | /// <param name="color"></param> | ||
3009 | /// <param name="face"></param> | ||
3010 | public void SetFaceColor(Vector3 color, int face) | ||
3011 | { | ||
3012 | Primitive.TextureEntry tex = Shape.Textures; | ||
3013 | Color4 texcolor; | ||
3014 | if (face >= 0 && face < GetNumberOfSides()) | ||
3015 | { | ||
3016 | texcolor = tex.CreateFace((uint)face).RGBA; | ||
3017 | texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); | ||
3018 | texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); | ||
3019 | texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); | ||
3020 | tex.FaceTextures[face].RGBA = texcolor; | ||
3021 | UpdateTexture(tex); | ||
3022 | return; | ||
3023 | } | ||
3024 | else if (face == ALL_SIDES) | ||
3025 | { | ||
3026 | for (uint i = 0; i < GetNumberOfSides(); i++) | ||
3027 | { | ||
3028 | if (tex.FaceTextures[i] != null) | ||
3029 | { | ||
3030 | texcolor = tex.FaceTextures[i].RGBA; | ||
3031 | texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); | ||
3032 | texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); | ||
3033 | texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); | ||
3034 | tex.FaceTextures[i].RGBA = texcolor; | ||
3035 | } | ||
3036 | texcolor = tex.DefaultTexture.RGBA; | ||
3037 | texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); | ||
3038 | texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); | ||
3039 | texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); | ||
3040 | tex.DefaultTexture.RGBA = texcolor; | ||
3041 | } | ||
3042 | UpdateTexture(tex); | ||
3043 | return; | ||
3044 | } | ||
3045 | } | ||
3046 | |||
3047 | /// <summary> | ||
3048 | /// Get the number of sides that this part has. | ||
3049 | /// </summary> | ||
3050 | /// <returns></returns> | ||
3051 | public int GetNumberOfSides() | ||
3052 | { | ||
3053 | int ret = 0; | ||
3054 | bool hasCut; | ||
3055 | bool hasHollow; | ||
3056 | bool hasDimple; | ||
3057 | bool hasProfileCut; | ||
3058 | |||
3059 | PrimType primType = GetPrimType(); | ||
3060 | HasCutHollowDimpleProfileCut(primType, Shape, out hasCut, out hasHollow, out hasDimple, out hasProfileCut); | ||
3061 | |||
3062 | switch (primType) | ||
3063 | { | ||
3064 | case PrimType.BOX: | ||
3065 | ret = 6; | ||
3066 | if (hasCut) ret += 2; | ||
3067 | if (hasHollow) ret += 1; | ||
3068 | break; | ||
3069 | case PrimType.CYLINDER: | ||
3070 | ret = 3; | ||
3071 | if (hasCut) ret += 2; | ||
3072 | if (hasHollow) ret += 1; | ||
3073 | break; | ||
3074 | case PrimType.PRISM: | ||
3075 | ret = 5; | ||
3076 | if (hasCut) ret += 2; | ||
3077 | if (hasHollow) ret += 1; | ||
3078 | break; | ||
3079 | case PrimType.SPHERE: | ||
3080 | ret = 1; | ||
3081 | if (hasCut) ret += 2; | ||
3082 | if (hasDimple) ret += 2; | ||
3083 | if (hasHollow) ret += 1; | ||
3084 | break; | ||
3085 | case PrimType.TORUS: | ||
3086 | ret = 1; | ||
3087 | if (hasCut) ret += 2; | ||
3088 | if (hasProfileCut) ret += 2; | ||
3089 | if (hasHollow) ret += 1; | ||
3090 | break; | ||
3091 | case PrimType.TUBE: | ||
3092 | ret = 4; | ||
3093 | if (hasCut) ret += 2; | ||
3094 | if (hasProfileCut) ret += 2; | ||
3095 | if (hasHollow) ret += 1; | ||
3096 | break; | ||
3097 | case PrimType.RING: | ||
3098 | ret = 3; | ||
3099 | if (hasCut) ret += 2; | ||
3100 | if (hasProfileCut) ret += 2; | ||
3101 | if (hasHollow) ret += 1; | ||
3102 | break; | ||
3103 | case PrimType.SCULPT: | ||
3104 | ret = 1; | ||
3105 | break; | ||
3106 | } | ||
3107 | return ret; | ||
3108 | } | ||
3109 | |||
3110 | /// <summary> | ||
3111 | /// Tell us what type this prim is | ||
3112 | /// </summary> | ||
3113 | /// <param name="primShape"></param> | ||
3114 | /// <returns></returns> | ||
3115 | public PrimType GetPrimType() | ||
3116 | { | ||
3117 | if (Shape.SculptEntry) | ||
3118 | return PrimType.SCULPT; | ||
3119 | if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Square) | ||
3120 | { | ||
3121 | if (Shape.PathCurve == (byte)Extrusion.Straight) | ||
3122 | return PrimType.BOX; | ||
3123 | else if (Shape.PathCurve == (byte)Extrusion.Curve1) | ||
3124 | return PrimType.TUBE; | ||
3125 | } | ||
3126 | else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.Circle) | ||
3127 | { | ||
3128 | if (Shape.PathCurve == (byte)Extrusion.Straight) | ||
3129 | return PrimType.CYLINDER; | ||
3130 | // ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits | ||
3131 | else if (Shape.PathCurve == (byte)Extrusion.Curve1) | ||
3132 | return PrimType.TORUS; | ||
3133 | } | ||
3134 | else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle) | ||
3135 | { | ||
3136 | if (Shape.PathCurve == (byte)Extrusion.Curve1 || Shape.PathCurve == (byte)Extrusion.Curve2) | ||
3137 | return PrimType.SPHERE; | ||
3138 | } | ||
3139 | else if ((Shape.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle) | ||
3140 | { | ||
3141 | if (Shape.PathCurve == (byte)Extrusion.Straight) | ||
3142 | return PrimType.PRISM; | ||
3143 | else if (Shape.PathCurve == (byte)Extrusion.Curve1) | ||
3144 | return PrimType.RING; | ||
3145 | } | ||
3146 | |||
3147 | return PrimType.BOX; | ||
3148 | } | ||
3149 | |||
3150 | /// <summary> | ||
3151 | /// Tell us if this object has cut, hollow, dimple, and other factors affecting the number of faces | ||
3152 | /// </summary> | ||
3153 | /// <param name="primType"></param> | ||
3154 | /// <param name="shape"></param> | ||
3155 | /// <param name="hasCut"></param> | ||
3156 | /// <param name="hasHollow"></param> | ||
3157 | /// <param name="hasDimple"></param> | ||
3158 | /// <param name="hasProfileCut"></param> | ||
3159 | protected static void HasCutHollowDimpleProfileCut(PrimType primType, PrimitiveBaseShape shape, out bool hasCut, out bool hasHollow, | ||
3160 | out bool hasDimple, out bool hasProfileCut) | ||
3161 | { | ||
3162 | if (primType == PrimType.BOX | ||
3163 | || | ||
3164 | primType == PrimType.CYLINDER | ||
3165 | || | ||
3166 | primType == PrimType.PRISM) | ||
3167 | |||
3168 | hasCut = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); | ||
3169 | else | ||
3170 | hasCut = (shape.PathBegin > 0) || (shape.PathEnd > 0); | ||
3171 | |||
3172 | hasHollow = shape.ProfileHollow > 0; | ||
3173 | hasDimple = (shape.ProfileBegin > 0) || (shape.ProfileEnd > 0); // taken from llSetPrimitiveParms | ||
3174 | hasProfileCut = hasDimple; // is it the same thing? | ||
3175 | } | ||
2984 | 3176 | ||
2985 | public void SetGroup(UUID groupID, IClientAPI client) | 3177 | public void SetGroup(UUID groupID, IClientAPI client) |
2986 | { | 3178 | { |
@@ -3013,6 +3205,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3013 | } | 3205 | } |
3014 | } | 3206 | } |
3015 | 3207 | ||
3208 | /// <summary> | ||
3209 | /// Set the events that this part will pass on to listeners. | ||
3210 | /// </summary> | ||
3211 | /// <param name="scriptid"></param> | ||
3212 | /// <param name="events"></param> | ||
3016 | public void SetScriptEvents(UUID scriptid, int events) | 3213 | public void SetScriptEvents(UUID scriptid, int events) |
3017 | { | 3214 | { |
3018 | // scriptEvents oldparts; | 3215 | // scriptEvents oldparts; |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 9661775..3317dd3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -585,8 +585,32 @@ namespace OpenSim.Region.Framework.Scenes | |||
585 | m_items.TryGetValue(itemId, out item); | 585 | m_items.TryGetValue(itemId, out item); |
586 | m_items.LockItemsForRead(false); | 586 | m_items.LockItemsForRead(false); |
587 | return item; | 587 | return item; |
588 | } | 588 | } |
589 | |||
590 | /// <summary> | ||
591 | /// Get inventory items by name. | ||
592 | /// </summary> | ||
593 | /// <param name="name"></param> | ||
594 | /// <returns> | ||
595 | /// A list of inventory items with that name. | ||
596 | /// If no inventory item has that name then an empty list is returned. | ||
597 | /// </returns> | ||
598 | public IList<TaskInventoryItem> GetInventoryItems(string name) | ||
599 | { | ||
600 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); | ||
601 | |||
602 | lock (m_items) | ||
603 | { | ||
604 | foreach (TaskInventoryItem item in m_items.Values) | ||
605 | { | ||
606 | if (item.Name == name) | ||
607 | items.Add(item); | ||
608 | } | ||
609 | } | ||
589 | 610 | ||
611 | return items; | ||
612 | } | ||
613 | |||
590 | /// <summary> | 614 | /// <summary> |
591 | /// Update an existing inventory item. | 615 | /// Update an existing inventory item. |
592 | /// </summary> | 616 | /// </summary> |