From 515324a1aa08b1bdb432ade07361738ff37d06e2 Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Fri, 15 Mar 2013 00:06:42 +0000 Subject: [PATCH] refactor: make llGetLinkName() and llGetLinkKey() use a common GetLinkEntity() method --- .../Shared/Api/Implementation/LSL_Api.cs | 164 +++++++++--------- 1 file changed, 81 insertions(+), 83 deletions(-) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index b4a3290516..1b0cc542dc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -274,6 +274,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); @@ -3765,47 +3839,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; - } } /// @@ -3859,53 +3898,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api nametable.Add(presence.ControllingClient.Name); }); - int totalprims = m_host.ParentGroup.PrimCount + nametable.Count; - if (totalprims > m_host.ParentGroup.PrimCount) - { - // sitting Avatar-Name with negativ linknum / SinglePrim - if (linknum < 0 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1) - return nametable[0]; - // Prim-Name / SinglePrim Sitting Avatar - if (linknum == 1 && m_host.ParentGroup.PrimCount == 1 && nametable.Count == 1) - return m_host.Name; - // LinkNumber > of Real PrimSet = AvatarName - if (linknum > m_host.ParentGroup.PrimCount && linknum <= totalprims) - return nametable[totalprims - linknum]; - } + ISceneEntity entity = GetLinkEntity(linknum); - // simplest case, this prims link number - if (linknum == m_host.LinkNum) - return m_host.Name; - - // Single prim - if (m_host.LinkNum == 0) - { - if (linknum == 0 || linknum == ScriptBaseClass.LINK_ROOT) - return m_host.Name; - else - return UUID.Zero.ToString(); - } - - // Link set - SceneObjectPart part = null; - if (m_host.LinkNum == 1) // this is the Root prim - { - if (linknum < 0) - part = m_host.ParentGroup.GetLinkNumPart(2); - else - part = m_host.ParentGroup.GetLinkNumPart(linknum); - } - else // this is a child prim - { - if (linknum < 2) - part = m_host.ParentGroup.GetLinkNumPart(1); - else - part = m_host.ParentGroup.GetLinkNumPart(linknum); - } - if (part != null) - return part.Name; + if (entity != null) + return entity.Name; else - return UUID.Zero.ToString(); + return ScriptBaseClass.NULL_KEY; } public LSL_Integer llGetInventoryNumber(int type)