From 7837c611fb483dc776b531306d3d791e8f177aab Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Sat, 28 Jan 2012 00:00:12 +0000
Subject: Add OS_NPC_SENSE_AS_AGENT option to osNpcCreate().
This allows NPCs to be sensed as agents by LSL sensors rather than as a specific NPC type (which is currently an OpenSimulator-only extension).
Wiki doc on this and other recent NPC functions will follow soon
---
OpenSim/Region/Framework/Interfaces/INPCModule.cs | 34 +++++++++++++++++++++-
.../Region/OptionalModules/World/NPC/NPCAvatar.cs | 9 ++++--
.../Region/OptionalModules/World/NPC/NPCModule.cs | 21 +++++++++++--
.../World/NPC/Tests/NPCModuleTests.cs | 12 ++++----
.../Shared/Api/Implementation/OSSL_Api.cs | 14 ++++++---
.../Api/Implementation/Plugins/SensorRepeat.cs | 9 ++++--
.../Shared/Api/Runtime/LSL_Constants.cs | 1 +
7 files changed, 83 insertions(+), 17 deletions(-)
diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
index b428c40..2731291 100644
--- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs
+++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs
@@ -31,6 +31,19 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces
{
+ ///
+ /// Temporary interface. More methods to come at some point to make NPCs more object oriented rather than
+ /// controlling purely through module level interface calls (e.g. sit/stand).
+ ///
+ public interface INPC
+ {
+ ///
+ /// Should this NPC be sensed by LSL sensors as an 'agent' (interpreted here to mean a normal user)
+ /// rather than an OpenSim specific NPC extension?
+ ///
+ bool SenseAsAgent { get; }
+ }
+
public interface INPCModule
{
///
@@ -39,10 +52,21 @@ namespace OpenSim.Region.Framework.Interfaces
///
///
///
+ ///
+ /// Make the NPC show up as an agent on LSL sensors. The default is that they
+ /// show up as the NPC type instead, but this is currently an OpenSim-only extension.
+ ///
///
/// The avatar appearance to use for the new NPC.
/// The UUID of the ScenePresence created.
- UUID CreateNPC(string firstname, string lastname, Vector3 position, UUID owner, Scene scene, AvatarAppearance appearance);
+ UUID CreateNPC(
+ string firstname,
+ string lastname,
+ Vector3 position,
+ UUID owner,
+ bool senseAsAgent,
+ Scene scene,
+ AvatarAppearance appearance);
///
/// Check if the agent is an NPC.
@@ -53,6 +77,14 @@ namespace OpenSim.Region.Framework.Interfaces
bool IsNPC(UUID agentID, Scene scene);
///
+ /// Get the NPC. This is not currently complete - manipulation of NPCs still occurs through the region interface
+ ///
+ ///
+ ///
+ /// The NPC. null if it does not exist.
+ INPC GetNPC(UUID agentID, Scene scene);
+
+ ///
/// Check if the caller has permission to manipulate the given NPC.
///
///
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index 6a6c4c3..6d40a92 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -31,13 +31,16 @@ using System.Net;
using OpenMetaverse;
using OpenMetaverse.Packets;
using OpenSim.Framework;
+using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.CoreModules.World.Estate;
namespace OpenSim.Region.OptionalModules.World.NPC
{
- public class NPCAvatar : IClientAPI
+ public class NPCAvatar : IClientAPI, INPC
{
+ public bool SenseAsAgent { get; set; }
+
private readonly string m_firstname;
private readonly string m_lastname;
private readonly Vector3 m_startPos;
@@ -45,13 +48,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
private readonly Scene m_scene;
private readonly UUID m_ownerID;
- public NPCAvatar(string firstname, string lastname, Vector3 position, UUID ownerID, Scene scene)
+ public NPCAvatar(
+ string firstname, string lastname, Vector3 position, UUID ownerID, bool senseAsAgent, Scene scene)
{
m_firstname = firstname;
m_lastname = lastname;
m_startPos = position;
m_scene = scene;
m_ownerID = ownerID;
+ SenseAsAgent = senseAsAgent;
}
public IScene Scene
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
index d90309f..3831d7a 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCModule.cs
@@ -109,9 +109,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
}
public UUID CreateNPC(
- string firstname, string lastname, Vector3 position, UUID owner, Scene scene, AvatarAppearance appearance)
+ string firstname,
+ string lastname,
+ Vector3 position,
+ UUID owner,
+ bool senseAsAgent,
+ Scene scene,
+ AvatarAppearance appearance)
{
- NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, owner, scene);
+ NPCAvatar npcAvatar = new NPCAvatar(firstname, lastname, position, owner, senseAsAgent, scene);
npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
m_log.DebugFormat(
@@ -266,6 +272,17 @@ namespace OpenSim.Region.OptionalModules.World.NPC
return UUID.Zero;
}
+ public INPC GetNPC(UUID agentID, Scene scene)
+ {
+ lock (m_avatars)
+ {
+ if (m_avatars.ContainsKey(agentID))
+ return m_avatars[agentID];
+ else
+ return null;
+ }
+ }
+
public bool DeleteNPC(UUID agentID, Scene scene)
{
lock (m_avatars)
diff --git a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
index d21d601..d507822 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/Tests/NPCModuleTests.cs
@@ -109,7 +109,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
afm.SetAppearance(sp, originalTe, null);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
@@ -129,7 +129,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(128, 128, 30);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
npcModule.DeleteNPC(npcId, scene);
@@ -157,7 +157,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
@@ -189,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(128, 128, 30);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos));
@@ -260,7 +260,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(128, 128, 30);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
@@ -293,7 +293,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(1, 1, 1);
INPCModule npcModule = scene.RequestModuleInterface();
- UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, scene, sp.Appearance);
+ UUID npcId = npcModule.CreateNPC("John", "Smith", startPos, UUID.Zero, true, scene, sp.Appearance);
ScenePresence npc = scene.GetScenePresence(npcId);
SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index a2f5c92..b1583eb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -2233,7 +2233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
m_host.AddScriptLPS(1);
- return NpcCreate(firstname, lastname, position, notecard, true);
+ return NpcCreate(firstname, lastname, position, notecard, false, true);
}
public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options)
@@ -2241,10 +2241,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
m_host.AddScriptLPS(1);
- return NpcCreate(firstname, lastname, position, notecard, (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0);
+ return NpcCreate(
+ firstname, lastname, position, notecard,
+ (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0,
+ (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) == 0);
}
- private LSL_Key NpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, bool owned)
+ private LSL_Key NpcCreate(
+ string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent)
{
INPCModule module = World.RequestModuleInterface();
if (module != null)
@@ -2281,7 +2285,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
lastname,
new Vector3((float) position.x, (float) position.y, (float) position.z),
ownerID,
- World,appearance);
+ senseAsAgent,
+ World,
+ appearance);
return new LSL_Key(x.ToString());
}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
index 8356dce..3e0e452 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/Plugins/SensorRepeat.cs
@@ -447,9 +447,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
Action senseEntity = new Action(delegate(ScenePresence presence)
{
- if ((ts.type & NPC) == 0 && presence.PresenceType == PresenceType.Npc)
+ if ((ts.type & NPC) == 0
+ && presence.PresenceType == PresenceType.Npc
+ && !npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent)
return;
- if ((ts.type & AGENT) == 0 && presence.PresenceType == PresenceType.User)
+
+ if ((ts.type & AGENT) == 0
+ && (presence.PresenceType == PresenceType.User
+ || npcModule.GetNPC(presence.UUID, presence.Scene).SenseAsAgent))
return;
if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index ab2c543..a69b4cb 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -616,6 +616,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int OS_NPC_CREATOR_OWNED = 0x1;
public const int OS_NPC_NOT_OWNED = 0x2;
+ public const int OS_NPC_SENSE_AS_AGENT = 0x4;
public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED";
public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED";
--
cgit v1.1