diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 5c94fba9ac..db81fea0a8 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3747,7 +3747,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (!m_scene.TryGetScenePresence(part.OwnerID, out sp)) continue; - List atts = sp.Attachments; + List atts = sp.GetAttachments(); bool found = false; foreach (SceneObjectGroup att in atts) { diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs index d9dcee79c5..3373bd5dfc 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/OfflineMessageModule.cs @@ -172,10 +172,10 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage private void RetrieveInstantMessages(IClientAPI client) { if (m_RestURL == String.Empty) - { + { return; - } - else + } + else { m_log.DebugFormat("[OFFLINE MESSAGING]: Retrieving stored messages for {0}", client.AgentId); @@ -183,64 +183,51 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage = SynchronousRestObjectRequester.MakeRequest>( "POST", m_RestURL + "/RetrieveMessages/", client.AgentId); - if (msglist != null) - { - foreach (GridInstantMessage im in msglist) + if (msglist != null) { - // client.SendInstantMessage(im); + foreach (GridInstantMessage im in msglist) + { + // client.SendInstantMessage(im); - // Send through scene event manager so all modules get a chance - // to look at this message before it gets delivered. - // - // Needed for proper state management for stored group - // invitations - // + // Send through scene event manager so all modules get a chance + // to look at this message before it gets delivered. + // + // Needed for proper state management for stored group + // invitations + // - im.offline = 1; + im.offline = 1; - Scene s = FindScene(client.AgentId); - if (s != null) - s.EventManager.TriggerIncomingInstantMessage(im); + Scene s = FindScene(client.AgentId); + if (s != null) + s.EventManager.TriggerIncomingInstantMessage(im); + } } } } private void UndeliveredMessage(GridInstantMessage im) { - if (im.dialog != (byte)InstantMessageDialog.MessageFromObject && - im.dialog != (byte)InstantMessageDialog.MessageFromAgent && - im.dialog != (byte)InstantMessageDialog.GroupNotice && - im.dialog != (byte)InstantMessageDialog.GroupInvitation && - im.dialog != (byte)InstantMessageDialog.InventoryOffered) + if ((im.offline != 0) + && (!im.fromGroup || (im.fromGroup && m_ForwardOfflineGroupMessages))) { bool success = SynchronousRestObjectRequester.MakeRequest( - "POST", m_RestURL+"/SaveMessage/", im); - return; - } + "POST", m_RestURL + "/SaveMessage/", im); - // It's not delivered. Make sure the scope id is saved - // We don't need the imSessionID here anymore, overwrite it - Scene scene = FindScene(new UUID(im.fromAgentID)); - if (scene == null) - scene = m_SceneList[0]; + if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) + { + IClientAPI client = FindClient(new UUID(im.fromAgentID)); + if (client == null) + return; - bool success = SynchronousRestObjectPoster.BeginPostObject( - "POST", m_RestURL+"/SaveMessage/?scope=" + - scene.RegionInfo.ScopeID.ToString(), im); - - if (im.dialog == (byte)InstantMessageDialog.MessageFromAgent) - { - IClientAPI client = FindClient(new UUID(im.fromAgentID)); - if (client == null) - return; - - client.SendInstantMessage(new GridInstantMessage( - null, new UUID(im.toAgentID), - "System", new UUID(im.fromAgentID), - (byte)InstantMessageDialog.MessageFromAgent, - "User is not logged in. "+ - (success ? "Message saved." : "Message not saved"), - false, new Vector3())); + client.SendInstantMessage(new GridInstantMessage( + null, new UUID(im.toAgentID), + "System", new UUID(im.fromAgentID), + (byte)InstantMessageDialog.MessageFromAgent, + "User is not logged in. " + + (success ? "Message saved." : "Message not saved"), + false, new Vector3())); + } } } } diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 654e202009..a4bb40ef93 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -788,7 +788,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) return null; - + SceneObjectPart rootPart = group.RootPart; for (int i = 0; i < objlist.Count; i++) { group = objlist[i]; @@ -835,8 +835,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group.AbsolutePosition = pos + veclist[i]; } - SceneObjectPart rootPart = group.RootPart; - group.SetGroup(remoteClient.ActiveGroupId, remoteClient); if (!attachment) @@ -861,13 +859,57 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (item != null) DoPostRezWhenFromItem(item, attachment); - if ((rootPart.OwnerID != item.Owner) || + if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0 || // Magic number (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) + { + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; + + if (m_Scene.Permissions.PropagatePermissions()) + { + foreach (SceneObjectPart part in group.Parts) + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) { - //Need to kill the for sale here - rootPart.ObjectSaleType = 0; - rootPart.SalePrice = 10; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) + part.EveryoneMask = item.EveryOnePermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) + part.NextOwnerMask = item.NextPermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) + part.GroupMask = item.GroupPermissions; + } + } + + foreach (SceneObjectPart part in group.Parts) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.Owner; + part.Inventory.ChangeInventoryOwner(item.Owner); + } + + group.ApplyNextOwnerPermissions(); + } + } + foreach (SceneObjectPart part in group.Parts) + { + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) + part.EveryoneMask = item.EveryOnePermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) + part.NextOwnerMask = item.NextPermissions; + if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) + part.GroupMask = item.GroupPermissions; + } + + if ((rootPart.OwnerID != item.Owner) || + (item.CurrentPermissions & 16) != 0 || // Magic number + (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) + { + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; + } return group; } @@ -1014,48 +1056,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess m_Scene.InventoryService.DeleteItems(item.Owner, uuids); } } - } - if ((rootPart.OwnerID != item.Owner) || - (item.CurrentPermissions & 16) != 0 || // Magic number - (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) - { - //Need to kill the for sale here - rootPart.ObjectSaleType = 0; - rootPart.SalePrice = 10; - - if (m_Scene.Permissions.PropagatePermissions()) - { - foreach (SceneObjectPart part in group.Parts) - { - if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) - { - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) - part.EveryoneMask = item.EveryOnePermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) - part.NextOwnerMask = item.NextPermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) - part.GroupMask = item.GroupPermissions; - } - } - - foreach (SceneObjectPart part in group.Parts) - { - part.LastOwnerID = part.OwnerID; - part.OwnerID = item.Owner; - part.Inventory.ChangeInventoryOwner(item.Owner); - } - - group.ApplyNextOwnerPermissions(); - } - } - foreach (SceneObjectPart part in group.Parts) - { - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) - part.EveryoneMask = item.EveryOnePermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) - part.NextOwnerMask = item.NextPermissions; - if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) - part.GroupMask = item.GroupPermissions; } } diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 89f36836c2..63dd5502c0 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -968,24 +968,25 @@ namespace OpenSim.Region.Framework.Scenes if (part != null) { group = part.ParentGroup; - } + } if (part != null && group != null) { if (!Permissions.CanEditObjectInventory(part.UUID, remoteClient.AgentId)) return; - + TaskInventoryItem item = group.GetInventoryItem(localID, itemID); if (item == null) return; - if (item.Type == 10) - { - part.RemoveScriptEvents(itemID); - EventManager.TriggerRemoveScript(localID, itemID); + if (item.Type == 10) + { + part.RemoveScriptEvents(itemID); + EventManager.TriggerRemoveScript(localID, itemID); + } + + group.RemoveInventoryItem(localID, itemID); + part.GetProperties(remoteClient); } - - group.RemoveInventoryItem(localID, itemID); - part.GetProperties(remoteClient); } private InventoryItemBase CreateAgentInventoryItemFromTask(UUID destAgent, SceneObjectPart part, UUID itemId) diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 26fe61d113..345c2df0ca 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5347,41 +5347,6 @@ namespace OpenSim.Region.Framework.Scenes // } // } - lock (m_cleaningAttachments) - { - ForEachSOG(delegate (SceneObjectGroup grp) - { - if (grp.RootPart.Shape.PCode == 0 && grp.RootPart.Shape.State != 0 && (!objectsToDelete.Contains(grp))) - { - UUID agentID = grp.OwnerID; - if (agentID == UUID.Zero) - { - objectsToDelete.Add(grp); - return; - } - - ScenePresence sp = GetScenePresence(agentID); - if (sp == null) - { - objectsToDelete.Add(grp); - return; - } - } - }); - } - - if (objectsToDelete.Count > 0) - { - m_log.DebugFormat("[SCENE]: Starting delete of {0} dropped attachments", objectsToDelete.Count); - foreach (SceneObjectGroup grp in objectsToDelete) - { - m_log.InfoFormat("[SCENE]: Deleting dropped attachment {0} of user {1}", grp.UUID, grp.OwnerID); - DeleteSceneObject(grp, true); - } - m_log.Debug("[SCENE]: Finished dropped attachment deletion"); - } - } - public void ThreadAlive(int threadCode) { switch(threadCode) diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 29edf13c46..42e2502e8f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs @@ -1437,9 +1437,9 @@ namespace OpenSim.Region.Framework.Scenes // Set the new attachment point data in the object byte attachmentPoint = group.GetAttachmentPoint(); group.UpdateGroupPosition(pos); - group.RootPart.IsAttachment = false; + group.IsAttachment = false; group.AbsolutePosition = group.RootPart.AttachedPos; - group.SetAttachmentPoint(attachmentPoint); + group.AttachmentPoint = attachmentPoint; group.HasGroupChanged = true; } else @@ -1723,12 +1723,11 @@ namespace OpenSim.Region.Framework.Scenes // So that, on delink, no prims are unwittingly // left for sale and sold off - if (child != null) - { - child.RootPart.ObjectSaleType = 0; - child.RootPart.SalePrice = 10; - childGroups.Add(child); - } + if (child != null) + { + child.RootPart.ObjectSaleType = 0; + child.RootPart.SalePrice = 10; + childGroups.Add(child); } } diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 88a62327f4..35684e09ff 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs @@ -350,10 +350,6 @@ namespace OpenSim.Region.Framework.Scenes { get { return m_rotation; } set { - foreach(SceneObjectPart p in m_parts.GetArray()) - { - p.StoreUndoState(UndoType.STATE_GROUP_ROTATION); - } m_rotation = value; } } @@ -487,8 +483,6 @@ namespace OpenSim.Region.Framework.Scenes SceneObjectPart[] parts = m_parts.GetArray(); foreach (SceneObjectPart part in parts) { - part.IgnoreUndoUpdate = false; - part.StoreUndoState(UndoType.STATE_GROUP_POSITION); part.GroupPosition = val; if (!m_dupeInProgress) { @@ -1193,45 +1187,31 @@ namespace OpenSim.Region.Framework.Scenes /// /// /// - public void AttachToAgent(UUID agentID, uint attachmentpoint, Vector3 AttachOffset, bool silent) + private void AttachToAgent( + ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { - ScenePresence avatar = m_scene.GetScenePresence(agentID); if (avatar != null) { // don't attach attachments to child agents if (avatar.IsChildAgent) return; -// m_log.DebugFormat("[SOG]: Adding attachment {0} to avatar {1}", Name, avatar.Name); - - DetachFromBackup(); - // Remove from database and parcel prim count - m_scene.DeleteFromStorage(UUID); + m_scene.DeleteFromStorage(so.UUID); m_scene.EventManager.TriggerParcelPrimCountTainted(); - m_rootPart.AttachedAvatar = agentID; + so.AttachedAvatar = avatar.UUID; - //Anakin Lohner bug #3839 - lock (m_parts) + if (so.RootPart.PhysActor != null) { - foreach (SceneObjectPart p in m_parts.GetArray()) - { - p.AttachedAvatar = agentID; - } + m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor); + so.RootPart.PhysActor = null; } - if (m_rootPart.PhysActor != null) - { - m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); - m_rootPart.PhysActor = null; - } - - AbsolutePosition = AttachOffset; - m_rootPart.AttachedPos = AttachOffset; - m_rootPart.IsAttachment = true; - - m_rootPart.SetParentLocalId(avatar.LocalId); - SetAttachmentPoint(Convert.ToByte(attachmentpoint)); + so.AbsolutePosition = attachOffset; + so.RootPart.AttachedPos = attachOffset; + so.IsAttachment = true; + so.RootPart.SetParentLocalId(avatar.LocalId); + so.AttachmentPoint = attachmentpoint; avatar.AddAttachment(this); @@ -1254,7 +1234,7 @@ namespace OpenSim.Region.Framework.Scenes { m_log.WarnFormat( "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present", - UUID, agentID, Scene.RegionInfo.RegionName); + UUID, avatar.ControllingClient.AgentId, Scene.RegionInfo.RegionName); } } @@ -1263,11 +1243,6 @@ namespace OpenSim.Region.Framework.Scenes return m_rootPart.Shape.State; } - public void ClearPartAttachmentData() - { - SetAttachmentPoint((Byte)0); - } - public void DetachToGround() { ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar); @@ -1788,19 +1763,19 @@ namespace OpenSim.Region.Framework.Scenes // This is only necessary when userExposed is false! - bool previousAttachmentStatus = dupe.IsAttachment; + bool previousAttachmentStatus = dupe.IsAttachment; - if (!userExposed) - dupe.IsAttachment = true; + if (!userExposed) + dupe.IsAttachment = true; if (!userExposed) dupe.RootPart.IsAttachment = true; dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); - if (!userExposed) - { - dupe.IsAttachment = previousAttachmentStatus; - } + if (!userExposed) + { + dupe.IsAttachment = previousAttachmentStatus; + } if (!userExposed) { @@ -1855,8 +1830,8 @@ namespace OpenSim.Region.Framework.Scenes dupe.UpdateParentIDs(); dupe.HasGroupChanged = true; dupe.AttachToBackup(); - - ScheduleGroupForFullUpdate(); + } + ScheduleGroupForFullUpdate(); // Need to duplicate the physics actor as well if (part.PhysActor != null && userExposed) { @@ -3175,7 +3150,6 @@ namespace OpenSim.Region.Framework.Scenes { if (IsAttachment) { - m_rootPart.StoreUndoState(UndoType.STATE_GROUP_POSITION); m_rootPart.AttachedPos = pos; } if (RootPart.GetStatusSandbox()) @@ -3207,9 +3181,9 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = GetChildPart(localID); -// SceneObjectPart[] parts = m_parts.GetArray(); -// for (int i = 0; i < parts.Length; i++) -// parts[i].StoreUndoState(); + SceneObjectPart[] parts = m_parts.GetArray(); + for (int i = 0; i < parts.Length; i++) + parts[i].StoreUndoState(); if (part != null) { @@ -3368,8 +3342,6 @@ namespace OpenSim.Region.Framework.Scenes { SceneObjectPart part = GetChildPart(localID); SceneObjectPart[] parts = m_parts.GetArray(); - for (int i = 0; i < parts.Length; i++) - parts[i].StoreUndoState(UndoType.STATE_PRIM_ROTATION); if (part != null) { @@ -3440,14 +3412,7 @@ namespace OpenSim.Region.Framework.Scenes Quaternion axRot = rot; Quaternion oldParentRot = m_rootPart.RotationOffset; - - m_rootPart.StoreUndoState(UndoType.STATE_PRIM_ROTATION); - bool cancelUndo = false; - if (!m_rootPart.Undoing) - { - m_rootPart.Undoing = true; - cancelUndo = true; - } + m_rootPart.StoreUndoState(); //Don't use UpdateRotation because it schedules an update prematurely m_rootPart.RotationOffset = rot; diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 893faf827a..69887187a3 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs @@ -852,7 +852,7 @@ namespace OpenSim.Region.Framework.Scenes set { - StoreUndoState(UndoType.STATE_PRIM_ROTATION); + StoreUndoState(); m_rotationOffset = value; PhysicsActor actor = PhysActor; @@ -3590,7 +3590,8 @@ namespace OpenSim.Region.Framework.Scenes m_parentGroup.ScheduleGroupForTerseUpdate(); //m_parentGroup.ScheduleGroupForFullUpdate(); } - public void StoreUndoState(UndoType type) + + public void StoreUndoState() { StoreUndoState(false); } @@ -3613,57 +3614,45 @@ namespace OpenSim.Region.Framework.Scenes // TODO: May need to fix for group comparison if (last.Compare(this)) { - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", - // Name, LocalId, m_undo.Count); - + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Not storing undo for {0} {1} since current state is same as last undo state, initial stack size {2}", + // Name, LocalId, m_undo.Count); + return; } } } - - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", - // Name, LocalId, forGroup, m_undo.Count); - + + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Storing undo state for {0} {1}, forGroup {2}, initial stack size {3}", + // Name, LocalId, forGroup, m_undo.Count); + if (m_parentGroup.GetSceneMaxUndo() > 0) { UndoState nUndo = new UndoState(this, forGroup); - - UndoState nUndo = new UndoState(this, type); - if (lastUndo != null) - { - TimeSpan ts = DateTime.Now.Subtract(lastUndo.LastUpdated); - if (ts.TotalMilliseconds < 500) - { - //Delete the last entry since it was less than 500 milliseconds ago - nUndo.Merge(lastUndo); - m_undo.Pop(); - } - } m_undo.Push(nUndo); - + if (m_redo.Count > 0) m_redo.Clear(); - - // m_log.DebugFormat( - // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", - // Name, LocalId, forGroup, m_undo.Count); + + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Stored undo state for {0} {1}, forGroup {2}, stack size now {3}", + // Name, LocalId, forGroup, m_undo.Count); } } } } -// else -// { -// m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); -// } + // else + // { + // m_log.DebugFormat("[SCENE OBJECT PART]: Ignoring undo store for {0} {1}", Name, LocalId); + // } } -// else -// { -// m_log.DebugFormat( -// "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); -// } + // else + // { + // m_log.DebugFormat( + // "[SCENE OBJECT PART]: Ignoring undo store for {0} {1} since already undoing", Name, LocalId); + // } } /// diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index de9b1f317a..8ee7d8901e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs @@ -1361,12 +1361,15 @@ namespace OpenSim.Region.Framework.Scenes } } + /// + /// This is the event handler for client movement. If a client is moving, this event is triggering. + /// /// /// This is the event handler for client movement. If a client is moving, this event is triggering. /// public void HandleAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData) { -// m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name); + // m_log.DebugFormat("[SCENE PRESENCE]: Received agent update from {0}", remoteClient.Name); //if (m_isChildAgent) //{ @@ -1389,7 +1392,6 @@ namespace OpenSim.Region.Framework.Scenes m_log.Error("[AVATAR]: NonFinite Avatar position detected... Reset Position. Mantis this please. Error #9999902"); m_pos = m_LastFinitePos; - if (!m_pos.IsFinite()) { m_pos.X = 127f; @@ -1459,6 +1461,7 @@ namespace OpenSim.Region.Framework.Scenes m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - posAdjusted), Vector3.Distance(m_CameraCenter, posAdjusted) + 0.3f, RayCastCameraCallback); } } + lock (scriptedcontrols) { if (scriptedcontrols.Count > 0) @@ -1473,9 +1476,6 @@ namespace OpenSim.Region.Framework.Scenes if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) { - m_updateCount = 0; // Kill animation update burst so that the SIT_G.. will stick. - Animator.TrySetMovementAnimation("SIT_GROUND_CONSTRAINED"); - // TODO: This doesn't prevent the user from walking yet. // Setting parent ID would fix this, if we knew what value // to use. Or we could add a m_isSitting variable. @@ -1530,20 +1530,6 @@ namespace OpenSim.Region.Framework.Scenes if (actor.Flying != oldflying) update_movementflag = true; - if (m_animator.m_jumping) // add for jumping - update_movementflag = true; - - if (q != m_bodyRot) - { - m_bodyRot = q; - update_rotation = true; - } - - //guilty until proven innocent.. - bool Nudging = true; - //Basically, if there is at least one non-nudge control then we don't need - //to worry about stopping the avatar - if (m_parentID == 0) { bool bAllowUpdateMoveToPosition = false; @@ -1557,12 +1543,10 @@ namespace OpenSim.Region.Framework.Scenes else dirVectors = Dir_Vectors; - bool[] isNudge = GetDirectionIsNudge(); - - - - - + // The fact that m_movementflag is a byte needs to be fixed + // it really should be a uint + // A DIR_CONTROL_FLAG occurs when the user is trying to move in a particular direction. + uint nudgehack = 250; foreach (Dir_ControlFlags DCF in DIR_CONTROL_FLAGS) { if (((uint)flags & (uint)DCF) != 0) @@ -1572,30 +1556,43 @@ namespace OpenSim.Region.Framework.Scenes try { agent_control_v3 += dirVectors[i]; - if (isNudge[i] == false) - { - Nudging = false; - } + //m_log.DebugFormat("[Motion]: {0}, {1}",i, dirVectors[i]); } catch (IndexOutOfRangeException) { // Why did I get this? } - if ((m_movementflag & (uint)DCF) == 0) + if ((m_movementflag & (byte)(uint)DCF) == 0) { + if (DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE) + { + m_movementflag |= (byte)nudgehack; + } -// m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); + // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with {1}", Name, DCF); m_movementflag += (byte)(uint)DCF; update_movementflag = true; } } else { - if ((m_movementflag & (uint)DCF) != 0) + if ((m_movementflag & (byte)(uint)DCF) != 0 || + ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACK_NUDGE) + && ((m_movementflag & (byte)nudgehack) == nudgehack)) + ) // This or is for Nudge forward { - m_movementflag -= (byte)(uint)DCF; + // m_log.DebugFormat("[SCENE PRESENCE]: Updating m_movementflag for {0} with lack of {1}", Name, DCF); + m_movementflag -= ((byte)(uint)DCF); update_movementflag = true; + + /* + if ((DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD_NUDGE || DCF == Dir_ControlFlags.DIR_CONTROL_FLAG_BACKWARD_NUDGE) + && ((m_movementflag & (byte)nudgehack) == nudgehack)) + { + m_log.Debug("Removed Hack flag"); + } + */ } else { @@ -1605,128 +1602,19 @@ namespace OpenSim.Region.Framework.Scenes i++; } + if (MovingToTarget) { - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; - update_movementflag = true; - bAllowUpdateMoveToPosition = false; - } - - if (bAllowUpdateMoveToPosition && (m_moveToPositionInProgress && !m_autopilotMoving)) - { -/* - bool twoD = false; - bool there = false; - if (Animator != null) - { - switch (Animator.CurrentMovementAnimation) - { - case "STAND": - case "WALK": - case "RUN": - case "CROUCH": - case "CROUCHWALK": - { - twoD = true; - } - break; - } - } - - if (twoD) - { -*/ - Vector3 abspos = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, 0.0f); - Vector3 tgt = new Vector3(m_moveToPositionTarget.X, m_moveToPositionTarget.Y, 0.0f); -/* if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) there = true; - } - else - { - if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) there = true; - } -*/ - //Check the error term of the current position in relation to the target position -// if (Util.GetDistanceTo(AbsolutePosition, m_moveToPositionTarget) <= 0.5f) -// if (there) - if (Util.GetDistanceTo(abspos, tgt) <= 0.5f) + // If the user has pressed a key then we want to cancel any move to target. + if (DCFlagKeyPressed) { ResetMoveToTarget(); update_movementflag = true; } else if (bAllowUpdateMoveToPosition) { - try - { - // move avatar in 2D at one meter/second towards target, in avatar coordinate frame. - // This movement vector gets added to the velocity through AddNewMovement(). - // Theoretically we might need a more complex PID approach here if other - // unknown forces are acting on the avatar and we need to adaptively respond - // to such forces, but the following simple approach seems to works fine. - Vector3 LocalVectorToTarget3D = -// (m_moveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords - (tgt - abspos) - * Matrix4.CreateFromQuaternion(Quaternion.Inverse(bodyRotation)); // change to avatar coords - // Ignore z component of vector - Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); - LocalVectorToTarget2D.Normalize(); - - //We're not nudging - Nudging = false; - agent_control_v3 += LocalVectorToTarget2D; - - // update avatar movement flags. the avatar coordinate system is as follows: - // - // +X (forward) - // - // ^ - // | - // | - // | - // | - // (left) +Y <--------o--------> -Y - // avatar - // | - // | - // | - // | - // v - // -X - // - - // based on the above avatar coordinate system, classify the movement into - // one of left/right/back/forward. - if (LocalVectorToTarget2D.Y > 0)//MoveLeft - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - //AgentControlFlags - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_LEFT; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.Y < 0) //MoveRight - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_RIGHT; - update_movementflag = true; - } - if (LocalVectorToTarget2D.X < 0) //MoveBack - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_BACK; - update_movementflag = true; - } - else if (LocalVectorToTarget2D.X > 0) //Move Forward - { - m_movementflag += (byte)(uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - AgentControlFlags |= (uint)Dir_ControlFlags.DIR_CONTROL_FLAG_FORWARD; - update_movementflag = true; - } - } - catch (Exception e) - { - //Avoid system crash, can be slower but... - m_log.DebugFormat("Crash! {0}", e.ToString()); - } + if (HandleMoveToTargetUpdate(ref agent_control_v3)) + update_movementflag = true; } } } @@ -1759,31 +1647,26 @@ namespace OpenSim.Region.Framework.Scenes // which occurs later in the main scene loop if (update_movementflag || (update_rotation && DCFlagKeyPressed)) { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", -// m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); + // m_log.DebugFormat( + // "[SCENE PRESENCE]: In {0} adding velocity of {1} to {2}, umf = {3}, ur = {4}", + // m_scene.RegionInfo.RegionName, agent_control_v3, Name, update_movementflag, update_rotation); - AddNewMovement(agent_control_v3, q, Nudging); - - + AddNewMovement(agent_control_v3); } -// else -// { -// if (!update_movementflag) -// { -// m_log.DebugFormat( -// "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", -// m_scene.RegionInfo.RegionName, agent_control_v3, Name); -// } -// } + // else + // { + // if (!update_movementflag) + // { + // m_log.DebugFormat( + // "[SCENE PRESENCE]: In {0} ignoring requested update of {1} for {2} as update_movementflag = false", + // m_scene.RegionInfo.RegionName, agent_control_v3, Name); + // } + // } if (update_movementflag && m_parentID == 0) Animator.UpdateMovementAnimations(); } - if (update_movementflag && !SitGround) - Animator.UpdateMovementAnimations(); - m_scene.EventManager.TriggerOnClientMovement(this); m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); @@ -1799,24 +1682,20 @@ namespace OpenSim.Region.Framework.Scenes /// True if movement has been updated in some way. False otherwise. public bool HandleMoveToTargetUpdate(ref Vector3 agent_control_v3) { -// m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); + // m_log.DebugFormat("[SCENE PRESENCE]: Called HandleMoveToTargetUpdate() for {0}", Name); + bool updated = false; - public void StopMoveToPosition() - { - m_moveToPositionTarget = Vector3.Zero; - m_moveToPositionInProgress = false; - } + // m_log.DebugFormat( + // "[SCENE PRESENCE]: bAllowUpdateMoveToPosition {0}, m_moveToPositionInProgress {1}, m_autopilotMoving {2}", + // allowUpdate, m_moveToPositionInProgress, m_autopilotMoving); - public void DoMoveToPosition(Object sender, string method, List args) - { -//Console.WriteLine("SP:DoMoveToPosition"); - try + if (!m_autopilotMoving) { double distanceToTarget = Util.GetDistanceTo(AbsolutePosition, MoveToPositionTarget); -// m_log.DebugFormat( -// "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", -// Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); + // m_log.DebugFormat( + // "[SCENE PRESENCE]: Abs pos of {0} is {1}, target {2}, distance {3}", + // Name, AbsolutePosition, MoveToPositionTarget, distanceToTarget); // Check the error term of the current position in relation to the target position if (distanceToTarget <= 1) @@ -1839,7 +1718,7 @@ namespace OpenSim.Region.Framework.Scenes (MoveToPositionTarget - AbsolutePosition) // vector from cur. pos to target in global coords * Matrix4.CreateFromQuaternion(Quaternion.Inverse(Rotation)); // change to avatar coords // Ignore z component of vector -// Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); + // Vector3 LocalVectorToTarget2D = new Vector3((float)(LocalVectorToTarget3D.X), (float)(LocalVectorToTarget3D.Y), 0f); LocalVectorToTarget3D.Normalize(); // update avatar movement flags. the avatar coordinate system is as follows: @@ -1905,9 +1784,9 @@ namespace OpenSim.Region.Framework.Scenes updated = true; } -// m_log.DebugFormat( -// "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", -// LocalVectorToTarget3D, agent_control_v3, Name); + // m_log.DebugFormat( + // "[SCENE PRESENCE]: HandleMoveToTargetUpdate adding {0} to move vector {1} for {2}", + // LocalVectorToTarget3D, agent_control_v3, Name); agent_control_v3 += LocalVectorToTarget3D; } @@ -1917,7 +1796,7 @@ namespace OpenSim.Region.Framework.Scenes m_log.DebugFormat("Crash! {0}", e.ToString()); } } - } + } return updated; } @@ -2746,41 +2625,21 @@ namespace OpenSim.Region.Framework.Scenes /// Rotate the avatar to the given rotation and apply a movement in the given relative vector /// /// The vector in which to move. This is relative to the rotation argument - /// The direction in which this avatar should now face. - public void AddNewMovement(Vector3 vec, Quaternion rotation, bool Nudging) + public void AddNewMovement(Vector3 vec) { - if (m_isChildAgent) - { - // WHAT??? - m_log.Debug("[SCENEPRESENCE]: AddNewMovement() called on child agent"); - - return; - } - m_perfMonMS = Util.EnvironmentTickCount(); Vector3 direc = vec * Rotation; direc.Normalize(); - PhysicsActor actor = m_physicsActor; - - if (actor.Flying != m_flyingOld) // add for fly velocity control - { - m_flyingOld = actor.Flying; // add for fly velocity control - if (!actor.Flying) m_wasFlying = true; // add for fly velocity control - } - - if (m_physicsActor.IsColliding == true) m_wasFlying = false; // add for fly velocity control - - if ((vec.Z == 0f) && !actor.Flying) direc.Z = 0f; // Prevent camera WASD up. direc *= 0.03f * 128f * m_speedModifier; + PhysicsActor actor = m_physicsActor; if (actor != null) { if (actor.Flying) { -// rm speed mod direc *= 4.0f; - direc *= 5.2f; // for speed mod + direc *= 4.0f; //bool controlland = (((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0) || ((m_AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)); //bool colliding = (m_physicsActor.IsColliding==true); //if (controlland) @@ -2793,34 +2652,22 @@ namespace OpenSim.Region.Framework.Scenes // m_log.Info("[AGENT]: Stop FLying"); //} } - if (Animator.m_falling && m_wasFlying) // if falling from flying, disable motion add - { - direc *= 0.0f; - } - /* This jumping section removed to SPA else if (!actor.Flying && actor.IsColliding) { if (direc.Z > 2.0f) { - if(m_animator.m_animTickJump == -1) - { - direc.Z *= 3.0f; // jump - } - else - { - direc.Z *= 0.1f; // prejump - } - / * Animations are controlled via GetMovementAnimation() in ScenePresenceAnimator.cs - Animator.TrySetMovementAnimation("PREJUMP"); - Animator.TrySetMovementAnimation("JUMP"); - * / + direc.Z *= 3.0f; + + // TODO: PreJump and jump happen too quickly. Many times prejump gets ignored. + Animator.TrySetMovementAnimation("PREJUMP"); + Animator.TrySetMovementAnimation("JUMP"); } - } */ + } } // TODO: Add the force instead of only setting it to support multiple forces per frame? m_forceToApply = direc; - m_isNudging = Nudging; + m_scene.StatsReporter.AddAgentTime(Util.EnvironmentTickCountSubtract(m_perfMonMS)); } @@ -3961,7 +3808,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju { StartCollidingMessage.Colliders = colliding; - foreach (SceneObjectGroup att in Attachments) + foreach (SceneObjectGroup att in GetAttachments()) Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); } } @@ -3996,7 +3843,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju { EndCollidingMessage.Colliders = colliding; - foreach (SceneObjectGroup att in Attachments) + foreach (SceneObjectGroup att in GetAttachments()) Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); } } @@ -4517,7 +4364,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju List attachments = m_appearance.GetAttachments(); foreach (AvatarAttachment attach in attachments) { - if (m_isDeleted) + if (IsDeleted) return; int p = attach.AttachPoint; @@ -4603,7 +4450,7 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju public void SaveChangedAttachments() { // Need to copy this list because DetachToInventoryPrep mods it - List attachments = new List(Attachments.ToArray()); + List attachments = new List(GetAttachments().ToArray()); IAttachmentsModule attachmentsModule = m_scene.AttachmentsModule; if (attachmentsModule != null) @@ -4612,12 +4459,12 @@ if (m_animator.m_jumping) force.Z = m_animator.m_jumpVelocity; // add for ju { if (grp.HasGroupChanged) // Resizer scripts? { - grp.RootPart.IsAttachment = false; + grp.IsAttachment = false; grp.AbsolutePosition = grp.RootPart.AttachedPos; // grp.DetachToInventoryPrep(); attachmentsModule.UpdateKnownItem(ControllingClient, grp, grp.GetFromItemID(), grp.OwnerID); - grp.RootPart.IsAttachment = true; + grp.IsAttachment = true; } } } diff --git a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs index 2db718c413..f9e118b23c 100644 --- a/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs +++ b/OpenSim/Region/OptionalModules/World/AutoBackup/AutoBackupModuleState.cs @@ -23,104 +23,104 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -using System; -using System.Collections.Generic; - - -namespace OpenSim.Region.OptionalModules.World.AutoBackup -{ - /// AutoBackupModuleState: Auto-Backup state for one region (scene). - /// If you use this class in any way outside of AutoBackupModule, you should treat the class as opaque. - /// Since it is not part of the framework, you really should not rely upon it outside of the AutoBackupModule implementation. - /// - /// - public class AutoBackupModuleState - { - private Dictionary m_liveRequests = null; - - public AutoBackupModuleState() - { - this.Enabled = false; - this.BackupDir = "."; - this.BusyCheck = true; - this.Timer = null; - this.NamingType = NamingType.Time; - this.Script = null; - } - - public Dictionary LiveRequests - { - get { - return this.m_liveRequests ?? - (this.m_liveRequests = new Dictionary(1)); - } - } - - public bool Enabled - { - get; - set; - } - - public System.Timers.Timer Timer - { - get; - set; - } - - public double IntervalMinutes - { - get - { - if (this.Timer == null) - { - return -1.0; - } - else - { - return this.Timer.Interval / 60000.0; - } - } - } - - public bool BusyCheck - { - get; - set; - } - - public string Script - { - get; - set; - } - - public string BackupDir - { - get; - set; - } - - public NamingType NamingType - { - get; - set; - } - - public new string ToString() - { - string retval = ""; - - retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n"; - retval += "[AUTO BACKUP]: Interval: " + IntervalMinutes + " minutes" + "\n"; - retval += "[AUTO BACKUP]: Do Busy Check: " + (BusyCheck ? "Yes" : "No") + "\n"; - retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n"; - retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n"; - retval += "[AUTO BACKUP]: Script: " + Script + "\n"; - return retval; - } - } -} - + */ + +using System; +using System.Collections.Generic; + + +namespace OpenSim.Region.OptionalModules.World.AutoBackup +{ + /// AutoBackupModuleState: Auto-Backup state for one region (scene). + /// If you use this class in any way outside of AutoBackupModule, you should treat the class as opaque. + /// Since it is not part of the framework, you really should not rely upon it outside of the AutoBackupModule implementation. + /// + /// + public class AutoBackupModuleState + { + private Dictionary m_liveRequests = null; + + public AutoBackupModuleState() + { + this.Enabled = false; + this.BackupDir = "."; + this.BusyCheck = true; + this.Timer = null; + this.NamingType = NamingType.Time; + this.Script = null; + } + + public Dictionary LiveRequests + { + get { + return this.m_liveRequests ?? + (this.m_liveRequests = new Dictionary(1)); + } + } + + public bool Enabled + { + get; + set; + } + + public System.Timers.Timer Timer + { + get; + set; + } + + public double IntervalMinutes + { + get + { + if (this.Timer == null) + { + return -1.0; + } + else + { + return this.Timer.Interval / 60000.0; + } + } + } + + public bool BusyCheck + { + get; + set; + } + + public string Script + { + get; + set; + } + + public string BackupDir + { + get; + set; + } + + public NamingType NamingType + { + get; + set; + } + + public new string ToString() + { + string retval = ""; + + retval += "[AUTO BACKUP]: AutoBackup: " + (Enabled ? "ENABLED" : "DISABLED") + "\n"; + retval += "[AUTO BACKUP]: Interval: " + IntervalMinutes + " minutes" + "\n"; + retval += "[AUTO BACKUP]: Do Busy Check: " + (BusyCheck ? "Yes" : "No") + "\n"; + retval += "[AUTO BACKUP]: Naming Type: " + NamingType.ToString() + "\n"; + retval += "[AUTO BACKUP]: Backup Dir: " + BackupDir + "\n"; + retval += "[AUTO BACKUP]: Script: " + Script + "\n"; + return retval; + } + } +} + diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 9ec8a42f81..0c1da47f24 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2166,8 +2166,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID x = module.CreateNPC(firstname, lastname, new Vector3((float) position.x, (float) position.y, (float) position.z), - World, - appearance); + World,appearance); return new LSL_Key(x.ToString()); }