From 7837c611fb483dc776b531306d3d791e8f177aab Mon Sep 17 00:00:00 2001 From: "Justin Clark-Casey (justincc)" Date: Sat, 28 Jan 2012 00:00:12 +0000 Subject: [PATCH] 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 --- .../Region/Framework/Interfaces/INPCModule.cs | 34 ++++++++++++++++++- .../OptionalModules/World/NPC/NPCAvatar.cs | 9 +++-- .../OptionalModules/World/NPC/NPCModule.cs | 21 ++++++++++-- .../World/NPC/Tests/NPCModuleTests.cs | 12 +++---- .../Shared/Api/Implementation/OSSL_Api.cs | 14 +++++--- .../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 b428c40a61..2731291ea0 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. @@ -52,6 +76,14 @@ namespace OpenSim.Region.Framework.Interfaces /// True if the agent is an NPC in the given scene. False otherwise. 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 6a6c4c3136..6d40a92e2e 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 d90309f66f..3831d7a416 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 d21d601482..d5078227ef 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 a2f5c921aa..b1583ebb1e 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 8356dced80..3e0e452ce0 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 ab2c543fa0..a69b4cb487 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";