public LSL_Integer llGetAgentInfo(string id)
{
if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return 0;
UUID key = new UUID();
if (!UUID.TryParse(id, out key))
{
return 0;
}
int flags = 0;
IScenePresence agent = World.GetScenePresence(key);
if (agent == null)
{
return 0;
}
if (agent.IsChildAgent)
return 0; // Fail if they are not in the same region
// note: in OpenSim, sitting seems to cancel AGENT_ALWAYS_RUN, unlike SL
if (agent.SetAlwaysRun)
{
flags |= ScriptBaseClass.AGENT_ALWAYS_RUN;
}
IAttachmentsModule attachMod = World.RequestModuleInterface<IAttachmentsModule>();
if (attachMod != null)
{
ISceneEntity[] att = attachMod.GetAttachmentsForAvatar(agent.UUID);
if (att.Length > 0)
{
flags |= ScriptBaseClass.AGENT_ATTACHMENTS;
#if (!ISWIN)
foreach (ISceneEntity gobj in att)
{
if (gobj != null)
{
if (gobj.RootChild.Inventory.ContainsScripts())
{
flags |= ScriptBaseClass.AGENT_SCRIPTED;
break;
}
}
}
#else
if (att.Where(gobj => gobj != null).Any(gobj => gobj.RootChild.Inventory.ContainsScripts()))
{
flags |= ScriptBaseClass.AGENT_SCRIPTED;
}
#endif
}
}
if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0)
{
flags |= ScriptBaseClass.AGENT_FLYING;
flags |= ScriptBaseClass.AGENT_IN_AIR; // flying always implies in-air, even if colliding with e.g. a wall
}
if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AWAY) != 0)
{
flags |= ScriptBaseClass.AGENT_AWAY;
}
// seems to get unset, even if in mouselook, when avatar is sitting on a prim???
if ((agent.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
{
flags |= ScriptBaseClass.AGENT_MOUSELOOK;
}
if ((agent.State & (byte)AgentState.Typing) != 0)
{
flags |= ScriptBaseClass.AGENT_TYPING;
}
if (agent.IsBusy)
{
flags |= ScriptBaseClass.AGENT_BUSY;
}
string agentMovementAnimation = agent.Animator.CurrentMovementAnimation;
if (agentMovementAnimation == "CROUCH")
{
flags |= ScriptBaseClass.AGENT_CROUCHING;
}
if (agentMovementAnimation == "WALK" || agentMovementAnimation == "CROUCHWALK")
{
flags |= ScriptBaseClass.AGENT_WALKING;
}
// not colliding implies in air. Note: flying also implies in-air, even if colliding (see above)
// note: AGENT_IN_AIR and AGENT_WALKING seem to be mutually exclusive states in SL.
// note: this may need some tweaking when walking downhill. you "fall down" for a brief instant
// and don't collide when walking downhill, which instantly registers as in-air, briefly. should
// there be some minimum non-collision threshold time before claiming the avatar is in-air?
if ((flags & ScriptBaseClass.AGENT_WALKING) == 0 &&
agent.PhysicsActor != null &&
!agent.PhysicsActor.IsColliding)
{
flags |= ScriptBaseClass.AGENT_IN_AIR;
}
if (agent.ParentID != UUID.Zero)
{
flags |= ScriptBaseClass.AGENT_ON_OBJECT;
flags |= ScriptBaseClass.AGENT_SITTING;
}
if (agent.Animator.Animations.DefaultAnimation.AnimID
== AnimationSet.Animations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
{
flags |= ScriptBaseClass.AGENT_SITTING;
}
return flags;
}