From 681066050c2f7019d1b425c86f7985d7650d8226 Mon Sep 17 00:00:00 2001 From: Melanie Date: Sat, 25 Aug 2012 18:32:59 +0100 Subject: Also move the other avatar based overload out of harms way --- .../Shared/Api/Implementation/LSL_Api.cs | 1430 ++++++++++---------- 1 file changed, 715 insertions(+), 715 deletions(-) (limited to 'OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2bdb485..64f145b 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8670,75 +8670,142 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return res; } - public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules) + public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules) { - // avatars case - // replies as SL wiki - LSL_List res = new LSL_List(); -// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed - SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone?? - - int idx = 0; + int idx=0; while (idx < rules.Length) { - int code = (int)rules.GetLSLIntegerItem(idx++); - int remain = rules.Length - idx; + int code=(int)rules.GetLSLIntegerItem(idx++); + int remain=rules.Length-idx; switch (code) { case (int)ScriptBaseClass.PRIM_MATERIAL: - res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh)); + res.Add(new LSL_Integer(part.Material)); break; case (int)ScriptBaseClass.PRIM_PHYSICS: + if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0) + res.Add(new LSL_Integer(1)); + else res.Add(new LSL_Integer(0)); break; case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: + if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) != 0) + res.Add(new LSL_Integer(1)); + else res.Add(new LSL_Integer(0)); break; case (int)ScriptBaseClass.PRIM_PHANTOM: + if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) + res.Add(new LSL_Integer(1)); + else res.Add(new LSL_Integer(0)); break; case (int)ScriptBaseClass.PRIM_POSITION: - - Vector3 pos = avatar.OffsetPosition; - - Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f); - pos -= sitOffset; - - if( sitPart != null) - pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation(); - - res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z)); + LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, + part.AbsolutePosition.Y, + part.AbsolutePosition.Z); + res.Add(v); break; case (int)ScriptBaseClass.PRIM_SIZE: - // as in llGetAgentSize above - res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight)); + res.Add(new LSL_Vector(part.Scale.X, + part.Scale.Y, + part.Scale.Z)); break; case (int)ScriptBaseClass.PRIM_ROTATION: - Quaternion rot = avatar.Rotation; - if (sitPart != null) - { - rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation - } - - res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W)); + res.Add(GetPartRot(part)); break; case (int)ScriptBaseClass.PRIM_TYPE: - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX)); - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT)); - res.Add(new LSL_Vector(0f,1.0f,0f)); - res.Add(new LSL_Float(0.0f)); - res.Add(new LSL_Vector(0, 0, 0)); - res.Add(new LSL_Vector(1.0f,1.0f,0f)); - res.Add(new LSL_Vector(0, 0, 0)); + // implementing box + PrimitiveBaseShape Shape = part.Shape; + int primType = (int)part.GetPrimType(); + res.Add(new LSL_Integer(primType)); + double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX + double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY. + switch (primType) + { + case ScriptBaseClass.PRIM_TYPE_BOX: + case ScriptBaseClass.PRIM_TYPE_CYLINDER: + case ScriptBaseClass.PRIM_TYPE_PRISM: + res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. + res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); + res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); + res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); + res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); + res.Add(new LSL_Vector(topshearx, topsheary, 0)); + break; + + case ScriptBaseClass.PRIM_TYPE_SPHERE: + res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. + res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); + res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); + res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); + res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); + break; + + case ScriptBaseClass.PRIM_TYPE_SCULPT: + res.Add(Shape.SculptTexture.ToString()); + res.Add(new LSL_Integer(Shape.SculptType)); + break; + + case ScriptBaseClass.PRIM_TYPE_RING: + case ScriptBaseClass.PRIM_TYPE_TUBE: + case ScriptBaseClass.PRIM_TYPE_TORUS: + // holeshape + res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. + + // cut + res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); + + // hollow + res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); + + // twist + res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); + + // vector holesize + res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); + + // vector topshear + res.Add(new LSL_Vector(topshearx, topsheary, 0)); + + // vector profilecut + res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); + + // vector tapera + res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); + + // float revolutions + res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); + // Slightly inaccurate, because an unsigned byte is being used to represent + // the entire range of floating-point values from 1.0 through 4.0 (which is how + // SL does it). + // + // Using these formulas to store and retrieve PathRevolutions, it is not + // possible to use all values between 1.00 and 4.00. For instance, you can't + // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you + // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them + // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar + // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. + // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value + // such as 1.10. So, SL must store and retreive the actual user input rather + // than only storing the encoded value. + + // float radiusoffset + res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); + + // float skew + res.Add(new LSL_Float(Shape.PathSkew / 100.0)); + break; + } break; case (int)ScriptBaseClass.PRIM_TEXTURE: @@ -8746,24 +8813,37 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return res; int face = (int)rules.GetLSLIntegerItem(idx++); + Primitive.TextureEntry tex = part.Shape.Textures; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < 21; face++) + for (face = 0 ; face < GetNumberOfSides(part); face++) { - res.Add(new LSL_String("")); - res.Add(new LSL_Vector(0,0,0)); - res.Add(new LSL_Vector(0,0,0)); - res.Add(new LSL_Float(0.0)); + Primitive.TextureEntryFace texface = tex.GetFace((uint)face); + + res.Add(new LSL_String(texface.TextureID.ToString())); + res.Add(new LSL_Vector(texface.RepeatU, + texface.RepeatV, + 0)); + res.Add(new LSL_Vector(texface.OffsetU, + texface.OffsetV, + 0)); + res.Add(new LSL_Float(texface.Rotation)); } } else { - if (face >= 0 && face < 21) + if (face >= 0 && face < GetNumberOfSides(part)) { - res.Add(new LSL_String("")); - res.Add(new LSL_Vector(0,0,0)); - res.Add(new LSL_Vector(0,0,0)); - res.Add(new LSL_Float(0.0)); + Primitive.TextureEntryFace texface = tex.GetFace((uint)face); + + res.Add(new LSL_String(texface.TextureID.ToString())); + res.Add(new LSL_Vector(texface.RepeatU, + texface.RepeatV, + 0)); + res.Add(new LSL_Vector(texface.OffsetU, + texface.OffsetV, + 0)); + res.Add(new LSL_Float(texface.Rotation)); } } break; @@ -8772,20 +8852,28 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if (remain < 1) return res; - face = (int)rules.GetLSLIntegerItem(idx++); + face=(int)rules.GetLSLIntegerItem(idx++); + tex = part.Shape.Textures; + Color4 texcolor; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < 21; face++) + for (face = 0 ; face < GetNumberOfSides(part); face++) { - res.Add(new LSL_Vector(0,0,0)); - res.Add(new LSL_Float(0)); + texcolor = tex.GetFace((uint)face).RGBA; + res.Add(new LSL_Vector(texcolor.R, + texcolor.G, + texcolor.B)); + res.Add(new LSL_Float(texcolor.A)); } } else { - res.Add(new LSL_Vector(0,0,0)); - res.Add(new LSL_Float(0)); + texcolor = tex.GetFace((uint)face).RGBA; + res.Add(new LSL_Vector(texcolor.R, + texcolor.G, + texcolor.B)); + res.Add(new LSL_Float(texcolor.A)); } break; @@ -8794,18 +8882,54 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return res; face = (int)rules.GetLSLIntegerItem(idx++); + tex = part.Shape.Textures; + int shiny; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < 21; face++) + for (face = 0; face < GetNumberOfSides(part); face++) { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE)); - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE)); + Shininess shinyness = tex.GetFace((uint)face).Shiny; + if (shinyness == Shininess.High) + { + shiny = ScriptBaseClass.PRIM_SHINY_HIGH; + } + else if (shinyness == Shininess.Medium) + { + shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; + } + else if (shinyness == Shininess.Low) + { + shiny = ScriptBaseClass.PRIM_SHINY_LOW; + } + else + { + shiny = ScriptBaseClass.PRIM_SHINY_NONE; + } + res.Add(new LSL_Integer(shiny)); + res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); } } else { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE)); - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE)); + Shininess shinyness = tex.GetFace((uint)face).Shiny; + if (shinyness == Shininess.High) + { + shiny = ScriptBaseClass.PRIM_SHINY_HIGH; + } + else if (shinyness == Shininess.Medium) + { + shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; + } + else if (shinyness == Shininess.Low) + { + shiny = ScriptBaseClass.PRIM_SHINY_LOW; + } + else + { + shiny = ScriptBaseClass.PRIM_SHINY_NONE; + } + res.Add(new LSL_Integer(shiny)); + res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); } break; @@ -8814,27 +8938,52 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return res; face = (int)rules.GetLSLIntegerItem(idx++); + tex = part.Shape.Textures; + int fullbright; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < 21; face++) + for (face = 0; face < GetNumberOfSides(part); face++) { - res.Add(new LSL_Integer(ScriptBaseClass.FALSE)); + if (tex.GetFace((uint)face).Fullbright == true) + { + fullbright = ScriptBaseClass.TRUE; + } + else + { + fullbright = ScriptBaseClass.FALSE; + } + res.Add(new LSL_Integer(fullbright)); } } else { - res.Add(new LSL_Integer(ScriptBaseClass.FALSE)); - } + if (tex.GetFace((uint)face).Fullbright == true) + { + fullbright = ScriptBaseClass.TRUE; + } + else + { + fullbright = ScriptBaseClass.FALSE; + } + res.Add(new LSL_Integer(fullbright)); + } break; case (int)ScriptBaseClass.PRIM_FLEXIBLE: - res.Add(new LSL_Integer(0)); - res.Add(new LSL_Integer(0));// softness - res.Add(new LSL_Float(0.0f)); // gravity - res.Add(new LSL_Float(0.0f)); // friction - res.Add(new LSL_Float(0.0f)); // wind - res.Add(new LSL_Float(0.0f)); // tension - res.Add(new LSL_Vector(0f,0f,0f)); + PrimitiveBaseShape shape = part.Shape; + + if (shape.FlexiEntry) + res.Add(new LSL_Integer(1)); // active + else + res.Add(new LSL_Integer(0)); + res.Add(new LSL_Integer(shape.FlexiSoftness));// softness + res.Add(new LSL_Float(shape.FlexiGravity)); // gravity + res.Add(new LSL_Float(shape.FlexiDrag)); // friction + res.Add(new LSL_Float(shape.FlexiWind)); // wind + res.Add(new LSL_Float(shape.FlexiTension)); // tension + res.Add(new LSL_Vector(shape.FlexiForceX, // force + shape.FlexiForceY, + shape.FlexiForceZ)); break; case (int)ScriptBaseClass.PRIM_TEXGEN: @@ -8843,25 +8992,47 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return res; face = (int)rules.GetLSLIntegerItem(idx++); + tex = part.Shape.Textures; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < 21; face++) + for (face = 0; face < GetNumberOfSides(part); face++) { + if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); + } + else + { res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); + } } } else { + if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); + } + else + { res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); + } } break; case (int)ScriptBaseClass.PRIM_POINT_LIGHT: - res.Add(new LSL_Integer(0)); - res.Add(new LSL_Vector(0f,0f,0f)); - res.Add(new LSL_Float(0f)); // intensity - res.Add(new LSL_Float(0f)); // radius - res.Add(new LSL_Float(0f)); // falloff + shape = part.Shape; + + if (shape.LightEntry) + res.Add(new LSL_Integer(1)); // active + else + res.Add(new LSL_Integer(0)); + res.Add(new LSL_Vector(shape.LightColorR, // color + shape.LightColorG, + shape.LightColorB)); + res.Add(new LSL_Float(shape.LightIntensity)); // intensity + res.Add(new LSL_Float(shape.LightRadius)); // radius + res.Add(new LSL_Float(shape.LightFalloff)); // falloff break; case (int)ScriptBaseClass.PRIM_GLOW: @@ -8869,591 +9040,159 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return res; face = (int)rules.GetLSLIntegerItem(idx++); + tex = part.Shape.Textures; + float primglow; if (face == ScriptBaseClass.ALL_SIDES) { - for (face = 0; face < 21; face++) + for (face = 0; face < GetNumberOfSides(part); face++) { - res.Add(new LSL_Float(0f)); + primglow = tex.GetFace((uint)face).Glow; + res.Add(new LSL_Float(primglow)); } } else { - res.Add(new LSL_Float(0f)); + primglow = tex.GetFace((uint)face).Glow; + res.Add(new LSL_Float(primglow)); } break; case (int)ScriptBaseClass.PRIM_TEXT: - res.Add(new LSL_String("")); - res.Add(new LSL_Vector(0f,0f,0f)); - res.Add(new LSL_Float(1.0f)); + Color4 textColor = part.GetTextColor(); + res.Add(new LSL_String(part.Text)); + res.Add(new LSL_Vector(textColor.R, + textColor.G, + textColor.B)); + res.Add(new LSL_Float(textColor.A)); break; case (int)ScriptBaseClass.PRIM_NAME: - res.Add(new LSL_String(avatar.Name)); + res.Add(new LSL_String(part.Name)); break; case (int)ScriptBaseClass.PRIM_DESC: - res.Add(new LSL_String("")); + res.Add(new LSL_String(part.Description)); break; - case (int)ScriptBaseClass.PRIM_ROT_LOCAL: - Quaternion lrot = avatar.Rotation; - - if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart) - { - lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset - } - res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W)); + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); break; case (int)ScriptBaseClass.PRIM_POS_LOCAL: - Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part - Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f); - lpos -= lsitOffset; - - if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart) - { - lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim - } - res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z)); + res.Add(new LSL_Vector(GetPartLocalPos(part))); break; - case (int)ScriptBaseClass.PRIM_LINK_TARGET: if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. return res; LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); LSL_List new_rules = rules.GetSublist(idx, -1); - - res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules); - return res; + LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules); + res += tres; + return res; + case (int)ScriptBaseClass.PRIM_SLICE: + PrimType prim_type = part.GetPrimType(); + bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING); + res.Add(new LSL_Vector( + (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0, + 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0, + 0 + )); + break; } } return res; } - public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules) + public LSL_List llGetPrimMediaParams(int face, LSL_List rules) + { + m_host.AddScriptLPS(1); + ScriptSleep(1000); + return GetPrimMediaParams(m_host, face, rules); + } + + public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) + { + m_host.AddScriptLPS(1); + ScriptSleep(1000); + if (link == ScriptBaseClass.LINK_ROOT) + return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); + else if (link == ScriptBaseClass.LINK_THIS) + return GetPrimMediaParams(m_host, face, rules); + else + { + SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); + if (null != part) + return GetPrimMediaParams(part, face, rules); + } + + return new LSL_List(); + } + + private LSL_List GetPrimMediaParams(SceneObjectPart part, int face, LSL_List rules) { + // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid + // TODO: Need to correctly handle case where a face has no media (which gives back an empty list). + // Assuming silently fail means give back an empty list. Ideally, need to check this. + if (face < 0 || face > part.GetNumberOfSides() - 1) + return new LSL_List(); + + IMoapModule module = m_ScriptEngine.World.RequestModuleInterface(); + if (null == module) + return new LSL_List(); + + MediaEntry me = module.GetMediaEntry(part, face); + + // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams + if (null == me) + return new LSL_List(); + LSL_List res = new LSL_List(); - int idx=0; - while (idx < rules.Length) + + for (int i = 0; i < rules.Length; i++) { - int code=(int)rules.GetLSLIntegerItem(idx++); - int remain=rules.Length-idx; + int code = (int)rules.GetLSLIntegerItem(i); switch (code) { - case (int)ScriptBaseClass.PRIM_MATERIAL: - res.Add(new LSL_Integer(part.Material)); + case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE: + // Not implemented + res.Add(new LSL_Integer(0)); break; - case (int)ScriptBaseClass.PRIM_PHYSICS: - if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0) - res.Add(new LSL_Integer(1)); + case ScriptBaseClass.PRIM_MEDIA_CONTROLS: + if (me.Controls == MediaControls.Standard) + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD)); else - res.Add(new LSL_Integer(0)); + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI)); break; - case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: - if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.TemporaryOnRez) != 0) - res.Add(new LSL_Integer(1)); - else - res.Add(new LSL_Integer(0)); + case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL: + res.Add(new LSL_String(me.CurrentURL)); break; - case (int)ScriptBaseClass.PRIM_PHANTOM: - if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) - res.Add(new LSL_Integer(1)); - else - res.Add(new LSL_Integer(0)); + case ScriptBaseClass.PRIM_MEDIA_HOME_URL: + res.Add(new LSL_String(me.HomeURL)); break; - case (int)ScriptBaseClass.PRIM_POSITION: - LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, - part.AbsolutePosition.Y, - part.AbsolutePosition.Z); - res.Add(v); + case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP: + res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); break; - case (int)ScriptBaseClass.PRIM_SIZE: - res.Add(new LSL_Vector(part.Scale.X, - part.Scale.Y, - part.Scale.Z)); + case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY: + res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); break; - case (int)ScriptBaseClass.PRIM_ROTATION: - res.Add(GetPartRot(part)); + case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE: + res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); break; - case (int)ScriptBaseClass.PRIM_TYPE: - // implementing box - PrimitiveBaseShape Shape = part.Shape; - int primType = (int)part.GetPrimType(); - res.Add(new LSL_Integer(primType)); - double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX - double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY. - switch (primType) - { - case ScriptBaseClass.PRIM_TYPE_BOX: - case ScriptBaseClass.PRIM_TYPE_CYLINDER: - case ScriptBaseClass.PRIM_TYPE_PRISM: - res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. - res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); - res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); - res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); - res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); - res.Add(new LSL_Vector(topshearx, topsheary, 0)); - break; - - case ScriptBaseClass.PRIM_TYPE_SPHERE: - res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. - res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); - res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); - res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); - res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); - break; + case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM: + res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); + break; - case ScriptBaseClass.PRIM_TYPE_SCULPT: - res.Add(Shape.SculptTexture.ToString()); - res.Add(new LSL_Integer(Shape.SculptType)); - break; - - case ScriptBaseClass.PRIM_TYPE_RING: - case ScriptBaseClass.PRIM_TYPE_TUBE: - case ScriptBaseClass.PRIM_TYPE_TORUS: - // holeshape - res.Add(new LSL_Integer(Shape.ProfileCurve) & 0xf0); // Isolate hole shape nibble. - - // cut - res.Add(new LSL_Vector(Shape.PathBegin / 50000.0, 1 - Shape.PathEnd / 50000.0, 0)); - - // hollow - res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0)); - - // twist - res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0)); - - // vector holesize - res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0)); - - // vector topshear - res.Add(new LSL_Vector(topshearx, topsheary, 0)); - - // vector profilecut - res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0)); - - // vector tapera - res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0)); - - // float revolutions - res.Add(new LSL_Float(Math.Round(Shape.PathRevolutions * 0.015d, 2, MidpointRounding.AwayFromZero)) + 1.0d); - // Slightly inaccurate, because an unsigned byte is being used to represent - // the entire range of floating-point values from 1.0 through 4.0 (which is how - // SL does it). - // - // Using these formulas to store and retrieve PathRevolutions, it is not - // possible to use all values between 1.00 and 4.00. For instance, you can't - // represent 1.10. You can represent 1.09 and 1.11, but not 1.10. So, if you - // use llSetPrimitiveParams to set revolutions to 1.10 and then retreive them - // with llGetPrimitiveParams, you'll retrieve 1.09. You can also see a similar - // behavior in the viewer as you cannot set 1.10. The viewer jumps to 1.11. - // In SL, llSetPrimitveParams and llGetPrimitiveParams can set and get a value - // such as 1.10. So, SL must store and retreive the actual user input rather - // than only storing the encoded value. - - // float radiusoffset - res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); - - // float skew - res.Add(new LSL_Float(Shape.PathSkew / 100.0)); - break; - } - break; - - case (int)ScriptBaseClass.PRIM_TEXTURE: - if (remain < 1) - return res; - - int face = (int)rules.GetLSLIntegerItem(idx++); - Primitive.TextureEntry tex = part.Shape.Textures; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0 ; face < GetNumberOfSides(part); face++) - { - Primitive.TextureEntryFace texface = tex.GetFace((uint)face); - - res.Add(new LSL_String(texface.TextureID.ToString())); - res.Add(new LSL_Vector(texface.RepeatU, - texface.RepeatV, - 0)); - res.Add(new LSL_Vector(texface.OffsetU, - texface.OffsetV, - 0)); - res.Add(new LSL_Float(texface.Rotation)); - } - } - else - { - if (face >= 0 && face < GetNumberOfSides(part)) - { - Primitive.TextureEntryFace texface = tex.GetFace((uint)face); - - res.Add(new LSL_String(texface.TextureID.ToString())); - res.Add(new LSL_Vector(texface.RepeatU, - texface.RepeatV, - 0)); - res.Add(new LSL_Vector(texface.OffsetU, - texface.OffsetV, - 0)); - res.Add(new LSL_Float(texface.Rotation)); - } - } - break; - - case (int)ScriptBaseClass.PRIM_COLOR: - if (remain < 1) - return res; - - face=(int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - Color4 texcolor; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0 ; face < GetNumberOfSides(part); face++) - { - texcolor = tex.GetFace((uint)face).RGBA; - res.Add(new LSL_Vector(texcolor.R, - texcolor.G, - texcolor.B)); - res.Add(new LSL_Float(texcolor.A)); - } - } - else - { - texcolor = tex.GetFace((uint)face).RGBA; - res.Add(new LSL_Vector(texcolor.R, - texcolor.G, - texcolor.B)); - res.Add(new LSL_Float(texcolor.A)); - } - break; - - case (int)ScriptBaseClass.PRIM_BUMP_SHINY: - if (remain < 1) - return res; - face = (int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - int shiny; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0; face < GetNumberOfSides(part); face++) - { - Shininess shinyness = tex.GetFace((uint)face).Shiny; - if (shinyness == Shininess.High) - { - shiny = ScriptBaseClass.PRIM_SHINY_HIGH; - } - else if (shinyness == Shininess.Medium) - { - shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; - } - else if (shinyness == Shininess.Low) - { - shiny = ScriptBaseClass.PRIM_SHINY_LOW; - } - else - { - shiny = ScriptBaseClass.PRIM_SHINY_NONE; - } - res.Add(new LSL_Integer(shiny)); - res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); - } - } - else - { - Shininess shinyness = tex.GetFace((uint)face).Shiny; - if (shinyness == Shininess.High) - { - shiny = ScriptBaseClass.PRIM_SHINY_HIGH; - } - else if (shinyness == Shininess.Medium) - { - shiny = ScriptBaseClass.PRIM_SHINY_MEDIUM; - } - else if (shinyness == Shininess.Low) - { - shiny = ScriptBaseClass.PRIM_SHINY_LOW; - } - else - { - shiny = ScriptBaseClass.PRIM_SHINY_NONE; - } - res.Add(new LSL_Integer(shiny)); - res.Add(new LSL_Integer((int)tex.GetFace((uint)face).Bump)); - } - break; - - case (int)ScriptBaseClass.PRIM_FULLBRIGHT: - if (remain < 1) - return res; - face = (int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - int fullbright; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0; face < GetNumberOfSides(part); face++) - { - if (tex.GetFace((uint)face).Fullbright == true) - { - fullbright = ScriptBaseClass.TRUE; - } - else - { - fullbright = ScriptBaseClass.FALSE; - } - res.Add(new LSL_Integer(fullbright)); - } - } - else - { - if (tex.GetFace((uint)face).Fullbright == true) - { - fullbright = ScriptBaseClass.TRUE; - } - else - { - fullbright = ScriptBaseClass.FALSE; - } - res.Add(new LSL_Integer(fullbright)); - } - break; - - case (int)ScriptBaseClass.PRIM_FLEXIBLE: - PrimitiveBaseShape shape = part.Shape; - - if (shape.FlexiEntry) - res.Add(new LSL_Integer(1)); // active - else - res.Add(new LSL_Integer(0)); - res.Add(new LSL_Integer(shape.FlexiSoftness));// softness - res.Add(new LSL_Float(shape.FlexiGravity)); // gravity - res.Add(new LSL_Float(shape.FlexiDrag)); // friction - res.Add(new LSL_Float(shape.FlexiWind)); // wind - res.Add(new LSL_Float(shape.FlexiTension)); // tension - res.Add(new LSL_Vector(shape.FlexiForceX, // force - shape.FlexiForceY, - shape.FlexiForceZ)); - break; - - case (int)ScriptBaseClass.PRIM_TEXGEN: - // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) - if (remain < 1) - return res; - face = (int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0; face < GetNumberOfSides(part); face++) - { - if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) - { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); - } - else - { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); - } - } - } - else - { - if (tex.GetFace((uint)face).TexMapType == MappingType.Planar) - { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_PLANAR)); - } - else - { - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); - } - } - break; - - case (int)ScriptBaseClass.PRIM_POINT_LIGHT: - shape = part.Shape; - - if (shape.LightEntry) - res.Add(new LSL_Integer(1)); // active - else - res.Add(new LSL_Integer(0)); - res.Add(new LSL_Vector(shape.LightColorR, // color - shape.LightColorG, - shape.LightColorB)); - res.Add(new LSL_Float(shape.LightIntensity)); // intensity - res.Add(new LSL_Float(shape.LightRadius)); // radius - res.Add(new LSL_Float(shape.LightFalloff)); // falloff - break; - - case (int)ScriptBaseClass.PRIM_GLOW: - if (remain < 1) - return res; - face = (int)rules.GetLSLIntegerItem(idx++); - - tex = part.Shape.Textures; - float primglow; - if (face == ScriptBaseClass.ALL_SIDES) - { - for (face = 0; face < GetNumberOfSides(part); face++) - { - primglow = tex.GetFace((uint)face).Glow; - res.Add(new LSL_Float(primglow)); - } - } - else - { - primglow = tex.GetFace((uint)face).Glow; - res.Add(new LSL_Float(primglow)); - } - break; - - case (int)ScriptBaseClass.PRIM_TEXT: - Color4 textColor = part.GetTextColor(); - res.Add(new LSL_String(part.Text)); - res.Add(new LSL_Vector(textColor.R, - textColor.G, - textColor.B)); - res.Add(new LSL_Float(textColor.A)); - break; - - case (int)ScriptBaseClass.PRIM_NAME: - res.Add(new LSL_String(part.Name)); - break; - - case (int)ScriptBaseClass.PRIM_DESC: - res.Add(new LSL_String(part.Description)); - break; - - case (int)ScriptBaseClass.PRIM_ROT_LOCAL: - res.Add(new LSL_Rotation(part.RotationOffset.X, part.RotationOffset.Y, part.RotationOffset.Z, part.RotationOffset.W)); - break; - - case (int)ScriptBaseClass.PRIM_POS_LOCAL: - res.Add(new LSL_Vector(GetPartLocalPos(part))); - break; - case (int)ScriptBaseClass.PRIM_LINK_TARGET: - if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. - return res; - LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); - LSL_List new_rules = rules.GetSublist(idx, -1); - LSL_List tres = llGetLinkPrimitiveParams((int)new_linknumber, new_rules); - res += tres; - return res; - case (int)ScriptBaseClass.PRIM_SLICE: - PrimType prim_type = part.GetPrimType(); - bool useProfileBeginEnd = (prim_type == PrimType.SPHERE || prim_type == PrimType.TORUS || prim_type == PrimType.TUBE || prim_type == PrimType.RING); - res.Add(new LSL_Vector( - (useProfileBeginEnd ? part.Shape.ProfileBegin : part.Shape.PathBegin) / 50000.0, - 1 - (useProfileBeginEnd ? part.Shape.ProfileEnd : part.Shape.PathEnd) / 50000.0, - 0 - )); - break; - } - } - return res; - } - - public LSL_List llGetPrimMediaParams(int face, LSL_List rules) - { - m_host.AddScriptLPS(1); - ScriptSleep(1000); - return GetPrimMediaParams(m_host, face, rules); - } - - public LSL_List llGetLinkMedia(LSL_Integer link, LSL_Integer face, LSL_List rules) - { - m_host.AddScriptLPS(1); - ScriptSleep(1000); - if (link == ScriptBaseClass.LINK_ROOT) - return GetPrimMediaParams(m_host.ParentGroup.RootPart, face, rules); - else if (link == ScriptBaseClass.LINK_THIS) - return GetPrimMediaParams(m_host, face, rules); - else - { - SceneObjectPart part = m_host.ParentGroup.GetLinkNumPart(link); - if (null != part) - return GetPrimMediaParams(part, face, rules); - } - - return new LSL_List(); - } - - private LSL_List GetPrimMediaParams(SceneObjectPart part, int face, LSL_List rules) - { - // LSL Spec http://wiki.secondlife.com/wiki/LlGetPrimMediaParams says to fail silently if face is invalid - // TODO: Need to correctly handle case where a face has no media (which gives back an empty list). - // Assuming silently fail means give back an empty list. Ideally, need to check this. - if (face < 0 || face > part.GetNumberOfSides() - 1) - return new LSL_List(); - - IMoapModule module = m_ScriptEngine.World.RequestModuleInterface(); - if (null == module) - return new LSL_List(); - - MediaEntry me = module.GetMediaEntry(part, face); - - // As per http://wiki.secondlife.com/wiki/LlGetPrimMediaParams - if (null == me) - return new LSL_List(); - - LSL_List res = new LSL_List(); - - for (int i = 0; i < rules.Length; i++) - { - int code = (int)rules.GetLSLIntegerItem(i); - - switch (code) - { - case ScriptBaseClass.PRIM_MEDIA_ALT_IMAGE_ENABLE: - // Not implemented - res.Add(new LSL_Integer(0)); - break; - - case ScriptBaseClass.PRIM_MEDIA_CONTROLS: - if (me.Controls == MediaControls.Standard) - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_STANDARD)); - else - res.Add(new LSL_Integer(ScriptBaseClass.PRIM_MEDIA_CONTROLS_MINI)); - break; - - case ScriptBaseClass.PRIM_MEDIA_CURRENT_URL: - res.Add(new LSL_String(me.CurrentURL)); - break; - - case ScriptBaseClass.PRIM_MEDIA_HOME_URL: - res.Add(new LSL_String(me.HomeURL)); - break; - - case ScriptBaseClass.PRIM_MEDIA_AUTO_LOOP: - res.Add(me.AutoLoop ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); - break; - - case ScriptBaseClass.PRIM_MEDIA_AUTO_PLAY: - res.Add(me.AutoPlay ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); - break; - - case ScriptBaseClass.PRIM_MEDIA_AUTO_SCALE: - res.Add(me.AutoScale ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); - break; - - case ScriptBaseClass.PRIM_MEDIA_AUTO_ZOOM: - res.Add(me.AutoZoom ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); - break; - - case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT: - res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); - break; + case ScriptBaseClass.PRIM_MEDIA_FIRST_CLICK_INTERACT: + res.Add(me.InteractOnFirstClick ? ScriptBaseClass.TRUE : ScriptBaseClass.FALSE); + break; case ScriptBaseClass.PRIM_MEDIA_WIDTH_PIXELS: res.Add(new LSL_Integer(me.Width)); @@ -13015,142 +12754,403 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api LSL_Vector sitOffset = (llRot2Up(new LSL_Rotation(av.Rotation.X, av.Rotation.Y, av.Rotation.Z, av.Rotation.W)) * av.Appearance.AvatarHeight * 0.02638f); - v = v + 2 * sitOffset; + v = v + 2 * sitOffset; + + av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z); + av.SendAvatarDataToAllAgents(); + + } + break; + + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + case (int)ScriptBaseClass.PRIM_ROTATION: + { + if (remain < 1) + return null; + + LSL_Rotation r; + r = rules.GetQuaternionItem(idx++); + + SceneObjectPart part = World.GetSceneObjectPart(av.ParentID); + if (part == null) + break; + + LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION; + LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR; + + if (part.LinkNum > 1) + localRot = GetPartLocalRot(part); + + r = r * llGetRootRotation() / localRot; + av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); + av.SendAvatarDataToAllAgents(); + } + break; + + // parse rest doing nothing but number of parameters error check + case (int)ScriptBaseClass.PRIM_SIZE: + case (int)ScriptBaseClass.PRIM_MATERIAL: + case (int)ScriptBaseClass.PRIM_PHANTOM: + case (int)ScriptBaseClass.PRIM_PHYSICS: + case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE: + case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: + case (int)ScriptBaseClass.PRIM_NAME: + case (int)ScriptBaseClass.PRIM_DESC: + if (remain < 1) + return null; + idx++; + break; + + case (int)ScriptBaseClass.PRIM_GLOW: + case (int)ScriptBaseClass.PRIM_FULLBRIGHT: + case (int)ScriptBaseClass.PRIM_TEXGEN: + if (remain < 2) + return null; + idx += 2; + break; + + case (int)ScriptBaseClass.PRIM_TYPE: + if (remain < 3) + return null; + code = (int)rules.GetLSLIntegerItem(idx++); + remain = rules.Length - idx; + switch (code) + { + case (int)ScriptBaseClass.PRIM_TYPE_BOX: + case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: + case (int)ScriptBaseClass.PRIM_TYPE_PRISM: + if (remain < 6) + return null; + idx += 6; + break; + + case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: + if (remain < 5) + return null; + idx += 5; + break; + + case (int)ScriptBaseClass.PRIM_TYPE_TORUS: + case (int)ScriptBaseClass.PRIM_TYPE_TUBE: + case (int)ScriptBaseClass.PRIM_TYPE_RING: + if (remain < 11) + return null; + idx += 11; + break; + + case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: + if (remain < 2) + return null; + idx += 2; + break; + } + break; + + case (int)ScriptBaseClass.PRIM_COLOR: + case (int)ScriptBaseClass.PRIM_TEXT: + case (int)ScriptBaseClass.PRIM_BUMP_SHINY: + case (int)ScriptBaseClass.PRIM_OMEGA: + if (remain < 3) + return null; + idx += 3; + break; + + case (int)ScriptBaseClass.PRIM_TEXTURE: + case (int)ScriptBaseClass.PRIM_POINT_LIGHT: + case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL: + if (remain < 5) + return null; + idx += 5; + break; + + case (int)ScriptBaseClass.PRIM_FLEXIBLE: + if (remain < 7) + return null; + + idx += 7; + break; + + case (int)ScriptBaseClass.PRIM_LINK_TARGET: + if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. + return null; + + return rules.GetSublist(idx, -1); + } + } + } + + finally + { + if (positionChanged) + { + av.OffsetPosition = finalPos; +// av.SendAvatarDataToAllAgents(); + av.SendTerseUpdateToAllClients(); + positionChanged = false; + } + } + return null; + } + + public LSL_List GetPrimParams(ScenePresence avatar, LSL_List rules) + { + // avatars case + // replies as SL wiki + + LSL_List res = new LSL_List(); +// SceneObjectPart sitPart = avatar.ParentPart; // most likelly it will be needed + SceneObjectPart sitPart = World.GetSceneObjectPart(avatar.ParentID); // maybe better do this expensive search for it in case it's gone?? + + int idx = 0; + while (idx < rules.Length) + { + int code = (int)rules.GetLSLIntegerItem(idx++); + int remain = rules.Length - idx; + + switch (code) + { + case (int)ScriptBaseClass.PRIM_MATERIAL: + res.Add(new LSL_Integer((int)SOPMaterialData.SopMaterial.Flesh)); + break; + + case (int)ScriptBaseClass.PRIM_PHYSICS: + res.Add(new LSL_Integer(0)); + break; + + case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: + res.Add(new LSL_Integer(0)); + break; + + case (int)ScriptBaseClass.PRIM_PHANTOM: + res.Add(new LSL_Integer(0)); + break; + + case (int)ScriptBaseClass.PRIM_POSITION: + + Vector3 pos = avatar.OffsetPosition; + + Vector3 sitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f *2.0f); + pos -= sitOffset; + + if( sitPart != null) + pos = sitPart.GetWorldPosition() + pos * sitPart.GetWorldRotation(); + + res.Add(new LSL_Vector(pos.X,pos.Y,pos.Z)); + break; + + case (int)ScriptBaseClass.PRIM_SIZE: + // as in llGetAgentSize above + res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight)); + break; + + case (int)ScriptBaseClass.PRIM_ROTATION: + Quaternion rot = avatar.Rotation; + if (sitPart != null) + { + rot = sitPart.GetWorldRotation() * rot; // apply sit part world rotation + } + + res.Add(new LSL_Rotation (rot.X, rot.Y, rot.Z, rot.W)); + break; + + case (int)ScriptBaseClass.PRIM_TYPE: + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TYPE_BOX)); + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_HOLE_DEFAULT)); + res.Add(new LSL_Vector(0f,1.0f,0f)); + res.Add(new LSL_Float(0.0f)); + res.Add(new LSL_Vector(0, 0, 0)); + res.Add(new LSL_Vector(1.0f,1.0f,0f)); + res.Add(new LSL_Vector(0, 0, 0)); + break; + + case (int)ScriptBaseClass.PRIM_TEXTURE: + if (remain < 1) + return res; + + int face = (int)rules.GetLSLIntegerItem(idx++); + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < 21; face++) + { + res.Add(new LSL_String("")); + res.Add(new LSL_Vector(0,0,0)); + res.Add(new LSL_Vector(0,0,0)); + res.Add(new LSL_Float(0.0)); + } + } + else + { + if (face >= 0 && face < 21) + { + res.Add(new LSL_String("")); + res.Add(new LSL_Vector(0,0,0)); + res.Add(new LSL_Vector(0,0,0)); + res.Add(new LSL_Float(0.0)); + } + } + break; + + case (int)ScriptBaseClass.PRIM_COLOR: + if (remain < 1) + return res; - av.OffsetPosition = new Vector3((float)v.x, (float)v.y, (float)v.z); - av.SendAvatarDataToAllAgents(); + face = (int)rules.GetLSLIntegerItem(idx++); + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < 21; face++) + { + res.Add(new LSL_Vector(0,0,0)); + res.Add(new LSL_Float(0)); } - break; + } + else + { + res.Add(new LSL_Vector(0,0,0)); + res.Add(new LSL_Float(0)); + } + break; - case (int)ScriptBaseClass.PRIM_ROT_LOCAL: - case (int)ScriptBaseClass.PRIM_ROTATION: + case (int)ScriptBaseClass.PRIM_BUMP_SHINY: + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); + + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < 21; face++) { - if (remain < 1) - return null; + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE)); + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE)); + } + } + else + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_SHINY_NONE)); + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_BUMP_NONE)); + } + break; - LSL_Rotation r; - r = rules.GetQuaternionItem(idx++); + case (int)ScriptBaseClass.PRIM_FULLBRIGHT: + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); - SceneObjectPart part = World.GetSceneObjectPart(av.ParentID); - if (part == null) - break; + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < 21; face++) + { + res.Add(new LSL_Integer(ScriptBaseClass.FALSE)); + } + } + else + { + res.Add(new LSL_Integer(ScriptBaseClass.FALSE)); + } + break; - LSL_Rotation localRot = ScriptBaseClass.ZERO_ROTATION; - LSL_Vector localPos = ScriptBaseClass.ZERO_VECTOR; + case (int)ScriptBaseClass.PRIM_FLEXIBLE: + res.Add(new LSL_Integer(0)); + res.Add(new LSL_Integer(0));// softness + res.Add(new LSL_Float(0.0f)); // gravity + res.Add(new LSL_Float(0.0f)); // friction + res.Add(new LSL_Float(0.0f)); // wind + res.Add(new LSL_Float(0.0f)); // tension + res.Add(new LSL_Vector(0f,0f,0f)); + break; - if (part.LinkNum > 1) - localRot = GetPartLocalRot(part); + case (int)ScriptBaseClass.PRIM_TEXGEN: + // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); - r = r * llGetRootRotation() / localRot; - av.Rotation = new Quaternion((float)r.x, (float)r.y, (float)r.z, (float)r.s); - av.SendAvatarDataToAllAgents(); + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < 21; face++) + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); } - break; + } + else + { + res.Add(new LSL_Integer(ScriptBaseClass.PRIM_TEXGEN_DEFAULT)); + } + break; - // parse rest doing nothing but number of parameters error check - case (int)ScriptBaseClass.PRIM_SIZE: - case (int)ScriptBaseClass.PRIM_MATERIAL: - case (int)ScriptBaseClass.PRIM_PHANTOM: - case (int)ScriptBaseClass.PRIM_PHYSICS: - case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE: - case (int)ScriptBaseClass.PRIM_TEMP_ON_REZ: - case (int)ScriptBaseClass.PRIM_NAME: - case (int)ScriptBaseClass.PRIM_DESC: - if (remain < 1) - return null; - idx++; - break; + case (int)ScriptBaseClass.PRIM_POINT_LIGHT: + res.Add(new LSL_Integer(0)); + res.Add(new LSL_Vector(0f,0f,0f)); + res.Add(new LSL_Float(0f)); // intensity + res.Add(new LSL_Float(0f)); // radius + res.Add(new LSL_Float(0f)); // falloff + break; - case (int)ScriptBaseClass.PRIM_GLOW: - case (int)ScriptBaseClass.PRIM_FULLBRIGHT: - case (int)ScriptBaseClass.PRIM_TEXGEN: - if (remain < 2) - return null; - idx += 2; - break; + case (int)ScriptBaseClass.PRIM_GLOW: + if (remain < 1) + return res; + face = (int)rules.GetLSLIntegerItem(idx++); - case (int)ScriptBaseClass.PRIM_TYPE: - if (remain < 3) - return null; - code = (int)rules.GetLSLIntegerItem(idx++); - remain = rules.Length - idx; - switch (code) + if (face == ScriptBaseClass.ALL_SIDES) + { + for (face = 0; face < 21; face++) { - case (int)ScriptBaseClass.PRIM_TYPE_BOX: - case (int)ScriptBaseClass.PRIM_TYPE_CYLINDER: - case (int)ScriptBaseClass.PRIM_TYPE_PRISM: - if (remain < 6) - return null; - idx += 6; - break; - - case (int)ScriptBaseClass.PRIM_TYPE_SPHERE: - if (remain < 5) - return null; - idx += 5; - break; + res.Add(new LSL_Float(0f)); + } + } + else + { + res.Add(new LSL_Float(0f)); + } + break; - case (int)ScriptBaseClass.PRIM_TYPE_TORUS: - case (int)ScriptBaseClass.PRIM_TYPE_TUBE: - case (int)ScriptBaseClass.PRIM_TYPE_RING: - if (remain < 11) - return null; - idx += 11; - break; + case (int)ScriptBaseClass.PRIM_TEXT: + res.Add(new LSL_String("")); + res.Add(new LSL_Vector(0f,0f,0f)); + res.Add(new LSL_Float(1.0f)); + break; - case (int)ScriptBaseClass.PRIM_TYPE_SCULPT: - if (remain < 2) - return null; - idx += 2; - break; - } - break; + case (int)ScriptBaseClass.PRIM_NAME: + res.Add(new LSL_String(avatar.Name)); + break; - case (int)ScriptBaseClass.PRIM_COLOR: - case (int)ScriptBaseClass.PRIM_TEXT: - case (int)ScriptBaseClass.PRIM_BUMP_SHINY: - case (int)ScriptBaseClass.PRIM_OMEGA: - if (remain < 3) - return null; - idx += 3; - break; + case (int)ScriptBaseClass.PRIM_DESC: + res.Add(new LSL_String("")); + break; - case (int)ScriptBaseClass.PRIM_TEXTURE: - case (int)ScriptBaseClass.PRIM_POINT_LIGHT: - case (int)ScriptBaseClass.PRIM_PHYSICS_MATERIAL: - if (remain < 5) - return null; - idx += 5; - break; + case (int)ScriptBaseClass.PRIM_ROT_LOCAL: + Quaternion lrot = avatar.Rotation; - case (int)ScriptBaseClass.PRIM_FLEXIBLE: - if (remain < 7) - return null; + if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart) + { + lrot = sitPart.RotationOffset * lrot; // apply sit part rotation offset + } + res.Add(new LSL_Rotation(lrot.X, lrot.Y, lrot.Z, lrot.W)); + break; - idx += 7; - break; + case (int)ScriptBaseClass.PRIM_POS_LOCAL: + Vector3 lpos = avatar.OffsetPosition; // pos relative to sit part + Vector3 lsitOffset = (Zrot(avatar.Rotation)) * (avatar.Appearance.AvatarHeight * 0.02638f * 2.0f); + lpos -= lsitOffset; - case (int)ScriptBaseClass.PRIM_LINK_TARGET: - if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. - return null; + if (sitPart != null && sitPart != sitPart.ParentGroup.RootPart) + { + lpos = sitPart.OffsetPosition + (lpos * sitPart.RotationOffset); // make it relative to root prim + } + res.Add(new LSL_Vector(lpos.X,lpos.Y,lpos.Z)); + break; - return rules.GetSublist(idx, -1); - } - } - } + case (int)ScriptBaseClass.PRIM_LINK_TARGET: + if (remain < 3) // setting to 3 on the basis that parsing any usage of PRIM_LINK_TARGET that has nothing following it is pointless. + return res; + LSL_Integer new_linknumber = rules.GetLSLIntegerItem(idx++); + LSL_List new_rules = rules.GetSublist(idx, -1); - finally - { - if (positionChanged) - { - av.OffsetPosition = finalPos; -// av.SendAvatarDataToAllAgents(); - av.SendTerseUpdateToAllClients(); - positionChanged = false; + res += llGetLinkPrimitiveParams((int)new_linknumber, new_rules); + return res; } } - return null; + return res; } } } -- cgit v1.1