29 using System.Reflection;
30 using System.Collections.Generic;
32 using OpenSim.Framework;
34 using OpenSim.Region.Framework.Interfaces;
35 using OpenSim.Region.Framework.Scenes;
36 using OpenSim.Region.ScriptEngine.Shared;
37 using OpenSim.Region.ScriptEngine.Shared.Api;
39 namespace OpenSim.
Region.ScriptEngine.Shared.Api.Plugins
73 public int SensorsCount
77 return SenseRepeaters.Count;
83 m_CmdManager = CmdManager;
84 maximumRange = CmdManager.m_ScriptEngine.Config.GetDouble(
"SensorMaxRange", 96.0d);
85 maximumToReturn = CmdManager.m_ScriptEngine.Config.GetInt(
"SensorMaxResults", 16);
86 m_npcModule = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<
INPCModule>();
93 private const int AGENT = 1;
94 private const int AGENT_BY_USERNAME = 0x10;
95 private const int NPC = 0x20;
96 private const int ACTIVE = 2;
97 private const int PASSIVE = 4;
98 private const int SCRIPTED = 8;
100 private double maximumRange = 96.0;
101 private int maximumToReturn = 16;
106 private class SensedEntity : IComparable
108 public SensedEntity(
double detectedDistance, UUID detectedID)
110 distance = detectedDistance;
113 public int CompareTo(
object obj)
115 if (!(obj is SensedEntity))
throw new InvalidOperationException();
116 SensedEntity ent = (SensedEntity)obj;
117 if (ent == null || ent.distance < distance)
return 1;
118 if (ent.distance > distance)
return -1;
122 public double distance;
135 private List<SensorInfo> SenseRepeaters =
new List<SensorInfo>();
136 private object SenseRepeatListLock =
new object();
139 string name, UUID keyID,
int type,
double range,
143 UnSetSenseRepeaterEvents(m_localID, m_itemID);
150 ts.localID = m_localID;
151 ts.itemID = m_itemID;
156 if (range > maximumRange)
157 ts.range = maximumRange;
163 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.
interval);
165 AddSenseRepeater(ts);
168 private void AddSenseRepeater(SensorInfo senseRepeater)
170 lock (SenseRepeatListLock)
172 List<SensorInfo> newSenseRepeaters =
new List<SensorInfo>(SenseRepeaters);
173 newSenseRepeaters.Add(senseRepeater);
174 SenseRepeaters = newSenseRepeaters;
181 lock (SenseRepeatListLock)
183 List<SensorInfo> newSenseRepeaters =
new List<SensorInfo>();
188 newSenseRepeaters.Add(ts);
192 SenseRepeaters = newSenseRepeaters;
202 if (ts.
next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
206 ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.
interval);
212 string name, UUID keyID,
int type,
217 ts.localID = m_localID;
218 ts.itemID = m_itemID;
223 if (range > maximumRange)
224 ts.range = maximumRange;
232 private void SensorSweep(SensorInfo ts)
239 List<SensedEntity> sensedEntities =
new List<SensedEntity>();
242 if ((ts.type & (AGENT | AGENT_BY_USERNAME | NPC)) != 0 && (ts.type & SCRIPTED) == 0)
244 sensedEntities.AddRange(doAgentSensor(ts));
248 if ((ts.type & SCRIPTED) != 0 || (ts.type & PASSIVE) != 0 || (ts.type & ACTIVE) != 0)
250 sensedEntities.AddRange(doObjectSensor(ts));
255 if (sensedEntities.Count == 0)
259 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
266 sensedEntities.Sort();
267 int count = sensedEntities.Count;
269 List<DetectParams> detected =
new List<DetectParams>();
270 for (idx = 0; idx < count; idx++)
275 detect.Key = sensedEntities[idx].itemID;
276 detect.Populate(m_CmdManager.m_ScriptEngine.World);
277 detected.Add(detect);
284 if (detected.Count == maximumToReturn)
288 if (detected.Count == 0)
293 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
299 m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
302 detected.ToArray()));
308 private List<SensedEntity> doObjectSensor(SensorInfo ts)
310 List<EntityBase> Entities;
311 List<SensedEntity> sensedEntities =
new List<SensedEntity>();
315 if (ts.keyID !=
UUID.Zero)
318 m_CmdManager.m_ScriptEngine.World.Entities.TryGetValue(ts.keyID, out e);
320 return sensedEntities;
321 Entities =
new List<EntityBase>();
326 Entities =
new List<EntityBase>(m_CmdManager.m_ScriptEngine.World.GetEntities());
330 Vector3 fromRegionPos = SensePoint.GetWorldPosition();
342 Quaternion q = SensePoint.GetWorldRotation();
355 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
359 return sensedEntities;
361 fromRegionPos = avatar.AbsolutePosition;
367 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
369 Vector3 ZeroVector =
new Vector3(0, 0, 0);
371 bool nameSearch = !string.IsNullOrEmpty(ts.name);
377 if (nameSearch && ent.
Name != ts.name)
385 toRegionPos = ent.AbsolutePosition;
388 dx = toRegionPos.X - fromRegionPos.X;
389 dy = toRegionPos.Y - fromRegionPos.Y;
390 dz = toRegionPos.Z - fromRegionPos.Z;
395 if (Math.Abs(dx) > ts.range || Math.Abs(dy) > ts.range || Math.Abs(dz) > ts.range)
396 dis = ts.range + 1.0;
398 dis = Math.Sqrt(dx * dx + dy * dy + dz * dz);
400 if (keep && dis <= ts.range && ts.host.UUID != ent.
UUID)
405 part = ((SceneObjectGroup)ent).RootPart;
407 part.ParentGroup.RootPart.Shape.PCode != (byte)PCode.NewTree &&
417 if (ent.
Velocity.Equals(ZeroVector))
428 if (((ts.type & objtype) != 0))
431 if (ts.arc < Math.PI)
443 Vector3 diff = toRegionPos - fromRegionPos;
444 double dot = LSL_Types.Vector3.Dot(forward_dir, diff);
445 double mag_obj = LSL_Types.Vector3.Mag(diff);
446 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
452 if (ang_obj > ts.arc) keep =
false;
458 sensedEntities.Add(
new SensedEntity(dis, ent.
UUID));
463 return sensedEntities;
466 private List<SensedEntity> doAgentSensor(SensorInfo ts)
468 List<SensedEntity> sensedEntities =
new List<SensedEntity>();
471 if (m_CmdManager.m_ScriptEngine.World.GetRootAgentCount() == 0)
472 return sensedEntities;
475 Vector3 fromRegionPos = SensePoint.GetWorldPosition();
477 Quaternion q = SensePoint.GetWorldRotation();
490 ScenePresence avatar = m_CmdManager.m_ScriptEngine.World.GetScenePresence(SensePoint.ParentGroup.AttachedAvatar);
494 return sensedEntities;
495 fromRegionPos = avatar.AbsolutePosition;
501 double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
502 bool attached = (SensePoint.ParentGroup.AttachmentPoint != 0);
506 Action<ScenePresence> senseEntity =
new Action<ScenePresence>(presence =>
512 if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
514 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
524 if ((ts.type & AGENT) == 0)
532 INPC npcData = m_npcModule.GetNPC(presence.UUID, presence.Scene);
543 if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
548 if (attached && presence.UUID == SensePoint.
OwnerID)
551 toRegionPos = presence.AbsolutePosition;
552 dis = Util.GetDistanceTo(toRegionPos, fromRegionPos);
553 if (presence.IsSatOnObject && presence.ParentPart != null &&
554 presence.ParentPart.ParentGroup != null &&
555 presence.ParentPart.ParentGroup.RootPart != null)
557 Vector3 rpos = presence.ParentPart.ParentGroup.RootPart.AbsolutePosition;
558 double dis2 = Util.GetDistanceTo(rpos, fromRegionPos);
577 if (ts.arc < Math.PI)
590 toRegionPos - fromRegionPos);
591 double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
592 double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
593 ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
598 if (ang_obj <= ts.arc)
600 sensedEntities.Add(
new SensedEntity(dis, presence.UUID));
605 sensedEntities.Add(
new SensedEntity(dis, presence.UUID));
612 if (ts.keyID !=
UUID.Zero)
616 if (!m_CmdManager.m_ScriptEngine.World.TryGetScenePresence(ts.keyID, out sp))
617 return sensedEntities;
620 else if (!
string.IsNullOrEmpty(ts.name))
624 if (((ts.type & AGENT) != 0) && m_CmdManager.m_ScriptEngine.World.TryGetAvatarByName(ts.name, out sp))
626 if ((ts.type & AGENT_BY_USERNAME) != 0)
628 m_CmdManager.m_ScriptEngine.World.ForEachRootScenePresence(
637 if (ssp.
Name.Replace(
" ",
".").ToLower() == ts.name)
643 return sensedEntities;
647 m_CmdManager.m_ScriptEngine.World.ForEachRootScenePresence(senseEntity);
649 return sensedEntities;
654 List<Object> data =
new List<Object>();
660 data.Add(ts.interval);
669 return data.ToArray();
676 m_CmdManager.m_ScriptEngine.World.GetSceneObjectPart(
684 while (idx < data.Length)
688 ts.localID = localID;
691 ts.interval = (double)data[idx];
692 ts.name = (string)data[idx+1];
693 ts.keyID = (
UUID)data[idx+2];
694 ts.type = (int)data[idx+3];
695 ts.range = (double)data[idx+4];
696 ts.arc = (double)data[idx+5];
700 DateTime.Now.ToUniversalTime().AddSeconds(ts.
interval);
702 AddSenseRepeater(ts);
710 List<SensorInfo> retList =
new List<SensorInfo>();
712 lock (SenseRepeatListLock)
715 retList.Add(i.Clone());
IEntityInventory Inventory
This part's inventory
Handles LSL commands that takes long time and returns an event, for example timers, HTTP requests, etc.
void CreateFromData(uint localID, UUID itemID, UUID objectID, Object[] data)
bool SenseAsAgent
Should this NPC be sensed by LSL sensors as an 'agent' (interpreted here to mean a normal user) rathe...
bool ContainsScripts()
Returns true if this inventory contains any scripts
SensorRepeat(AsyncCommandManager CmdManager)
A scene object group is conceptually an object in the scene. The object is constituted of SceneObject...
List< SensorInfo > GetSensorInfo()
void SetSenseRepeatEvent(uint m_localID, UUID m_itemID, string name, UUID keyID, int type, double range, double arc, double sec, SceneObjectPart host)
AsyncCommandManager m_CmdManager
Temporary interface. More methods to come at some point to make NPCs more object oriented rather than...
PresenceType
Indicate the type of ScenePresence.
bool IsDeleted
Signals whether this entity was in a scene but has since been removed from it.
void SenseOnce(uint m_localID, UUID m_itemID, string name, UUID keyID, int type, double range, double arc, SceneObjectPart host)
uint AttachmentPoint
Attachment point of this scene object to an avatar.
void UnSetSenseRepeaterEvents(uint m_localID, UUID m_itemID)
virtual Vector3 Velocity
Current velocity of the entity.
SceneObjectGroup ParentGroup
void CheckSenseRepeaterEvents()
virtual string Name
The name of this entity
Holds all the data required to execute a scripting event.
Used by one-off and repeated sensors
bool IsAttachment
Is this scene object acting as an attachment?
Object[] GetSerializationData(UUID itemID)