public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) { LSL_List res = new LSL_List(); 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(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: LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); // For some reason, the part.AbsolutePosition.* values do not change if the // linkset is rotated; they always reflect the child prim's world position // as though the linkset is unrotated. This is incompatible behavior with SL's // implementation, so will break scripts imported from there (not to mention it // makes it more difficult to determine a child prim's actual inworld position). if (part.ParentID != 0) v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition(); res.Add(v); break; case (int)ScriptBaseClass.PRIM_SIZE: res.Add(new LSL_Vector(part.Scale.X, part.Scale.Y, part.Scale.Z)); break; case (int)ScriptBaseClass.PRIM_ROTATION: res.Add(GetPartRot(part)); 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_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; if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); // Convert Shininess to PRIM_SHINY_* res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); // PRIM_BUMP_* res.Add(new LSL_Integer((int)texface.Bump)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); // Convert Shininess to PRIM_SHINY_* res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); // PRIM_BUMP_* res.Add(new LSL_Integer((int)texface.Bump)); } } break; case (int)ScriptBaseClass.PRIM_FULLBRIGHT: 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++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); } } 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: 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++) { MappingType texgen = tex.GetFace((uint)face).TexMapType; // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. res.Add(new LSL_Integer((uint)texgen >> 1)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { MappingType texgen = tex.GetFace((uint)face).TexMapType; res.Add(new LSL_Integer((uint)texgen >> 1)); } } 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; if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Float(texface.Glow)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Float(texface.Glow)); } } 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; } } return res; }
/// <summary> /// Copy a task (prim) inventory item to another task (prim) /// </summary> /// <param name="destId"></param> /// <param name="part"></param> /// <param name="itemId"></param> public void MoveTaskInventoryItem(UUID destId, SceneObjectPart part, UUID itemId) { TaskInventoryItem srcTaskItem = part.Inventory.GetInventoryItem(itemId); if (srcTaskItem == null) { m_log.ErrorFormat( "[PRIM INVENTORY]: Tried to retrieve item ID {0} from prim {1}, {2} for moving" + " but the item does not exist in this inventory", itemId, part.Name, part.UUID); return; } SceneObjectPart destPart = GetSceneObjectPart(destId); if (destPart == null) { m_log.ErrorFormat( "[PRIM INVENTORY]: " + "Could not find prim for ID {0}", destId); return; } // Can't transfer this // if ((part.OwnerID != destPart.OwnerID) && ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)) return; if (part.OwnerID != destPart.OwnerID && (part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0) { // object cannot copy items to an object owned by a different owner // unless llAllowInventoryDrop has been called return; } // must have both move and modify permission to put an item in an object if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0) { return; } TaskInventoryItem destTaskItem = new TaskInventoryItem(); destTaskItem.ItemID = UUID.Random(); destTaskItem.CreatorID = srcTaskItem.CreatorID; destTaskItem.AssetID = srcTaskItem.AssetID; destTaskItem.GroupID = destPart.GroupID; destTaskItem.OwnerID = destPart.OwnerID; destTaskItem.ParentID = destPart.UUID; destTaskItem.ParentPartID = destPart.UUID; destTaskItem.BasePermissions = srcTaskItem.BasePermissions; destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions; destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions; destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions; destTaskItem.NextPermissions = srcTaskItem.NextPermissions; destTaskItem.Flags = srcTaskItem.Flags; destTaskItem.SalePrice = srcTaskItem.SalePrice; destTaskItem.SaleType = srcTaskItem.SaleType; if (destPart.OwnerID != part.OwnerID) { if (Permissions.PropagatePermissions()) { destTaskItem.CurrentPermissions = srcTaskItem.CurrentPermissions & (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.GroupPermissions = srcTaskItem.GroupPermissions & (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.EveryonePermissions = srcTaskItem.EveryonePermissions & (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.BasePermissions = srcTaskItem.BasePermissions & (srcTaskItem.NextPermissions | (uint)PermissionMask.Move); destTaskItem.CurrentPermissions |= 16; // Slam! } } destTaskItem.Description = srcTaskItem.Description; destTaskItem.Name = srcTaskItem.Name; destTaskItem.InvType = srcTaskItem.InvType; destTaskItem.Type = srcTaskItem.Type; destPart.Inventory.AddInventoryItem(destTaskItem, part.OwnerID != destPart.OwnerID); if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Copy) == 0) part.Inventory.RemoveInventoryItem(itemId); ScenePresence avatar; if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar)) { destPart.GetProperties(avatar.ControllingClient); } }
public uint GenerateClientFlags(UUID user, SceneObjectPart task) { // Here's the way this works, // ObjectFlags and Permission flags are two different enumerations // ObjectFlags, however, tells the client to change what it will allow the user to do. // So, that means that all of the permissions type ObjectFlags are /temporary/ and only // supposed to be set when customizing the objectflags for the client. // These temporary objectflags get computed and added in this function based on the // Permission mask that's appropriate! // Outside of this method, they should never be added to objectflags! // -teravus // this shouldn't ever happen.. return no permissions/objectflags. if (task == null) return (uint)0; uint objflags = task.GetEffectiveObjectFlags(); UUID objectOwner = task.OwnerID; // Remove any of the objectFlags that are temporary. These will get added back if appropriate // in the next bit of code // libomv will moan about PrimFlags.ObjectYouOfficer being // deprecated #pragma warning disable 0612 objflags &= (uint) ~(PrimFlags.ObjectCopy | // Tells client you can copy the object PrimFlags.ObjectModify | // tells client you can modify the object PrimFlags.ObjectMove | // tells client that you can move the object (only, no mod) PrimFlags.ObjectTransfer | // tells the client that you can /take/ the object if you don't own it PrimFlags.ObjectYouOwner | // Tells client that you're the owner of the object PrimFlags.ObjectAnyOwner | // Tells client that someone owns the object PrimFlags.ObjectOwnerModify | // Tells client that you're the owner of the object PrimFlags.ObjectYouOfficer // Tells client that you've got group object editing permission. Used when ObjectGroupOwned is set ); #pragma warning restore 0612 // Creating the three ObjectFlags options for this method to choose from. // Customize the OwnerMask uint objectOwnerMask = ApplyObjectModifyMasks(task.OwnerMask, objflags); objectOwnerMask |= (uint)PrimFlags.ObjectYouOwner | (uint)PrimFlags.ObjectAnyOwner | (uint)PrimFlags.ObjectOwnerModify; // Customize the GroupMask uint objectGroupMask = ApplyObjectModifyMasks(task.GroupMask, objflags); // Customize the EveryoneMask uint objectEveryoneMask = ApplyObjectModifyMasks(task.EveryoneMask, objflags); if (objectOwner != UUID.Zero) objectEveryoneMask |= (uint)PrimFlags.ObjectAnyOwner; if (m_bypassPermissions) return objectOwnerMask; // Object owners should be able to edit their own content if (user == objectOwner) return objectOwnerMask; if (IsFriendWithPerms(user, objectOwner)) return objectOwnerMask; // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) return objectOwnerMask; // Admin should be able to edit anything in the sim (including admin objects) if (IsAdministrator(user)) return objectOwnerMask; // Users should be able to edit what is over their land. Vector3 taskPos = task.AbsolutePosition; ILandObject parcel = m_scene.LandChannel.GetLandObject(taskPos.X, taskPos.Y); if (parcel != null && parcel.LandData.OwnerID == user && m_ParcelOwnerIsGod) { // Admin objects should not be editable by the above if (!IsAdministrator(objectOwner)) return objectOwnerMask; } // Group permissions if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) return objectGroupMask | objectEveryoneMask; return objectEveryoneMask; }
public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) { LSL_List res = new LSL_List(); int idx = 0; while (idx < rules.Length) { int code = (int)rules.GetLSLIntegerItem(idx++); int remain = rules.Length - idx; Primitive.TextureEntry tex = part.Shape.Textures; int face = 0; if (idx < rules.Length) face = (int)rules.GetLSLIntegerItem(idx++); Primitive.TextureEntryFace texFace = tex.GetFace((uint)face); if (code == (int)ScriptBaseClass.PRIM_NAME) { res.Add(new LSL_Integer(part.Name)); } if (code == (int)ScriptBaseClass.PRIM_DESC) { res.Add(new LSL_Integer(part.Description)); } if (code == (int)ScriptBaseClass.PRIM_MATERIAL) { res.Add(new LSL_Integer(part.Material)); } if (code == (int)ScriptBaseClass.PRIM_PHYSICS) { if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Physics) != 0) res.Add(new LSL_Integer(1)); else res.Add(new LSL_Integer(0)); } if (code == (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)); } if (code == (int)ScriptBaseClass.PRIM_PHANTOM) { if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) res.Add(new LSL_Integer(1)); else res.Add(new LSL_Integer(0)); } if (code == (int)ScriptBaseClass.PRIM_POSITION) { Vector3 tmp = part.AbsolutePosition; LSL_Vector v = new LSL_Vector(tmp.X, tmp.Y, tmp.Z); // For some reason, the part.AbsolutePosition.* values do not change if the // linkset is rotated; they always reflect the child prim's world position // as though the linkset is unrotated. This is incompatible behavior with SL's // implementation, so will break scripts imported from there (not to mention it // makes it more difficult to determine a child prim's actual inworld position). if (part.ParentID != 0) { LSL_Rotation rtmp = llGetRootRotation(); LSL_Vector rpos = llGetRootPosition(); v = ((v - rpos) * rtmp) + rpos; } res.Add(v); } if (code == (int)ScriptBaseClass.PRIM_SIZE) { Vector3 tmp = part.Scale; res.Add(new LSL_Vector(tmp.X, tmp.Y, tmp.Z)); } if (code == (int)ScriptBaseClass.PRIM_ROTATION) { res.Add(GetPartRot(part)); } if (code == (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. if (primType == ScriptBaseClass.PRIM_TYPE_BOX || ScriptBaseClass.PRIM_TYPE_CYLINDER || ScriptBaseClass.PRIM_TYPE_PRISM) { res.Add(new LSL_Integer(Shape.ProfileCurve)); 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)); } if (primType == ScriptBaseClass.PRIM_TYPE_SPHERE) { res.Add(new LSL_Integer(Shape.ProfileCurve)); 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)); } if (primType == ScriptBaseClass.PRIM_TYPE_SCULPT) { res.Add(Shape.SculptTexture.ToString()); res.Add(new LSL_Integer(Shape.SculptType)); } if (primType == ScriptBaseClass.PRIM_TYPE_RING || ScriptBaseClass.PRIM_TYPE_TUBE || ScriptBaseClass.PRIM_TYPE_TORUS) { // holeshape res.Add(new LSL_Integer(Shape.ProfileCurve)); // 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((Shape.PathRevolutions * 0.015) + 1.0)); // 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). // float radiusoffset res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0)); // float skew res.Add(new LSL_Float(Shape.PathSkew / 100.0)); } } if (code == (int)ScriptBaseClass.PRIM_TEXTURE) { if (remain < 1) return res; 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)); } } } if (code == (int)ScriptBaseClass.PRIM_COLOR) { if (remain < 1) return res; 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)); } } if (code == (int)ScriptBaseClass.PRIM_BUMP_SHINY) { if (remain < 1) return res; face = (int)rules.GetLSLIntegerItem(idx++); texFace = tex.GetFace((uint)face); if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); // Convert Shininess to PRIM_SHINY_* res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); // PRIM_BUMP_* res.Add(new LSL_Integer((int)texface.Bump)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); // Convert Shininess to PRIM_SHINY_* res.Add(new LSL_Integer((uint)texface.Shiny >> 6)); // PRIM_BUMP_* res.Add(new LSL_Integer((int)texface.Bump)); } } } if (code == (int)ScriptBaseClass.PRIM_FULLBRIGHT) { 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++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Integer(texface.Fullbright ? 1 : 0)); } } } if (code == (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)); } if (code == (int)ScriptBaseClass.PRIM_TEXGEN) { if (remain < 1) return res; face = (int)rules.GetLSLIntegerItem(idx++); if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { MappingType texgen = tex.GetFace((uint)face).TexMapType; // Convert MappingType to PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR etc. res.Add(new LSL_Integer((uint)texgen >> 1)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { MappingType texgen = tex.GetFace((uint)face).TexMapType; res.Add(new LSL_Integer((uint)texgen >> 1)); } } } if (code == (int)ScriptBaseClass.PRIM_POINT_LIGHT) { PrimitiveBaseShape 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 } if (code == (int)ScriptBaseClass.PRIM_GLOW) { if (remain < 1) return res; face = (int)rules.GetLSLIntegerItem(idx++); if (face == ScriptBaseClass.ALL_SIDES) { for (face = 0; face < GetNumberOfSides(part); face++) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Float(texface.Glow)); } } else { if (face >= 0 && face < GetNumberOfSides(part)) { Primitive.TextureEntryFace texface = tex.GetFace((uint)face); res.Add(new LSL_Float(texface.Glow)); } } } if (code == (int)ScriptBaseClass.PRIM_TEXT) { Color4 textColor = part.GetTextColor(); res.Add(part.Text); res.Add(new LSL_Vector(textColor.R, textColor.G, textColor.B)); res.Add(new LSL_Float(textColor.A)); } if (code == (int)ScriptBaseClass.PRIM_ROT_LOCAL) { Quaternion rtmp = part.RotationOffset; res.Add(new LSL_Rotation(rtmp.X, rtmp.Y, rtmp.Z, rtmp.W)); } } return res; }
public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) { LSL_List res = new LSL_List(); 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(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: res.Add(new LSL_Vector(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z)); break; case (int)ScriptBaseClass.PRIM_SIZE: res.Add(new LSL_Vector(part.Scale.X, part.Scale.Y, part.Scale.Z)); break; case (int)ScriptBaseClass.PRIM_ROTATION: res.Add(GetPartRot(part)); break; case (int)ScriptBaseClass.PRIM_TYPE: // implementing box PrimitiveBaseShape Shape = part.Shape; int primType = getScriptPrimType(part.Shape); res.Add(new LSL_Integer(primType)); switch (primType) { case ScriptBaseClass.PRIM_TYPE_BOX: case ScriptBaseClass.PRIM_TYPE_CYLINDER: case ScriptBaseClass.PRIM_TYPE_PRISM: res.Add(new LSL_Integer(Shape.ProfileCurve)); 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(Shape.PathShearX / 100.0, Shape.PathShearY / 100.0, 0)); break; case ScriptBaseClass.PRIM_TYPE_SPHERE: res.Add(new LSL_Integer(Shape.ProfileCurve)); 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)); // 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(Shape.PathShearX / 100.0, Shape.PathShearY / 100.0, 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(Shape.PathRevolutions / 50.0)); // needs fixing :( // 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: // TODO-------------- if (remain < 1) return res; face=(int)rules.GetLSLIntegerItem(idx++); res.Add(new LSL_Integer(0)); res.Add(new LSL_Integer(0)); break; case (int)ScriptBaseClass.PRIM_FULLBRIGHT: // TODO-------------- if (remain < 1) return res; face=(int)rules.GetLSLIntegerItem(idx++); res.Add(new LSL_Integer(0)); 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: // TODO-------------- // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) if (remain < 1) return res; face=(int)rules.GetLSLIntegerItem(idx++); res.Add(new LSL_Integer(0)); 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: // TODO-------------- if (remain < 1) return res; face=(int)rules.GetLSLIntegerItem(idx++); res.Add(new LSL_Float(0)); break; } } return res; }
private bool CheckGreyGoo(SceneObjectPart sourcePart, SceneObjectGroup newGroup) { // Allow cooldown if the object isn't in a scenic region, or isn't a temp object, or is owned by the EO bool isTemp = (sourcePart.GetEffectiveObjectFlags() & PrimFlags.TemporaryOnRez) != 0; bool allowCooldown = true; if (isTemp) // if temp-rez object if (RegionInfo.AllowRezzers == ProductRulesWho.OnlyEO) // if scenic region if (!IsEstateOwner(sourcePart.OwnerID)) // if guest user (not EO) if (!(RegionInfo.AllowPartnerRez && IsEstateOwnerPartner(sourcePart.OwnerID))) // if guest user (not EO partner) allowCooldown = false; // hard-limit generations // First adjust the current generation based on possible cooldown rules. if (allowCooldown) { uint secsSinceRezzed = (uint)Util.UnixTimeSinceEpoch() - sourcePart.TimeStamp; uint secsSinceLastRez = (uint)Util.UnixTimeSinceEpoch() - sourcePart.TimeStampLastRez; if ((secsSinceRezzed > SceneObjectPart.GENERATION_COOLDOWN) || (sourcePart.TimeStampLastRez != 0)) { uint gooPeriod = 0; // seconds since recent significant event // Check if this isn't the first time this thing has rezzed an object if (sourcePart.TimeStampLastRez != 0) gooPeriod = secsSinceLastRez; else if (secsSinceRezzed > SceneObjectPart.GENERATION_COOLDOWN) gooPeriod = secsSinceRezzed; if (gooPeriod > SceneObjectPart.GENERATION_COOLDOWN) { int cooldownFactor = (int)(gooPeriod / SceneObjectPart.GENERATION_COOLDOWN); if (sourcePart.Generation < cooldownFactor) sourcePart.ParentGroup.SetGeneration(0); else sourcePart.ParentGroup.SetGeneration(sourcePart.Generation - cooldownFactor); } } } // Now regardless of cooldown, this part is rezzing something so apply the normal generation newGroup.RootPart.Generation = sourcePart.Generation + 1; return (newGroup.RootPart.Generation < SceneObjectPart.MAX_GENERATION); }
public uint GenerateClientFlags(UUID userID, SceneObjectPart part) { // libomv will moan about PrimFlags.ObjectYouOfficer being // obsolete... #pragma warning disable 0612 const PrimFlags DEFAULT_FLAGS = PrimFlags.ObjectModify | PrimFlags.ObjectCopy | PrimFlags.ObjectMove | PrimFlags.ObjectTransfer | PrimFlags.ObjectYouOwner | PrimFlags.ObjectAnyOwner | PrimFlags.ObjectOwnerModify | PrimFlags.ObjectYouOfficer; #pragma warning restore 0612 if (part == null) return 0; uint perms = part.GetEffectiveObjectFlags() | (uint)DEFAULT_FLAGS; GenerateClientFlagsHandler handlerGenerateClientFlags = OnGenerateClientFlags; if (handlerGenerateClientFlags != null) { Delegate[] list = handlerGenerateClientFlags.GetInvocationList(); foreach (GenerateClientFlagsHandler check in list) { perms &= check(userID, part); } } return perms; }
public LSL_List GetPrimParams(SceneObjectPart part, LSL_List rules, ref LSL_List res) { 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(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: LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); res.Add(v); break; case (int)ScriptBaseClass.PRIM_SIZE: res.Add(new LSL_Vector(part.Scale)); break; case (int)ScriptBaseClass.PRIM_ROTATION: res.Add(GetPartRot(part)); break; case (int)ScriptBaseClass.PRIM_PHYSICS_SHAPE_TYPE: res.Add(new LSL_Integer((int)part.PhysicsShapeType)); 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_TYPE_SCULPT: res.Add(new LSL_String(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 new LSL_List(); 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 new LSL_List(); 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 new LSL_List(); 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 new LSL_List(); 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 new LSL_List(); 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 new LSL_List(); 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)); break; case (int)ScriptBaseClass.PRIM_POS_LOCAL: res.Add(new LSL_Vector(GetPartLocalPos(part))); break; 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; case (int)ScriptBaseClass.PRIM_LINK_TARGET: // TODO: Should be issuing a runtime script warning in this case. if (remain < 2) return new LSL_List(); return rules.GetSublist(idx, -1); } } return new LSL_List(); }
public LSL_List GetLinkPrimitiveParams(SceneObjectPart part, LSL_List rules) { LSL_List res = new LSL_List(); 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(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: LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X, part.AbsolutePosition.Y, part.AbsolutePosition.Z); // For some reason, the part.AbsolutePosition.* values do not change if the // linkset is rotated; they always reflect the child prim's world position // as though the linkset is unrotated. This is incompatible behavior with SL's // implementation, so will break scripts imported from there (not to mention it // makes it more difficult to determine a child prim's actual inworld position). if (part.ParentID != 0) v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition(); res.Add(v); break; case (int)ScriptBaseClass.PRIM_SIZE: res.Add(new LSL_Vector(part.Scale.X, part.Scale.Y, part.Scale.Z)); break; case (int)ScriptBaseClass.PRIM_ROTATION: res.Add(GetPartRot(part)); break; case (int)ScriptBaseClass.PRIM_TYPE: // implementing box PrimitiveBaseShape Shape = part.Shape; int primType = getScriptPrimType(part.Shape); 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)); 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)); 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)); // 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((Shape.PathRevolutions * 0.015) + 1.0)); // 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). // 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: // TODO-------------- if (remain < 1) return res; face=(int)rules.GetLSLIntegerItem(idx++); res.Add(new LSL_Integer(0)); res.Add(new LSL_Integer(0)); break; case (int)ScriptBaseClass.PRIM_FULLBRIGHT: // TODO-------------- if (remain < 1) return res; face=(int)rules.GetLSLIntegerItem(idx++); res.Add(new LSL_Integer(0)); 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: // TODO-------------- // (PRIM_TEXGEN_DEFAULT, PRIM_TEXGEN_PLANAR) if (remain < 1) return res; face=(int)rules.GetLSLIntegerItem(idx++); res.Add(new LSL_Integer(0)); 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: // TODO-------------- if (remain < 1) return res; face=(int)rules.GetLSLIntegerItem(idx++); res.Add(new LSL_Float(0)); break; } } return res; }