diff --git a/OpenSim/Region/Framework/Interfaces/INPCModule.cs b/OpenSim/Region/Framework/Interfaces/INPCModule.cs index 8f9a13cc6a..a40f150934 100644 --- a/OpenSim/Region/Framework/Interfaces/INPCModule.cs +++ b/OpenSim/Region/Framework/Interfaces/INPCModule.cs @@ -38,7 +38,8 @@ namespace OpenSim.Region.Framework.Interfaces AllowNotOwned = 0x01, // allow NPCs to be created not Owned AllowSenseAsAvatar = 0x02, // allow NPCs to set to be sensed as Avatars AllowCloneOtherAvatars = 0x04, // allow NPCs to created cloning a avatar in region - NoNPCGroup = 0x08 // NPCs will have no group title, otherwise will have "- NPC -" + NoNPCGroup = 0x08, // NPCs will have no group title, otherwise will have "- NPC -" + objectGroup = 0x10 // NPC will have host sog groupID } /// @@ -48,12 +49,14 @@ namespace OpenSim.Region.Framework.Interfaces /// 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; } + UUID ActiveGroupId { get; set; } } public interface INPCModule diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs index 7228348b9a..d966fe5592 100644 --- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs +++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs @@ -64,6 +64,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC private UUID m_uuid = UUID.Random(); private readonly Scene m_scene; private readonly UUID m_ownerID; + private UUID m_hostGroupID; public List SelectedObjects {get; private set;} @@ -77,6 +78,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC m_scene = scene; m_ownerID = ownerID; SenseAsAgent = senseAsAgent; + m_hostGroupID = UUID.Zero; } public NPCAvatar( @@ -89,6 +91,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC m_scene = scene; m_ownerID = ownerID; SenseAsAgent = senseAsAgent; + m_hostGroupID = UUID.Zero; } public IScene Scene @@ -576,7 +579,8 @@ namespace OpenSim.Region.OptionalModules.World.NPC } public UUID ActiveGroupId { - get { return UUID.Zero; } + get { return m_hostGroupID; } + set { m_hostGroupID = value; } } public string ActiveGroupName @@ -591,7 +595,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC public bool IsGroupMember(UUID groupID) { - return false; + return (m_hostGroupID == groupID); } public ulong GetGroupPowers(UUID groupID) diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index c863528a81..bda323a85c 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -2593,7 +2593,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api bool owned = (module.NPCOptionFlags & NPCOptionsFlags.AllowNotOwned) == 0; - return NpcCreate(firstname, lastname, position, notecard, owned, false); + return NpcCreate(firstname, lastname, position, notecard, owned, false, false); } public LSL_Key osNpcCreate(string firstname, string lastname, LSL_Vector position, string notecard, int options) @@ -2604,101 +2604,128 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return NpcCreate( firstname, lastname, position, notecard, (options & ScriptBaseClass.OS_NPC_NOT_OWNED) == 0, - (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0); + (options & ScriptBaseClass.OS_NPC_SENSE_AS_AGENT) != 0, + (options & ScriptBaseClass.OS_NPC_OBJECT_GROUP) != 0); } private LSL_Key NpcCreate( - string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent) + string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent, bool hostGroupID) { if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z))) return new LSL_Key(UUID.Zero.ToString()); INPCModule module = World.RequestModuleInterface(); - if (module != null) + if(module == null) + new LSL_Key(UUID.Zero.ToString()); + + string groupTitle = String.Empty; + UUID groupID = UUID.Zero; + + AvatarAppearance appearance = null; + + // check creation options + NPCOptionsFlags createFlags = module.NPCOptionFlags; + + if((createFlags & NPCOptionsFlags.AllowNotOwned) == 0 && !owned) { - string groupTitle = String.Empty; - AvatarAppearance appearance = null; - - // check creation options - NPCOptionsFlags createFlags = module.NPCOptionFlags; - - if((createFlags & NPCOptionsFlags.AllowNotOwned) == 0 && !owned) - { - OSSLError("Not owned NPCs disabled"); - owned = true; // we should get here... - } - - if((createFlags & NPCOptionsFlags.AllowSenseAsAvatar) == 0 && senseAsAgent) - { - OSSLError("NPC allow sense as Avatar disabled"); - senseAsAgent = false; - } - - if((createFlags & NPCOptionsFlags.NoNPCGroup) == 0) - { - if (firstname != String.Empty || lastname != String.Empty) - { - if (firstname != "Shown outfit:") - groupTitle = "- NPC -"; - } - } - - if((createFlags & NPCOptionsFlags.AllowCloneOtherAvatars) != 0) - { - UUID id; - if (UUID.TryParse(notecard, out id)) - { - ScenePresence clonePresence = World.GetScenePresence(id); - if (clonePresence != null) - appearance = clonePresence.Appearance; - } - } - - if (appearance == null) - { - string appearanceSerialized = LoadNotecard(notecard); - - if (appearanceSerialized != null) - { - try - { - OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); - appearance = new AvatarAppearance(); - appearance.Unpack(appearanceOsd); - } - catch - { - return UUID.Zero.ToString(); - } - } - else - { - OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard)); - } - } - - UUID ownerID = UUID.Zero; - if (owned) - ownerID = m_host.OwnerID; - UUID x = module.CreateNPC(firstname, - lastname, - position, - ownerID, - senseAsAgent, - World, - appearance); - - ScenePresence sp; - if (World.TryGetScenePresence(x, out sp)) - { - sp.Grouptitle = groupTitle; - sp.SendAvatarDataToAllAgents(); - } - return new LSL_Key(x.ToString()); + OSSLError("Not owned NPCs disabled"); + owned = true; // we should get here... } - return new LSL_Key(UUID.Zero.ToString()); + if((createFlags & NPCOptionsFlags.AllowSenseAsAvatar) == 0 && senseAsAgent) + { + OSSLError("NPC allow sense as Avatar disabled"); + senseAsAgent = false; + } + + if(hostGroupID && m_host.GroupID != UUID.Zero) + { + IGroupsModule groupsModule = m_ScriptEngine.World.RequestModuleInterface(); + if (groupsModule != null) + { + GroupMembershipData member = groupsModule.GetMembershipData(m_host.GroupID, m_host.OwnerID); + if (member == null) + { + OSSLError(string.Format("osNpcCreate: the object owner is not member of the object group")); + return new LSL_Key(UUID.Zero.ToString()); + } + + groupID = m_host.GroupID; + + if((createFlags & NPCOptionsFlags.NoNPCGroup) != 0) + { + GroupRecord grprec = groupsModule.GetGroupRecord(m_host.GroupID); + if(grprec != null && grprec.GroupName != "") + groupTitle = grprec.GroupName; + } + } + } + + if((createFlags & NPCOptionsFlags.NoNPCGroup) == 0) + { + if (firstname != String.Empty || lastname != String.Empty) + { + if (firstname != "Shown outfit:") + groupTitle = "- NPC -"; + } + } + + if((createFlags & NPCOptionsFlags.AllowCloneOtherAvatars) != 0) + { + UUID id; + if (UUID.TryParse(notecard, out id)) + { + ScenePresence clonePresence = World.GetScenePresence(id); + if (clonePresence != null) + appearance = clonePresence.Appearance; + } + } + + if (appearance == null) + { + string appearanceSerialized = LoadNotecard(notecard); + + if (appearanceSerialized != null) + { + try + { + OSDMap appearanceOsd = (OSDMap)OSDParser.DeserializeLLSDXml(appearanceSerialized); + appearance = new AvatarAppearance(); + appearance.Unpack(appearanceOsd); + } + catch + { + OSSLError(string.Format("osNpcCreate: Error processing notcard '{0}'", notecard)); + return new LSL_Key(UUID.Zero.ToString()); + } + } + else + { + OSSLError(string.Format("osNpcCreate: Notecard reference '{0}' not found.", notecard)); + } + } + + UUID ownerID = UUID.Zero; + if (owned) + ownerID = m_host.OwnerID; + UUID x = module.CreateNPC(firstname, + lastname, + position, + ownerID, + senseAsAgent, + World, + appearance); + + ScenePresence sp; + if (World.TryGetScenePresence(x, out sp)) + { + sp.Grouptitle = groupTitle; + ((INPC)(sp.ControllingClient)).ActiveGroupId = groupID; + + sp.SendAvatarDataToAllAgents(); + } + return new LSL_Key(x.ToString()); } /// diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs index 158acc6aa9..4a8e885c59 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs @@ -763,6 +763,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 int OS_NPC_OBJECT_GROUP = 0x08; public const string URL_REQUEST_GRANTED = "URL_REQUEST_GRANTED"; public const string URL_REQUEST_DENIED = "URL_REQUEST_DENIED";