From 1130c3067cb1d54c5a96ace2bc3f2519cf3916c1 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Mon, 5 May 2008 00:03:30 +0000 Subject: * A bit of spice from here, a pinch of salt from there, some brains that attracts zombies.. a recipe for llRezObject * Original patch by YZh Thanks YZH!!!! * object_rez event patch by Melanie, Thanks Melanie!!! * Some fixups, some missing things(velocity,rotation) * script delay * Recoil * Standard error messages * Standard silent failures * Easter egg management --- .../Region/Environment/Scenes/Scene.Inventory.cs | 64 +++++++++++++++++++++- .../Region/Environment/Scenes/SceneObjectGroup.cs | 12 ++++ .../Common/BuiltIn_Commands_BaseClass.cs | 4 +- .../ScriptEngine/Common/LSL_BuiltIn_Commands.cs | 56 ++++++++++++++++++- .../Common/LSL_BuiltIn_Commands_Interface.cs | 2 +- 5 files changed, 132 insertions(+), 6 deletions(-) (limited to 'OpenSim') diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs index 1c7e98e..ee52a66 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs @@ -1353,7 +1353,69 @@ namespace OpenSim.Region.Environment.Scenes } return null; } - + + public virtual SceneObjectGroup RezObject(TaskInventoryItem item, LLVector3 pos, LLQuaternion rot, LLVector3 vel, int param) + { + // Rez object + if (item != null) + { + LLUUID ownerID = item.OwnerID; + + if (!PermissionsMngr.CanRezObject(ownerID, pos)) + { + return null; + } + + AssetBase rezAsset = AssetCache.GetAsset(item.AssetID, false); + + if (rezAsset != null) + { + string xmlData = Helpers.FieldToUTF8String(rezAsset.Data); + SceneObjectGroup group = new SceneObjectGroup(this, m_regionHandle, xmlData); + group.ResetIDs(); + AddEntity(group); + + // we set it's position in world. + group.AbsolutePosition = pos; + + SceneObjectPart rootPart = group.GetChildPart(group.UUID); + + // Since renaming the item in the inventory does not affect the name stored + // in the serialization, transfer the correct name from the inventory to the + // object itself before we rez. + rootPart.Name = item.Name; + rootPart.Description = item.Description; + + List partList = new List(group.Children.Values); + foreach (SceneObjectPart part in partList) + { + if (part.OwnerID != item.OwnerID) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.OwnerID; + part.EveryoneMask = item.EveryoneMask; + part.BaseMask = item.BaseMask; + part.OwnerMask = item.OwnerMask; + part.NextOwnerMask = item.NextOwnerMask; + part.ChangeInventoryOwner(item.OwnerID); + } + } + rootPart.TrimPermissions(); + if (group.RootPart.Shape.PCode == (byte)PCode.Prim) + { + group.ClearPartAttachmentData(); + } + group.UpdateGroupRotation(rot); + group.ApplyPhysics(m_physicalPrim); + group.Velocity = vel; + group.StartScripts(); + rootPart.ScheduleFullUpdate(); + return rootPart.ParentGroup; + } + + } + return null; + } } } diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs index 5d39790..9ed5990 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs @@ -2526,5 +2526,17 @@ namespace OpenSim.Region.Environment.Scenes } } } + public float GetMass() + { + float retmass = 0f; + lock (m_parts) + { + foreach (SceneObjectPart part in m_parts.Values) + { + retmass += part.GetMass(); + } + } + return retmass; + } } } diff --git a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs index f7cd697..49ddd3f 100644 --- a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs +++ b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs @@ -697,9 +697,9 @@ namespace OpenSim.Region.ScriptEngine.Common m_LSL_Functions.llMakeFire(); } - public void llRezObject(string inventory, vector pos, rotation rot, int param) + public void llRezObject(string inventory, vector pos, vector vel, rotation rot, int param) { - m_LSL_Functions.llRezObject(inventory, pos, rot, param); + m_LSL_Functions.llRezObject(inventory, pos, vel, rot, param); } public void llLookAt(vector target, double strength, double damping) diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs index f0108f8..ca94dd7 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs @@ -1839,10 +1839,62 @@ namespace OpenSim.Region.ScriptEngine.Common NotImplemented("llMakeFire"); } - public void llRezObject(string inventory, LSL_Types.Vector3 pos, LSL_Types.Quaternion rot, int param) + public void llRezObject(string inventory, LSL_Types.Vector3 pos, LSL_Types.Vector3 vel, LSL_Types.Quaternion rot, int param) { m_host.AddScriptLPS(1); - NotImplemented("llRezObject"); + //NotImplemented("llRezObject"); + bool found = false; + + // Instead of using return;, I'm using continue; because in our TaskInventory implementation + // it's possible to have two items with the same task inventory name. + // this is an easter egg of sorts. + + foreach (KeyValuePair inv in m_host.TaskInventory) + { + if (inv.Value.Name == inventory) + { + // make sure we're an object. + if (inv.Value.InvType != (int)InventoryType.Object) + { + llSay(0, "Unable to create requested object. Object is missing from database."); + continue; + } + + LLVector3 llpos = new LLVector3((float)pos.x, (float)pos.y, (float)pos.z); + + // test if we're further away then 10m + if (Util.GetDistanceTo(llpos, m_host.AbsolutePosition) > 10) + return; // wiki says, if it's further away then 10m, silently fail. + + LLVector3 llvel = new LLVector3((float)vel.x, (float)vel.y, (float)vel.z); + + // need the magnitude later + float velmag = (float)Util.GetMagnitude(llvel); + + SceneObjectGroup new_group = World.RezObject(inv.Value, llpos, new LLQuaternion((float)rot.x, (float)rot.y, (float)rot.z, (float)rot.s), llvel, param); + + // If either of these are null, then there was an unknown error. + if (new_group == null) + continue; + if (new_group.RootPart == null) + continue; + + // objects rezzed with this method are die_at_edge by default. + new_group.RootPart.SetDieAtEdge(true); + + m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(m_localID, m_itemID, "object_rez", EventQueueManager.llDetectNull, new Object[] { new LSL_Types.LSLString(new_group.RootPart.UUID.ToString()) }); + float groupmass = new_group.GetMass(); + + //Recoil. + llApplyImpulse(new LSL_Types.Vector3(llvel.X * groupmass, llvel.Y * groupmass, llvel.Z * groupmass), 0); + found = true; + //script delay + System.Threading.Thread.Sleep((int)((groupmass * velmag) / 10)); + break; + } + } + if (!found) + llSay(0, "Could not find object " + inventory); } public void llLookAt(LSL_Types.Vector3 target, double strength, double damping) diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs index 6742ed5..115e4e8 100644 --- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs +++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands_Interface.cs @@ -190,7 +190,7 @@ namespace OpenSim.Region.ScriptEngine.Common //wiki: (deprecated) void llMakeFire(); //wiki: llRezObject(string inventory, vector pos, vector rel, rotation rot, integer param) - void llRezObject(string inventory, LSL_Types.Vector3 pos, LSL_Types.Quaternion rot, int param); + void llRezObject(string inventory, LSL_Types.Vector3 pos, LSL_Types.Vector3 vel, LSL_Types.Quaternion rot, int param); //wiki: llLookAt(vector target, double strength, double damping) void llLookAt(LSL_Types.Vector3 target, double strength, double damping); //wiki: llStopLookAt() -- cgit v1.1