Mantis 6063 osNpcTouch.

Allow NPCS to touch obects.
0.7.4.1
Talun 2012-07-03 11:10:09 +01:00 committed by Justin Clark-Casey (justincc)
parent 43a2da9edb
commit 1b1f841c6a
6 changed files with 98 additions and 0 deletions

View File

@ -183,6 +183,14 @@ namespace OpenSim.Region.Framework.Interfaces
/// <returns>true if the stand succeeded, false if not</returns> /// <returns>true if the stand succeeded, false if not</returns>
bool Stand(UUID agentID, Scene scene); bool Stand(UUID agentID, Scene scene);
/// <summary>
/// Get the NPC to touch an object.
/// </summary>
/// <param name="agentID"></param>
/// <param name="partID"></param>
/// <returns>true if the touch is actually attempted, false if not</returns>
bool Touch(UUID agentID, UUID partID);
/// <summary> /// <summary>
/// Delete an NPC. /// Delete an NPC.
/// </summary> /// </summary>

View File

@ -104,6 +104,45 @@ namespace OpenSim.Region.OptionalModules.World.NPC
OnMoneyTransferRequest(m_uuid, target, amount, 1, "Payment"); OnMoneyTransferRequest(m_uuid, target, amount, 1, "Payment");
} }
public bool Touch(UUID target)
{
SceneObjectPart part = m_scene.GetSceneObjectPart(target);
if (part == null)
return false;
bool objectTouchable = hasTouchEvents(part); // Only touch an object that is scripted to respond
if (!objectTouchable && !part.IsRoot)
objectTouchable = hasTouchEvents(part.ParentGroup.RootPart);
if (!objectTouchable)
return false;
// Set up the surface args as if the touch is from a client that does not support this
SurfaceTouchEventArgs surfaceArgs = new SurfaceTouchEventArgs();
surfaceArgs.FaceIndex = -1; // TOUCH_INVALID_FACE
surfaceArgs.Binormal = Vector3.Zero; // TOUCH_INVALID_VECTOR
surfaceArgs.Normal = Vector3.Zero; // TOUCH_INVALID_VECTOR
surfaceArgs.STCoord = new Vector3(-1.0f, -1.0f, 0.0f); // TOUCH_INVALID_TEXCOORD
surfaceArgs.UVCoord = surfaceArgs.STCoord; // TOUCH_INVALID_TEXCOORD
List<SurfaceTouchEventArgs> touchArgs = new List<SurfaceTouchEventArgs>();
touchArgs.Add(surfaceArgs);
Vector3 offset = part.OffsetPosition * -1.0f;
if (OnGrabObject == null)
return false;
OnGrabObject(part.LocalId, offset, this, touchArgs);
if (OnGrabUpdate != null)
OnGrabUpdate(part.UUID, offset, part.ParentGroup.RootPart.GroupPosition, this, touchArgs);
if (OnDeGrabObject != null)
OnDeGrabObject(part.LocalId, this, touchArgs);
return true;
}
private bool hasTouchEvents(SceneObjectPart part)
{
if ((part.ScriptEvents & scriptEvents.touch) != 0 ||
(part.ScriptEvents & scriptEvents.touch_start) != 0 ||
(part.ScriptEvents & scriptEvents.touch_end) != 0)
return true;
return false;
}
public void InstantMessage(UUID target, string message) public void InstantMessage(UUID target, string message)
{ {
OnInstantMessage(this, new GridInstantMessage(m_scene, OnInstantMessage(this, new GridInstantMessage(m_scene,

View File

@ -305,6 +305,16 @@ namespace OpenSim.Region.OptionalModules.World.NPC
return false; return false;
} }
public bool Touch(UUID agentID, UUID objectID)
{
lock (m_avatars)
{
if (m_avatars.ContainsKey(agentID))
return m_avatars[agentID].Touch(objectID);
return false;
}
}
public UUID GetOwner(UUID agentID) public UUID GetOwner(UUID agentID)
{ {
lock (m_avatars) lock (m_avatars)

View File

@ -2677,6 +2677,41 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
} }
public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num)
{
CheckThreatLevel(ThreatLevel.High, "osNpcTouch");
m_host.AddScriptLPS(1);
INPCModule module = World.RequestModuleInterface<INPCModule>();
int linkNum = link_num.value;
if (module != null || (linkNum < 0 && linkNum != ScriptBaseClass.LINK_THIS))
{
UUID npcId;
if (!UUID.TryParse(npcLSL_Key, out npcId) || !module.CheckPermissions(npcId, m_host.OwnerID))
return;
SceneObjectPart part = null;
UUID objectId;
if (UUID.TryParse(LSL_String.ToString(object_key), out objectId))
part = World.GetSceneObjectPart(objectId);
if (part == null)
return;
if (linkNum != ScriptBaseClass.LINK_THIS)
{
if (linkNum == 0 || linkNum == ScriptBaseClass.LINK_ROOT)
{ // 0 and 1 are treated as root, find the root if the current part isnt it
if (!part.IsRoot)
part = part.ParentGroup.RootPart;
}
else
{ // Find the prim with the given link number if not found then fail silently
part = part.ParentGroup.GetLinkNumPart(linkNum);
if (part == null)
return;
}
}
module.Touch(npcId, part.UUID);
}
}
/// <summary> /// <summary>
/// Save the current appearance of the script owner permanently to the named notecard. /// Save the current appearance of the script owner permanently to the named notecard.
/// </summary> /// </summary>

View File

@ -231,6 +231,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
void osNpcRemove(key npc); void osNpcRemove(key npc);
void osNpcPlayAnimation(LSL_Key npc, string animation); void osNpcPlayAnimation(LSL_Key npc, string animation);
void osNpcStopAnimation(LSL_Key npc, string animation); void osNpcStopAnimation(LSL_Key npc, string animation);
void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num);
void osNpcWhisper(key npc, int channel, string message); void osNpcWhisper(key npc, int channel, string message);
LSL_Key osOwnerSaveAppearance(string notecard); LSL_Key osOwnerSaveAppearance(string notecard);

View File

@ -626,6 +626,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
m_OSSL_Functions.osNpcWhisper(npc, channel, message); m_OSSL_Functions.osNpcWhisper(npc, channel, message);
} }
public void osNpcTouch(LSL_Key npcLSL_Key, LSL_Key object_key, LSL_Integer link_num)
{
m_OSSL_Functions.osNpcTouch(npcLSL_Key, object_key, link_num);
}
public LSL_Key osOwnerSaveAppearance(string notecard) public LSL_Key osOwnerSaveAppearance(string notecard)
{ {
return m_OSSL_Functions.osOwnerSaveAppearance(notecard); return m_OSSL_Functions.osOwnerSaveAppearance(notecard);