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, 66570.8.0.3
							parent
							
								
									26fe59c35e
								
							
						
					
					
						commit
						0e23374aa2
					
				|  | @ -313,6 +313,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         /// <returns> |         /// <returns> | ||||||
|         /// The link entity.  null if not found. |         /// The link entity.  null if not found. | ||||||
|         /// </returns> |         /// </returns> | ||||||
|  |         /// <param name='part'></param> | ||||||
|         /// <param name='linknum'> |         /// <param name='linknum'> | ||||||
|         /// Can be either a non-negative integer or ScriptBaseClass.LINK_THIS (-4). |         /// 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 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 |         /// Otherwise, if a positive linknum is given which is greater than the number of entities in the linkset, then | ||||||
|         /// null is returned. |         /// null is returned. | ||||||
|         /// </param> |         /// </param> | ||||||
|         public ISceneEntity GetLinkEntity(int linknum) |         public ISceneEntity GetLinkEntity(SceneObjectPart part, int linknum) | ||||||
|         { |         { | ||||||
|             if (linknum < 0) |             if (linknum < 0) | ||||||
|             { |             { | ||||||
|                 if (linknum == ScriptBaseClass.LINK_THIS) |                 if (linknum == ScriptBaseClass.LINK_THIS) | ||||||
|                     return m_host; |                     return part; | ||||||
|                 else |                 else | ||||||
|                     return null; |                     return null; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             int actualPrimCount = m_host.ParentGroup.PrimCount; |             int actualPrimCount = part.ParentGroup.PrimCount; | ||||||
|             List<UUID> sittingAvatarIds = m_host.ParentGroup.GetSittingAvatars(); |             List<UUID> sittingAvatarIds = part.ParentGroup.GetSittingAvatars(); | ||||||
|             int adjustedPrimCount = actualPrimCount + sittingAvatarIds.Count; |             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 |             // 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 (linknum == 0) | ||||||
|             { |             { | ||||||
|                 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) |                 if (actualPrimCount == 1 && sittingAvatarIds.Count == 0) | ||||||
|                     return m_host; |                     return part; | ||||||
| 
 | 
 | ||||||
|                 return null; |                 return null; | ||||||
|             } |             } | ||||||
|  | @ -351,7 +352,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1) |             else if (linknum == ScriptBaseClass.LINK_ROOT && actualPrimCount == 1) | ||||||
|             { |             { | ||||||
|                 if (sittingAvatarIds.Count > 0) |                 if (sittingAvatarIds.Count > 0) | ||||||
|                     return m_host.ParentGroup.RootPart; |                     return part.ParentGroup.RootPart; | ||||||
|                 else |                 else | ||||||
|                     return null; |                     return null; | ||||||
|             } |             } | ||||||
|  | @ -359,7 +360,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             { |             { | ||||||
|                 if (linknum <= actualPrimCount) |                 if (linknum <= actualPrimCount) | ||||||
|                 { |                 { | ||||||
|                     return m_host.ParentGroup.GetLinkNumPart(linknum); |                     return part.ParentGroup.GetLinkNumPart(linknum); | ||||||
|                 } |                 } | ||||||
|                 else |                 else | ||||||
|                 { |                 { | ||||||
|  | @ -427,6 +428,57 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         public List<ISceneEntity> GetLinkEntities(int linkType) | ||||||
|  |         { | ||||||
|  |             return GetLinkEntities(m_host, linkType); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public List<ISceneEntity> GetLinkEntities(SceneObjectPart part, int linkType) | ||||||
|  |         { | ||||||
|  |             List<ISceneEntity> ret = new List<ISceneEntity>(); | ||||||
|  |             ret.Add(part); | ||||||
|  | 
 | ||||||
|  |             switch (linkType) | ||||||
|  |             { | ||||||
|  |                 case ScriptBaseClass.LINK_SET: | ||||||
|  |                     return new List<ISceneEntity>(part.ParentGroup.Parts); | ||||||
|  | 
 | ||||||
|  |                 case ScriptBaseClass.LINK_ROOT: | ||||||
|  |                     ret = new List<ISceneEntity>(); | ||||||
|  |                     ret.Add(part.ParentGroup.RootPart); | ||||||
|  |                     return ret; | ||||||
|  | 
 | ||||||
|  |                 case ScriptBaseClass.LINK_ALL_OTHERS: | ||||||
|  |                     ret = new List<ISceneEntity>(part.ParentGroup.Parts); | ||||||
|  | 
 | ||||||
|  |                     if (ret.Contains(part)) | ||||||
|  |                         ret.Remove(part); | ||||||
|  | 
 | ||||||
|  |                     return ret; | ||||||
|  | 
 | ||||||
|  |                 case ScriptBaseClass.LINK_ALL_CHILDREN: | ||||||
|  |                     ret = new List<ISceneEntity>(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>(); | ||||||
|  | 
 | ||||||
|  |                     ISceneEntity target = GetLinkEntity(part, linkType); | ||||||
|  |                     if (target == null) | ||||||
|  |                         return new List<ISceneEntity>(); | ||||||
|  |                     ret = new List<ISceneEntity>(); | ||||||
|  |                     ret.Add(target); | ||||||
|  |                     return ret; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|         //These are the implementations of the various ll-functions used by the LSL scripts. |         //These are the implementations of the various ll-functions used by the LSL scripts. | ||||||
|         public LSL_Float llSin(double f) |         public LSL_Float llSin(double f) | ||||||
|         { |         { | ||||||
|  | @ -3882,7 +3934,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
| 
 | 
 | ||||||
|             ISceneEntity entity = GetLinkEntity(linknum); |             ISceneEntity entity = GetLinkEntity(m_host, linknum); | ||||||
| 
 | 
 | ||||||
|             if (entity != null) |             if (entity != null) | ||||||
|                 return entity.UUID.ToString(); |                 return entity.UUID.ToString(); | ||||||
|  | @ -3933,7 +3985,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
|         { |         { | ||||||
|             m_host.AddScriptLPS(1); |             m_host.AddScriptLPS(1); | ||||||
| 
 | 
 | ||||||
|             ISceneEntity entity = GetLinkEntity(linknum); |             ISceneEntity entity = GetLinkEntity(m_host, linknum); | ||||||
| 
 | 
 | ||||||
|             if (entity != null) |             if (entity != null) | ||||||
|                 return entity.Name; |                 return entity.Name; | ||||||
|  | @ -7371,22 +7423,32 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|         protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) |         protected void setLinkPrimParams(int linknumber, LSL_List rules, string originFunc) | ||||||
|         { |         { | ||||||
|             List<SceneObjectPart> parts = GetLinkParts(linknumber); |             List<ISceneEntity> entities = GetLinkEntities(linknumber); | ||||||
| 
 | 
 | ||||||
|             LSL_List remaining = null; |             LSL_List remaining = null; | ||||||
|             uint rulesParsed = 0; |             uint rulesParsed = 0; | ||||||
| 
 | 
 | ||||||
|             foreach (SceneObjectPart part in parts) |             foreach (ISceneEntity entity in entities) | ||||||
|                 remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); |             { | ||||||
|  |                 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) |             while (remaining != null && remaining.Length > 2) | ||||||
|             { |             { | ||||||
|                 linknumber = remaining.GetLSLIntegerItem(0); |                 linknumber = remaining.GetLSLIntegerItem(0); | ||||||
|                 rules = remaining.GetSublist(1, -1); |                 rules = remaining.GetSublist(1, -1); | ||||||
|                 parts = GetLinkParts(linknumber); |                 entities = GetLinkEntities(linknumber); | ||||||
| 
 | 
 | ||||||
|                 foreach (SceneObjectPart part in parts) |                 foreach (ISceneEntity entity in entities) | ||||||
|                     remaining = SetPrimParams(part, rules, originFunc, ref rulesParsed); |                 { | ||||||
|  |                     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; |             return null; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | @ -8225,7 +8336,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | ||||||
| 
 | 
 | ||||||
|                 int linknumber = remaining.GetLSLIntegerItem(0); |                 int linknumber = remaining.GetLSLIntegerItem(0); | ||||||
|                 rules = remaining.GetSublist(1, -1); |                 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); |             m_host.AddScriptLPS(1); | ||||||
| 
 | 
 | ||||||
|             return GetEntityParams(GetLinkEntity(linknumber), rules); |             return GetEntityParams(GetLinkEntity(m_host, linknumber), rules); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public LSL_Vector GetAgentSize(ScenePresence sp) |         public LSL_Vector GetAgentSize(ScenePresence sp) | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Justin Clark-Casey (justincc)
						Justin Clark-Casey (justincc)