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
iar_mods
Justin Clark-Casey (justincc) 2012-01-28 00:00:12 +00:00
parent 31b87ff07b
commit 7837c611fb
7 changed files with 83 additions and 17 deletions

View File

@ -31,6 +31,19 @@ using OpenSim.Region.Framework.Scenes;
namespace OpenSim.Region.Framework.Interfaces namespace OpenSim.Region.Framework.Interfaces
{ {
/// <summary>
/// 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).
/// </summary>
public interface INPC
{
/// <summary>
/// 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?
/// </summary>
bool SenseAsAgent { get; }
}
public interface INPCModule public interface INPCModule
{ {
/// <summary> /// <summary>
@ -39,10 +52,21 @@ namespace OpenSim.Region.Framework.Interfaces
/// <param name="firstname"></param> /// <param name="firstname"></param>
/// <param name="lastname"></param> /// <param name="lastname"></param>
/// <param name="position"></param> /// <param name="position"></param>
/// <param name="senseAsAgent">
/// 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.
/// </param>
/// <param name="scene"></param> /// <param name="scene"></param>
/// <param name="appearance">The avatar appearance to use for the new NPC.</param> /// <param name="appearance">The avatar appearance to use for the new NPC.</param>
/// <returns>The UUID of the ScenePresence created.</returns> /// <returns>The UUID of the ScenePresence created.</returns>
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);
/// <summary> /// <summary>
/// Check if the agent is an NPC. /// Check if the agent is an NPC.
@ -52,6 +76,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns>True if the agent is an NPC in the given scene. False otherwise.</returns> /// <returns>True if the agent is an NPC in the given scene. False otherwise.</returns>
bool IsNPC(UUID agentID, Scene scene); bool IsNPC(UUID agentID, Scene scene);
/// <summary>
/// Get the NPC. This is not currently complete - manipulation of NPCs still occurs through the region interface
/// </summary>
/// <param name="agentID"></param>
/// <param name="scene"></param>
/// <returns>The NPC. null if it does not exist.</returns>
INPC GetNPC(UUID agentID, Scene scene);
/// <summary> /// <summary>
/// Check if the caller has permission to manipulate the given NPC. /// Check if the caller has permission to manipulate the given NPC.
/// </summary> /// </summary>

View File

@ -31,13 +31,16 @@ using System.Net;
using OpenMetaverse; using OpenMetaverse;
using OpenMetaverse.Packets; using OpenMetaverse.Packets;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes; using OpenSim.Region.Framework.Scenes;
using OpenSim.Region.CoreModules.World.Estate; using OpenSim.Region.CoreModules.World.Estate;
namespace OpenSim.Region.OptionalModules.World.NPC 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_firstname;
private readonly string m_lastname; private readonly string m_lastname;
private readonly Vector3 m_startPos; private readonly Vector3 m_startPos;
@ -45,13 +48,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
private readonly Scene m_scene; private readonly Scene m_scene;
private readonly UUID m_ownerID; 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_firstname = firstname;
m_lastname = lastname; m_lastname = lastname;
m_startPos = position; m_startPos = position;
m_scene = scene; m_scene = scene;
m_ownerID = ownerID; m_ownerID = ownerID;
SenseAsAgent = senseAsAgent;
} }
public IScene Scene public IScene Scene

View File

@ -109,9 +109,15 @@ namespace OpenSim.Region.OptionalModules.World.NPC
} }
public UUID CreateNPC( 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); npcAvatar.CircuitCode = (uint)Util.RandomClass.Next(0, int.MaxValue);
m_log.DebugFormat( m_log.DebugFormat(
@ -266,6 +272,17 @@ namespace OpenSim.Region.OptionalModules.World.NPC
return UUID.Zero; 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) public bool DeleteNPC(UUID agentID, Scene scene)
{ {
lock (m_avatars) lock (m_avatars)

View File

@ -109,7 +109,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
afm.SetAppearance(sp, originalTe, null); afm.SetAppearance(sp, originalTe, null);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
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); ScenePresence npc = scene.GetScenePresence(npcId);
@ -129,7 +129,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(128, 128, 30); Vector3 startPos = new Vector3(128, 128, 30);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
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); npcModule.DeleteNPC(npcId, scene);
@ -157,7 +157,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest); am.RezSingleAttachmentFromInventory(sp, attItemId, (uint)AttachmentPoint.Chest);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
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); ScenePresence npc = scene.GetScenePresence(npcId);
@ -189,7 +189,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(128, 128, 30); Vector3 startPos = new Vector3(128, 128, 30);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
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); ScenePresence npc = scene.GetScenePresence(npcId);
Assert.That(npc.AbsolutePosition, Is.EqualTo(startPos)); 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); Vector3 startPos = new Vector3(128, 128, 30);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
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); ScenePresence npc = scene.GetScenePresence(npcId);
SceneObjectPart part = SceneHelpers.AddSceneObject(scene); SceneObjectPart part = SceneHelpers.AddSceneObject(scene);
@ -293,7 +293,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
Vector3 startPos = new Vector3(1, 1, 1); Vector3 startPos = new Vector3(1, 1, 1);
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
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); ScenePresence npc = scene.GetScenePresence(npcId);
SceneObjectPart part = SceneHelpers.AddSceneObject(scene); SceneObjectPart part = SceneHelpers.AddSceneObject(scene);

View File

@ -2233,7 +2233,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
CheckThreatLevel(ThreatLevel.High, "osNpcCreate"); CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
m_host.AddScriptLPS(1); 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) 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"); CheckThreatLevel(ThreatLevel.High, "osNpcCreate");
m_host.AddScriptLPS(1); 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<INPCModule>(); INPCModule module = World.RequestModuleInterface<INPCModule>();
if (module != null) if (module != null)
@ -2281,7 +2285,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
lastname, lastname,
new Vector3((float) position.x, (float) position.y, (float) position.z), new Vector3((float) position.x, (float) position.y, (float) position.z),
ownerID, ownerID,
World,appearance); senseAsAgent,
World,
appearance);
return new LSL_Key(x.ToString()); return new LSL_Key(x.ToString());
} }

View File

@ -447,9 +447,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
Action<ScenePresence> senseEntity = new Action<ScenePresence>(delegate(ScenePresence presence) Action<ScenePresence> senseEntity = new Action<ScenePresence>(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; 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; return;
if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0) if (presence.IsDeleted || presence.IsChildAgent || presence.GodLevel > 0.0)

View File

@ -616,6 +616,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
public const int OS_NPC_CREATOR_OWNED = 0x1; public const int OS_NPC_CREATOR_OWNED = 0x1;
public const int OS_NPC_NOT_OWNED = 0x2; 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_GRANTED = "URL_REQUEST_GRANTED";
public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED"; public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED";