diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index cf165716b3..8adf4d9e5d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -283,6 +283,80 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
+ ///
+ /// Get a given link entity from a linkset (linked objects and any sitting avatars).
+ ///
+ ///
+ /// If there are any ScenePresence's in the linkset (i.e. because they are sat upon one of the prims), then
+ /// these are counted as extra entities that correspond to linknums beyond the number of prims in the linkset.
+ /// The ScenePresences receive linknums in the order in which they sat.
+ ///
+ ///
+ /// The link entity. null if not found.
+ ///
+ ///
+ /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4).
+ /// If ScriptBaseClass.LINK_THIS then the entity containing the script is returned.
+ /// If the linkset has one entity and a linknum of zero is given, then the single entity is returned. If any
+ /// positive integer is given in this case then null is returned.
+ /// If the linkset has more than one entity and a linknum greater than zero but equal to or less than the number
+ /// of entities, then the entity which corresponds to that linknum is returned.
+ /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then
+ /// null is returned.
+ ///
+ public ISceneEntity GetLinkEntity(int linknum)
+ {
+ if (linknum < 0)
+ {
+ if (linknum == ScriptBaseClass.LINK_THIS)
+ return m_host;
+ else
+ return null;
+ }
+
+ int actualPrimCount = m_host.ParentGroup.PrimCount;
+ List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
+ int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
+
+ // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
+ // prim that has any avatars sat upon it (in which case the root prim is link 1).
+ if (linknum == 0)
+ {
+ if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
+ return m_host;
+
+ return null;
+ }
+ // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
+ // here we must match 1 (ScriptBaseClass.LINK_ROOT).
+ else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1)
+ {
+ if (sittingAvatarIds.Count > 0)
+ return m_host.ParentGroup.RootPart;
+ else
+ return null;
+ }
+ else if (linknum <= adjustedPrimCount)
+ {
+ if (linknum <= actualPrimCount)
+ {
+ return m_host.ParentGroup.GetLinkNumPart(linknum);
+ }
+ else
+ {
+ ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
+ if (sp != null)
+ return sp;
+ else
+ return null;
+ }
+ }
+ else
+ {
+ return null;
+ }
+ }
+
public List GetLinkParts(int linkType)
{
return GetLinkParts(m_host, linkType);
@@ -3697,47 +3771,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- if (linknum < 0)
- {
- if (linknum == ScriptBaseClass.LINK_THIS)
- return m_host.UUID.ToString();
- else
- return ScriptBaseClass.NULL_KEY;
- }
+ ISceneEntity entity = GetLinkEntity(linknum);
- int actualPrimCount = m_host.ParentGroup.PrimCount;
- List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
- int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
-
- // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
- // prim that has any avatars sat upon it (in which case the root prim is link 1).
- if (linknum == 0)
- {
- if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
- return m_host.UUID.ToString();
-
- return ScriptBaseClass.NULL_KEY;
- }
- // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
- // here we must match 1 (ScriptBaseClass.LINK_ROOT).
- else if (linknum == 1 && actualPrimCount == 1)
- {
- if (sittingAvatarIds.Count > 0)
- return m_host.ParentGroup.RootPart.UUID.ToString();
- else
- return ScriptBaseClass.NULL_KEY;
- }
- else if (linknum <= adjustedPrimCount)
- {
- if (linknum <= actualPrimCount)
- return m_host.ParentGroup.GetLinkNumPart(linknum).UUID.ToString();
- else
- return sittingAvatarIds[linknum - actualPrimCount - 1].ToString();
- }
+ if (entity != null)
+ return entity.UUID.ToString();
else
- {
return ScriptBaseClass.NULL_KEY;
- }
}
///
@@ -3783,55 +3822,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- if (linknum < 0)
- {
- if (linknum == ScriptBaseClass.LINK_THIS)
- return m_host.Name;
- else
- return ScriptBaseClass.NULL_KEY;
- }
+ ISceneEntity entity = GetLinkEntity(linknum);
- int actualPrimCount = m_host.ParentGroup.PrimCount;
- List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
- int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count;
-
- // Special case for a single prim. In this case the linknum is zero. However, this will not match a single
- // prim that has any avatars sat upon it (in which case the root prim is link 1).
- if (linknum == 0)
- {
- if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
- return m_host.Name;
-
- return ScriptBaseClass.NULL_KEY;
- }
- // Special case to handle a single prim with sitting avatars. GetLinkPart() would only match zero but
- // here we must match 1 (ScriptBaseClass.LINK_ROOT).
- else if (linknum == 1 && actualPrimCount == 1)
- {
- if (sittingAvatarIds.Count > 0)
- return m_host.ParentGroup.RootPart.Name;
- else
- return ScriptBaseClass.NULL_KEY;
- }
- else if (linknum <= adjustedPrimCount)
- {
- if (linknum <= actualPrimCount)
- {
- return m_host.ParentGroup.GetLinkNumPart(linknum).Name;
- }
- else
- {
- ScenePresence sp = World.GetScenePresence(sittingAvatarIds[linknum - actualPrimCount - 1]);
- if (sp != null)
- return sp.Name;
- else
- return ScriptBaseClass.NULL_KEY;
- }
- }
+ if (entity != null)
+ return entity.Name;
else
- {
return ScriptBaseClass.NULL_KEY;
- }
}
public LSL_Integer llGetInventoryNumber(int type)