private void ContinueSitAsRootAgent(IClientAPI client, SceneObjectPart part, Vector3 offset) { Quaternion sitOrientation = Quaternion.Identity; DumpDebug("ContinueSitAsRootAgent", "n/a"); if (part != null) { lock (m_posInfo) { SceneObjectGroup group = part.ParentGroup; SitTargetInfo sitInfo = group.SitTargetForPart(part.UUID); part.AddSeatedAvatar(this, false); sitOrientation = sitInfo.Rotation; m_requestedSitTargetUUID = part.UUID; m_requestedSitTargetID = part.LocalId; if (m_avatarMovesWithPart) { Vector3 newPos = sitInfo.Offset; newPos += m_sitTargetCorrectionOffset; m_bodyRot = sitInfo.Rotation; //Rotation = sitTargetOrient; SetAgentPositionInfo(null, true, newPos, part, part.AbsolutePosition, Vector3.Zero); } } //m_animPersistUntil = 0; // abort any timed animation // Avatar has arrived on prim int avatarsRemainingOnPrim = part.ParentGroup.RidingAvatarArrivedFromOtherSim(); if (avatarsRemainingOnPrim > 0) { m_log.InfoFormat("[SCENE PRESENCE]: {0} Recognizing incoming avatar {1} seated on {2} ({3} remain)", Scene.RegionInfo.RegionName, this.UUID.ToString(), part.ParentGroup.Name, part.ParentGroup.AvatarsToExpect); } m_scene.EventManager.TriggerOnCrossedAvatarReady(part, this.UUID); //mitigation for client not getting the required immediate update for crossing objects //part.ParentGroup.SendFullUpdateToClientImmediate(this.ControllingClient); // Trigger any remaining events that rely on the avatar being present. if (!part.ParentGroup.IsAttachment) if (avatarsRemainingOnPrim == 0) part.ParentGroup.TriggerScriptChangedEvent(Changed.REGION); if (ControllingClient.DebugCrossings) { ulong elapsedMs = (Util.GetLongTickCount() - part.ParentGroup.TimeReceived); string msg = (elapsedMs / 1000.0f).ToString("0.000") + " seconds to confirm seated on object for " + this.Name; m_log.Info("[CROSSING]: " + msg); MessageToUserFromServer(msg); } } else { m_log.ErrorFormat("[SCENE PRESENCE]: ContinueSitAsRootAgent could not find seated prim {0} for agent {1}", part.UUID.ToString(), client.AgentId.ToString()); } }