From 0e23374aa244bb1e6f949228bf37241296c52209 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Wed, 26 Feb 2014 23:07:13 +0000
Subject: Implement PRIM_ROTATION, PRIM_ROT_LOCAL, PRIM_POSITION and
PRIM_POS_LOCAL when manipulating avatars via llSetLinkPrimitiveParams()
Combination of core parts of Freaky's patch at https://github.com/ft-/opensim-patches/blob/master/opensim-llsetlinkprimitive-agent-fix.patch plus further adjustments from myself.
Resolves Mantises 6121, 6421, 6573, 6657
---
.../Shared/Api/Implementation/LSL_Api.cs | 145 ++++++++++++++++++---
1 file changed, 128 insertions(+), 17 deletions(-)
(limited to 'OpenSim/Region/ScriptEngine')
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 91885b7..25d8c54 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -313,6 +313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
///
/// 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.
@@ -323,18 +324,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
/// 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)
+ public ISceneEntity GetLinkEntity(SceneObjectPart part, int linknum)
{
if (linknum < 0)
{
if (linknum == ScriptBaseClass.LINK_THIS)
- return m_host;
+ return part;
else
return null;
}
- int actualPrimCount = m_host.ParentGroup.PrimCount;
- List sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars();
+ int actualPrimCount = part.ParentGroup.PrimCount;
+ List sittingAvatarIds = part.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
@@ -342,7 +343,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
if (linknum == 0)
{
if (actualPrimCount == 1 && sittingAvatarIds.Count == 0)
- return m_host;
+ return part;
return null;
}
@@ -351,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1)
{
if (sittingAvatarIds.Count > 0)
- return m_host.ParentGroup.RootPart;
+ return part.ParentGroup.RootPart;
else
return null;
}
@@ -359,7 +360,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
if (linknum <= actualPrimCount)
{
- return m_host.ParentGroup.GetLinkNumPart(linknum);
+ return part.ParentGroup.GetLinkNumPart(linknum);
}
else
{
@@ -427,6 +428,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
+ public List GetLinkEntities(int linkType)
+ {
+ return GetLinkEntities(m_host, linkType);
+ }
+
+ public List GetLinkEntities(SceneObjectPart part, int linkType)
+ {
+ List ret = new List();
+ ret.Add(part);
+
+ switch (linkType)
+ {
+ case ScriptBaseClass.LINK_SET:
+ return new List(part.ParentGroup.Parts);
+
+ case ScriptBaseClass.LINK_ROOT:
+ ret = new List();
+ ret.Add(part.ParentGroup.RootPart);
+ return ret;
+
+ case ScriptBaseClass.LINK_ALL_OTHERS:
+ ret = new List(part.ParentGroup.Parts);
+
+ if (ret.Contains(part))
+ ret.Remove(part);
+
+ return ret;
+
+ case ScriptBaseClass.LINK_ALL_CHILDREN:
+ ret = new List(part.ParentGroup.Parts);
+
+ if (ret.Contains(part.ParentGroup.RootPart))
+ ret.Remove(part.ParentGroup.RootPart);
+ return ret;
+
+ case ScriptBaseClass.LINK_THIS:
+ return ret;
+
+ default:
+ if (linkType < 0)
+ return new List();
+
+ ISceneEntity target = GetLinkEntity(part, linkType);
+ if (target == null)
+ return new List();
+ ret = new List();
+ ret.Add(target);
+ return ret;
+ }
+ }
+
//These are the implementations of the various ll-functions used by the LSL scripts.
public LSL_Float llSin(double f)
{
@@ -3882,7 +3934,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- ISceneEntity entity = GetLinkEntity(linknum);
+ ISceneEntity entity = GetLinkEntity(m_host, linknum);
if (entity != null)
return entity.UUID.ToString();
@@ -3933,7 +3985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- ISceneEntity entity = GetLinkEntity(linknum);
+ ISceneEntity entity = GetLinkEntity(m_host, linknum);
if (entity != null)
return entity.Name;
@@ -7371,22 +7423,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc)
{
- List parts = GetLinkParts(linknumber);
+ List entities = GetLinkEntities(linknumber);
LSL_List remaining = null;
uint rulesParsed = 0;
- foreach (SceneObjectPart part in parts)
- remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
+ foreach (ISceneEntity entity in entities)
+ {
+ if (entity is SceneObjectPart)
+ remaining = SetPrimParams((SceneObjectPart)entity, rules, originFunc, ref rulesParsed);
+ else
+ remaining = SetAgentParams((ScenePresence)entity, rules, originFunc, ref rulesParsed);
+ }
while (remaining != null && remaining.Length > 2)
{
linknumber = remaining.GetLSLIntegerItem(0);
rules = remaining.GetSublist(1, -1);
- parts = GetLinkParts(linknumber);
+ entities = GetLinkEntities(linknumber);
- foreach (SceneObjectPart part in parts)
- remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed);
+ foreach (ISceneEntity entity in entities)
+ {
+ if (entity is SceneObjectPart)
+ remaining = SetPrimParams((SceneObjectPart)entity, rules, originFunc, ref rulesParsed);
+ else
+ remaining = SetAgentParams((ScenePresence)entity, rules, originFunc, ref rulesParsed);
+ }
}
}
@@ -7956,6 +8018,55 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
}
}
}
+
+ return null;
+ }
+
+ protected LSL_List SetAgentParams(ScenePresence sp, LSL_List rules, string originFunc, ref uint rulesParsed)
+ {
+ int idx = 0;
+ int idxStart = 0;
+
+ try
+ {
+ while (idx < rules.Length)
+ {
+ ++rulesParsed;
+ int code = rules.GetLSLIntegerItem(idx++);
+
+ int remain = rules.Length - idx;
+ idxStart = idx;
+
+ LSL_Vector v;
+
+ switch (code)
+ {
+ case (int)ScriptBaseClass.PRIM_POSITION:
+ case (int)ScriptBaseClass.PRIM_POS_LOCAL:
+ if (remain < 1)
+ return null;
+
+ sp.OffsetPosition = rules.GetVector3Item(idx++);
+ break;
+
+ case (int)ScriptBaseClass.PRIM_ROTATION:
+ case (int)ScriptBaseClass.PRIM_ROT_LOCAL:
+ if (remain < 1)
+ return null;
+
+ sp.Rotation = rules.GetQuaternionItem(idx++);
+
+ break;
+ }
+ }
+ }
+ catch (InvalidCastException e)
+ {
+ Error(
+ originFunc,
+ string.Format("Error running rule #{0}: arg #{1} - ", rulesParsed, idx - idxStart) + e.Message);
+ }
+
return null;
}
@@ -8225,7 +8336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
int linknumber = remaining.GetLSLIntegerItem(0);
rules = remaining.GetSublist(1, -1);
- entity = GetLinkEntity(linknumber);
+ entity = GetLinkEntity(m_host, linknumber);
}
}
@@ -8240,7 +8351,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
{
m_host.AddScriptLPS(1);
- return GetEntityParams(GetLinkEntity(linknumber), rules);
+ return GetEntityParams(GetLinkEntity(m_host, linknumber), rules);
}
public LSL_Vector GetAgentSize(ScenePresence sp)
--
cgit v1.1