From 87d55443d3fd3cc86dce0b8efe05a8c304f7d6c8 Mon Sep 17 00:00:00 2001 From: Teravus Ovares Date: Thu, 27 Dec 2007 03:25:00 +0000 Subject: * Added slightly better object sit handling * Added sit handling for sit targets * Implemented llSitTarget() * Implemented llAvatarOnSitTarget() * Sit targets do not persist sim restart. --- OpenSim/Region/ClientStack/ClientView.cs | 182 +++++++++++---------- OpenSim/Region/ClientStack/PacketServer.cs | 4 +- OpenSim/Region/ClientStack/UDPServer.cs | 12 +- .../Region/Environment/Scenes/SceneObjectPart.cs | 34 ++++ OpenSim/Region/Environment/Scenes/ScenePresence.cs | 110 +++++++++++-- .../Compiler/Server_API/LSL_BuiltIn_Commands.cs | 14 +- 6 files changed, 245 insertions(+), 111 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ClientStack/ClientView.cs b/OpenSim/Region/ClientStack/ClientView.cs index 823214a..45806ff 100644 --- a/OpenSim/Region/ClientStack/ClientView.cs +++ b/OpenSim/Region/ClientStack/ClientView.cs @@ -1999,118 +1999,128 @@ namespace OpenSim.Region.ClientStack { // Can't act on Null Data if (multipleupdate.ObjectData[i].Data != null) - { - if (tScene.PermissionsMngr.CanEditObjectPosition(simClient.AgentId, tScene.GetSceneObjectPart(multipleupdate.ObjectData[i].ObjectLocalID).UUID)) + { + LLUUID editobj = tScene.GetSceneObjectPart(multipleupdate.ObjectData[i].ObjectLocalID).UUID; + if (editobj != null) { - #region position - - if (multipleupdate.ObjectData[i].Type == 9) //change position + if (tScene.PermissionsMngr.CanEditObjectPosition(simClient.AgentId, editobj)) { - if (OnUpdatePrimGroupPosition != null) + #region position + + if (multipleupdate.ObjectData[i].Type == 9) //change position { - LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); - OnUpdatePrimGroupPosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + if (OnUpdatePrimGroupPosition != null) + { + LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + OnUpdatePrimGroupPosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + } } - } - else if (multipleupdate.ObjectData[i].Type == 1) //single item of group change position - { - if (OnUpdatePrimSinglePosition != null) + else if (multipleupdate.ObjectData[i].Type == 1) //single item of group change position { - LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); - // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); - OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + if (OnUpdatePrimSinglePosition != null) + { + LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); + OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + } } - } - #endregion position - #region rotation + #endregion position + #region rotation - else if (multipleupdate.ObjectData[i].Type == 2) // single item of group rotation from tab - { - if (OnUpdatePrimSingleRotation != null) + else if (multipleupdate.ObjectData[i].Type == 2) // single item of group rotation from tab { - LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); - //System.Console.WriteLine("new tab rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); - OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + if (OnUpdatePrimSingleRotation != null) + { + LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); + //System.Console.WriteLine("new tab rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); + OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + } } - } - else if (multipleupdate.ObjectData[i].Type == 3) // single item of group rotation from mouse - { - if (OnUpdatePrimSingleRotation != null) + else if (multipleupdate.ObjectData[i].Type == 3) // single item of group rotation from mouse { - LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true); - //System.Console.WriteLine("new mouse rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); - OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + if (OnUpdatePrimSingleRotation != null) + { + LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true); + //System.Console.WriteLine("new mouse rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); + OnUpdatePrimSingleRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + } } - } - else if (multipleupdate.ObjectData[i].Type == 10) //group rotation from object tab - { - if (OnUpdatePrimGroupRotation != null) + else if (multipleupdate.ObjectData[i].Type == 10) //group rotation from object tab { - LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); - // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); - OnUpdatePrimGroupRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + if (OnUpdatePrimGroupRotation != null) + { + LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 0, true); + // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); + OnUpdatePrimGroupRotation(multipleupdate.ObjectData[i].ObjectLocalID, rot, this); + } } - } - else if (multipleupdate.ObjectData[i].Type == 11) //group rotation from mouse - { - if (OnUpdatePrimGroupMouseRotation != null) + else if (multipleupdate.ObjectData[i].Type == 11) //group rotation from mouse { - LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); - LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true); - //Console.WriteLine("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z); - // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); - OnUpdatePrimGroupMouseRotation(multipleupdate.ObjectData[i].ObjectLocalID, pos, rot, this); + if (OnUpdatePrimGroupMouseRotation != null) + { + LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + LLQuaternion rot = new LLQuaternion(multipleupdate.ObjectData[i].Data, 12, true); + //Console.WriteLine("new rotation position is " + pos.X + " , " + pos.Y + " , " + pos.Z); + // Console.WriteLine("new rotation is " + rot.X + " , " + rot.Y + " , " + rot.Z + " , " + rot.W); + OnUpdatePrimGroupMouseRotation(multipleupdate.ObjectData[i].ObjectLocalID, pos, rot, this); + } } - } - #endregion - #region scale + #endregion + #region scale - else if (multipleupdate.ObjectData[i].Type == 13) //group scale from object tab - { - if (OnUpdatePrimScale != null) + else if (multipleupdate.ObjectData[i].Type == 13) //group scale from object tab { - LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); - //Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); - OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); - - // Change the position based on scale (for bug number 246) - LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); - // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); - OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + if (OnUpdatePrimScale != null) + { + LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); + //Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); + OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + + // Change the position based on scale (for bug number 246) + LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + // System.Console.WriteLine("new movement position is " + pos.X + " , " + pos.Y + " , " + pos.Z); + OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + } } - } - else if (multipleupdate.ObjectData[i].Type == 29) //group scale from mouse - { - if (OnUpdatePrimScale != null) + else if (multipleupdate.ObjectData[i].Type == 29) //group scale from mouse { - LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); - // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z ); - OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); - LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); - OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + if (OnUpdatePrimScale != null) + { + LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); + // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z ); + OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + LLVector3 pos = new LLVector3(multipleupdate.ObjectData[i].Data, 0); + OnUpdatePrimSinglePosition(multipleupdate.ObjectData[i].ObjectLocalID, pos, this); + } } - } - else if (multipleupdate.ObjectData[i].Type == 5) //single prim scale from object tab - { - if (OnUpdatePrimScale != null) + else if (multipleupdate.ObjectData[i].Type == 5) //single prim scale from object tab { - LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); - // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); - OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + if (OnUpdatePrimScale != null) + { + LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); + // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); + OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + } } - } - else if (multipleupdate.ObjectData[i].Type == 21) //single prim scale from mouse - { - if (OnUpdatePrimScale != null) + else if (multipleupdate.ObjectData[i].Type == 21) //single prim scale from mouse { - LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); - // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); - OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + if (OnUpdatePrimScale != null) + { + LLVector3 scale = new LLVector3(multipleupdate.ObjectData[i].Data, 12); + // Console.WriteLine("new scale is " + scale.X + " , " + scale.Y + " , " + scale.Z); + OnUpdatePrimScale(multipleupdate.ObjectData[i].ObjectLocalID, scale, this); + } } - } - #endregion + #endregion + } + } // editobj != null; + else + { + // It's a ghost! tell the client to delete it from view. + simClient.SendKillObject(this.Scene.RegionInfo.RegionHandle, multipleupdate.ObjectData[i].ObjectLocalID); } + } } return true; diff --git a/OpenSim/Region/ClientStack/PacketServer.cs b/OpenSim/Region/ClientStack/PacketServer.cs index a4c18d0..a232db8 100644 --- a/OpenSim/Region/ClientStack/PacketServer.cs +++ b/OpenSim/Region/ClientStack/PacketServer.cs @@ -123,9 +123,9 @@ namespace OpenSim.Region.ClientStack /// public virtual void CloseCircuit(uint circuitcode) { - OpenSim.Framework.Console.MainLog.Instance.Debug("PACKETSERVER", "Removing Circuit Code"); + m_networkHandler.RemoveClientCircuit(circuitcode); - OpenSim.Framework.Console.MainLog.Instance.Debug("PACKETSERVER", "Removed Circuit Code"); + //m_scene.ClientManager.CloseAllAgents(circuitcode); } diff --git a/OpenSim/Region/ClientStack/UDPServer.cs b/OpenSim/Region/ClientStack/UDPServer.cs index a8a1ff6..47e0b3c 100644 --- a/OpenSim/Region/ClientStack/UDPServer.cs +++ b/OpenSim/Region/ClientStack/UDPServer.cs @@ -326,9 +326,9 @@ namespace OpenSim.Region.ClientStack uint circuit; if (clientCircuits.TryGetValue(sender, out circuit)) { - MainLog.Instance.Debug("UDPSERVER", "CloseEndPoint:ClosingCircuit"); + m_packetServer.CloseCircuit(circuit); - MainLog.Instance.Debug("UDPSERVER", "CloseEndPoint:ClosedCircuit"); + } } @@ -381,13 +381,13 @@ namespace OpenSim.Region.ClientStack EndPoint sendto = null; if (clientCircuits_reverse.TryGetValue(circuitcode, out sendto)) { - MainLog.Instance.Debug("UDPSERVER", "RemovingClientCircuit"); + clientCircuits.Remove(sendto); - MainLog.Instance.Debug("UDPSERVER", "Removed Client Circuit"); + - MainLog.Instance.Debug("UDPSERVER", "Removing Reverse ClientCircuit"); + clientCircuits_reverse.Remove(circuitcode); - MainLog.Instance.Debug("UDPSERVER", "Removed Reverse ClientCircuit"); + } } } diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs index 34705db..bcd31c2 100644 --- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs @@ -68,6 +68,11 @@ namespace OpenSim.Region.Environment.Scenes public Int32 CreationDate; public uint ParentID = 0; + private Vector3 m_sitTargetPosition = new Vector3(0, 0, 0); + private Quaternion m_sitTargetOrientation = new Quaternion(0, 0, 0, 1); + private LLUUID m_SitTargetAvatar = LLUUID.Zero; + + // Main grid has default permissions as follows // public uint OwnerMask = FULL_MASK_PERMISSIONS_OWNER; @@ -161,6 +166,8 @@ namespace OpenSim.Region.Environment.Scenes //unkown if this will be kept, added as a way of removing the group position from the group class protected LLVector3 m_groupPosition; + + public LLVector3 GroupPosition { get @@ -774,6 +781,33 @@ namespace OpenSim.Region.Environment.Scenes m_parentGroup = parent; } + public void SetSitTarget(Vector3 offset, Quaternion orientation) + { + m_sitTargetPosition = offset; + m_sitTargetOrientation = orientation; + } + + public Vector3 GetSitTargetPosition() + { + return m_sitTargetPosition; + } + + public Quaternion GetSitTargetOrientation() + { + return m_sitTargetOrientation; + } + + public void SetAvatarOnSitTarget(LLUUID avatarID) + { + m_SitTargetAvatar = avatarID; + } + + public LLUUID GetAvatarOnSitTarget() + { + return m_SitTargetAvatar; + } + + public LLUUID GetRootPartUUID() { if (m_parentGroup != null) diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 4b8ca97..9a937a2 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs @@ -537,7 +537,7 @@ namespace OpenSim.Region.Environment.Scenes // and send a full object update. // There's no message to send the client to tell it to stop flying - // Add 1/2 the avatar's height to it's position so it doesn't shoot into the air + // Add 1/6 the avatar's height to it's position so it doesn't shoot into the air // when the avatar stands up AbsolutePosition = AbsolutePosition + new LLVector3(0, 0, (m_avHeight/6)); @@ -748,6 +748,15 @@ namespace OpenSim.Region.Environment.Scenes { if (m_parentID != 0) { + + SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); + if (part != null) + { + // Reset sit target. + if (part.GetAvatarOnSitTarget() == UUID) + part.SetAvatarOnSitTarget(LLUUID.Zero); + } + m_pos += m_parentPosition + new LLVector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); m_parentPosition = new LLVector3(); @@ -769,34 +778,82 @@ namespace OpenSim.Region.Environment.Scenes bool autopilot = true; LLVector3 pos = new LLVector3(); + LLQuaternion sitOrientation = new LLQuaternion(0,0,0,1); SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); if (part != null) { // TODO: determine position to sit at based on scene geometry; don't trust offset from client // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it + + + // Is a sit target available? + Vector3 avSitOffSet = part.GetSitTargetPosition(); + Quaternion avSitOrientation = part.GetSitTargetOrientation(); + LLUUID avOnTargetAlready = part.GetAvatarOnSitTarget(); + + bool SitTargetUnOccupied = (!(avOnTargetAlready != LLUUID.Zero)); + bool SitTargetisSet = (!(avSitOffSet.x == 0 && avSitOffSet.y == 0 && avSitOffSet.z == 0 && avSitOrientation.w == 0 && avSitOrientation.x == 0 && avSitOrientation.y == 0 && avSitOrientation.z == 1)); + + if (SitTargetisSet && SitTargetUnOccupied) + { + part.SetAvatarOnSitTarget(UUID); + offset = new LLVector3(avSitOffSet.x,avSitOffSet.y,avSitOffSet.z); + sitOrientation = new LLQuaternion(avSitOrientation.w,avSitOrientation.x,avSitOrientation.y,avSitOrientation.z); + autopilot = false; + + } + pos = part.AbsolutePosition + offset; if (m_physicsActor != null) { + // + // If we're not using the client autopilot, we're immediately warping the avatar to the location + // We can remove the physicsActor until they stand up. + // m_sitAvatarHeight = m_physicsActor.Size.Z; - } - // this doesn't seem to quite work yet.... - // // if we're close, set the avatar position to the target position and forgo autopilot - // if (AbsolutePosition.GetDistanceTo(pos) < 2.5) - // { - // autopilot = false; - // AbsolutePosition = pos + new LLVector3(0.0f, 0.0f, m_sitAvatarHeight); - // } - } + if (autopilot) + { + + if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) + { + autopilot = false; + + RemoveFromPhysicalScene(); + AbsolutePosition = pos + new LLVector3(0.0f, 0.0f, m_sitAvatarHeight); + + } + else + { + + } + } + else + { + RemoveFromPhysicalScene(); + + + } + } // Physactor != null + } // part != null + avatarSitResponse.SitTransform.AutoPilot = autopilot; avatarSitResponse.SitTransform.SitPosition = offset; - avatarSitResponse.SitTransform.SitRotation = new LLQuaternion(0.0f, 0.0f, 0.0f, 1.0f); + avatarSitResponse.SitTransform.SitRotation = sitOrientation; remoteClient.OutPacket(avatarSitResponse, ThrottleOutPacketType.Task); + + // This calls HandleAgentSit twice, once from here, and the client calls + // HandleAgentSit itself after it gets to the location + // It doesn't get to the location until we've moved them there though + // which happens in HandleAgentSit :P + if (!autopilot) + HandleAgentSit(remoteClient, UUID); + } public void HandleAgentRequestSit(IClientAPI remoteClient, LLUUID agentID, LLUUID targetID, LLVector3 offset) @@ -806,7 +863,7 @@ namespace OpenSim.Region.Environment.Scenes StandUp(); } - SendSitResponse(remoteClient, targetID, offset); + SceneObjectPart part = m_scene.GetSceneObjectPart(targetID); @@ -819,6 +876,7 @@ namespace OpenSim.Region.Environment.Scenes { MainLog.Instance.Warn("Sit requested on unknown object: " + targetID.ToString()); } + SendSitResponse(remoteClient, targetID, offset); } public void HandleAgentSit(IClientAPI remoteClient, LLUUID agentID) @@ -827,8 +885,28 @@ namespace OpenSim.Region.Environment.Scenes if (part != null) { - m_pos -= part.AbsolutePosition; - m_parentPosition = part.AbsolutePosition; + if (part.GetAvatarOnSitTarget() == UUID) + { + Vector3 sitTargetPos = part.GetSitTargetPosition(); + Quaternion sitTargetOrient = part.GetSitTargetOrientation(); + + //Quaternion vq = new Quaternion(sitTargetPos.x, sitTargetPos.y+0.2f, sitTargetPos.z+0.2f, 0); + //Quaternion nq = new Quaternion(sitTargetOrient.w, -sitTargetOrient.x, -sitTargetOrient.y, -sitTargetOrient.z); + + //Quaternion result = (sitTargetOrient * vq) * nq; + + m_pos = new LLVector3(sitTargetPos.x, sitTargetPos.y, sitTargetPos.z); + m_bodyRot = sitTargetOrient; + //Rotation = sitTargetOrient; + m_parentPosition = part.AbsolutePosition; + + //SendTerseUpdateToAllClients(); + } + else + { + m_pos -= part.AbsolutePosition; + m_parentPosition = part.AbsolutePosition; + } } m_parentID = m_requestedSitTargetID; @@ -838,6 +916,10 @@ namespace OpenSim.Region.Environment.Scenes SetMovementAnimation(Animations.AnimsLLUUID["SIT"], 1); SendFullUpdateToAllClients(); + // This may seem stupid, but Our Full updates don't send avatar rotation :P + // So we're also sending a terse update (which has avatar rotation) + SendTerseUpdateToAllClients(); + } /// diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/Server_API/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/Server_API/LSL_BuiltIn_Commands.cs index eeecd21..fb521df 100644 --- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/Server_API/LSL_BuiltIn_Commands.cs +++ b/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/Server_API/LSL_BuiltIn_Commands.cs @@ -2162,13 +2162,21 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler public void llSitTarget(LSL_Types.Vector3 offset, LSL_Types.Quaternion rot) { - NotImplemented("llSitTarget"); + // LSL quaternions can normalize to 0, normal Quaternions can't. + if (rot.s == 0 && rot.x == 0 && rot.y == 0 && rot.z == 0) + rot.z = 1; // ZERO_ROTATION = 0,0,0,1 + + m_host.SetSitTarget(new Vector3((float)offset.x, (float)offset.y, (float)offset.z), new Quaternion((float)rot.s, (float)rot.x, (float)rot.y, (float)rot.z)); } public string llAvatarOnSitTarget() { - NotImplemented("llAvatarOnSitTarget"); - return ""; + LLUUID AVID = m_host.GetAvatarOnSitTarget(); + + if (AVID != LLUUID.Zero) + return AVID.ToString(); + else + return ""; } public void llAddToLandPassList(string avatar, double hours) -- cgit v1.1