public void llTeleportAgentGlobalCoords(LSL_Key agent, LSL_Vector global_coordinates,
                                                LSL_Vector region_coordinates, LSL_Vector look_at)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }

            UUID invItemID = InventorySelf();

            if (invItemID == UUID.Zero)
            {
                return;
            }

            lock (m_host.TaskInventory) {
                if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
                {
                    Error("llTeleportAgentGlobalCoords", "No permissions to teleport the agent");
                    return;
                }

                if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) == 0)
                {
                    Error("llTeleportAgentGlobalCoords", "No permissions to teleport the agent");
                    return;
                }
            }

            IScenePresence presence = World.GetScenePresence(m_host.OwnerID);

            if (presence != null)
            {
                IEntityTransferModule module = World.RequestModuleInterface <IEntityTransferModule>();
                if (module != null)
                {
                    module.Teleport(presence,
                                    Utils.UIntsToLong((uint)global_coordinates.x, (uint)global_coordinates.y),
                                    region_coordinates.ToVector3(), look_at.ToVector3(),
                                    (uint)TeleportFlags.ViaLocation);
                }
            }
        }
示例#2
0
        public void llNavigateTo(LSL_Vector point, LSL_List options)
        {
            List <Vector3> positions = new List <Vector3>()
            {
                point.ToVector3()
            };
            List <TravelMode> travelMode = new List <TravelMode>()
            {
                TravelMode.Walk
            };
            IBotManager botManager = World.RequestModuleInterface <IBotManager>();
            int         flags      = 0;

            if (options.Length > 0)
            {
                flags |= options.GetLSLIntegerItem(0);
            }
            if (botManager != null)
            {
                botManager.SetBotMap(m_host.ParentEntity.UUID, positions, travelMode, flags, m_host.ParentEntity.OwnerID);
            }
        }
示例#3
0
        public void llPatrolPoints(LSL_List patrolPoints, LSL_List options)
        {
            List <Vector3>    positions  = new List <Vector3>();
            List <TravelMode> travelMode = new List <TravelMode>();

            foreach (object pos in patrolPoints.Data)
            {
                if (!(pos is LSL_Vector))
                {
                    continue;
                }
                LSL_Vector p = (LSL_Vector)pos;
                positions.Add(p.ToVector3());
                travelMode.Add(TravelMode.Walk);
            }
            IBotManager botManager = World.RequestModuleInterface <IBotManager>();

            if (botManager != null)
            {
                botManager.SetBotMap(m_host.ParentEntity.UUID, positions, travelMode, 1, m_host.ParentEntity.OwnerID);
            }
        }
示例#4
0
        public void llSetKeyframedMotion(LSL_List keyframes, LSL_List options)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }
            if (!m_host.IsRoot)
            {
                Error("llSetKeyframedMotion", "Must be used in the root object!");
                return;
            }
            KeyframeAnimation.Data  dataType    = KeyframeAnimation.Data.Both;
            KeyframeAnimation.Modes currentMode = KeyframeAnimation.Modes.Forward;
            for (int i = 0; i < options.Length; i += 2)
            {
                LSL_Integer option = options.GetLSLIntegerItem(i);
                LSL_Integer value  = options.GetLSLIntegerItem(i + 1);
                if (option == ScriptBaseClass.KFM_COMMAND)
                {
                    m_host.ParentEntity.AddKeyframedMotion(null, (KeyframeAnimation.Commands)value.value);
                    break; //Its supposed to be the only option in the list
                }
                if (option == ScriptBaseClass.KFM_MODE)
                {
                    currentMode = (KeyframeAnimation.Modes)value.value;
                }
                else if (option == ScriptBaseClass.KFM_DATA)
                {
                    dataType = (KeyframeAnimation.Data)value.value;
                }
            }
            List <Vector3>    positions = new List <Vector3>();
            List <Quaternion> rotations = new List <Quaternion>();
            List <float>      times     = new List <float>();

            for (int i = 0; i < keyframes.Length; i += (dataType == KeyframeAnimation.Data.Both ? 3 : 2))
            {
                if (dataType == KeyframeAnimation.Data.Both ||
                    dataType == KeyframeAnimation.Data.Translation)
                {
                    LSL_Vector pos = keyframes.GetVector3Item(i);
                    positions.Add(pos.ToVector3());
                }
                if (dataType == KeyframeAnimation.Data.Both ||
                    dataType == KeyframeAnimation.Data.Rotation)
                {
                    LSL_Rotation rot  = keyframes.GetQuaternionItem(i + (dataType == KeyframeAnimation.Data.Both ? 1 : 0));
                    Quaternion   quat = rot.ToQuaternion();
                    quat.Normalize();
                    rotations.Add(quat);
                }
                LSL_Float time = keyframes.GetLSLFloatItem(i + (dataType == KeyframeAnimation.Data.Both ? 2 : 1));
                times.Add((float)time);
            }
            KeyframeAnimation animation = new KeyframeAnimation
            {
                CurrentMode              = currentMode,
                PositionList             = positions.ToArray(),
                RotationList             = rotations.ToArray(),
                TimeList                 = times.ToArray(),
                CurrentAnimationPosition = 0,
                InitialPosition          = m_host.AbsolutePosition,
                InitialRotation          = m_host.GetRotationOffset()
            };

            m_host.ParentEntity.AddKeyframedMotion(animation, KeyframeAnimation.Commands.Play);
        }
示例#5
0
        public LSL_List llGetClosestNavPoint(LSL_Vector point, LSL_List options)
        {
            Vector3 diff = new Vector3(0, 0, 0.1f) *
                           (Vector3.RotationBetween(m_host.ParentEntity.AbsolutePosition, point.ToVector3()));

            return(new LSL_List(new LSL_Vector((m_host.ParentEntity.AbsolutePosition + diff))));
        }
示例#6
0
 public LSL_List llGetClosestNavPoint(LSL_Vector point, LSL_List options)
 {
     Vector3 diff = new Vector3(0, 0, 0.1f) *
                    (Vector3.RotationBetween(m_host.ParentEntity.AbsolutePosition, point.ToVector3()));
     return new LSL_List(new LSL_Vector((m_host.ParentEntity.AbsolutePosition + diff)));
 }
示例#7
0
 public void llNavigateTo(LSL_Vector point, LSL_List options)
 {
     List<Vector3> positions = new List<Vector3>() { point.ToVector3() };
     List<TravelMode> travelMode = new List<TravelMode>() { TravelMode.Walk };
     IBotManager botManager = World.RequestModuleInterface<IBotManager>();
     int flags = 0;
     if (options.Length > 0)
         flags |= options.GetLSLIntegerItem(0);
     if (botManager != null)
         botManager.SetBotMap(m_host.ParentEntity.UUID, positions, travelMode, flags, m_host.ParentEntity.OwnerID);
 }
示例#8
0
        public void osNpcMoveTo(LSL_Key npc, LSL_Vector pos)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.High, "osNpcMoveTo", m_host, "OSSL", m_itemID))
                return;

            IBotManager manager = World.RequestModuleInterface<IBotManager>();
            if (manager != null)
            {
                UUID npcId;
                if (!UUID.TryParse(npc.m_string, out npcId))
                    return;

                manager.WalkTo(npcId, pos.ToVector3(), m_host.OwnerID);
            }
        }
示例#9
0
        public void llTeleportAgentGlobalCoords(LSL_Key agent, LSL_Vector global_coordinates,
                                                LSL_Vector region_coordinates, LSL_Vector look_at)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) 
                return;

            UUID invItemID = InventorySelf();

            if (invItemID == UUID.Zero)
                return;

            lock (m_host.TaskInventory)
            {
                if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
                {
                    Error("llTeleportAgentGlobalCoords", "No permissions to teleport the agent");
                    return;
                }

                if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) == 0)
                {
                    Error("llTeleportAgentGlobalCoords", "No permissions to teleport the agent");
                    return;
                }
            }

            IScenePresence presence = World.GetScenePresence(m_host.OwnerID);
            if (presence != null)
            {
                IEntityTransferModule module = World.RequestModuleInterface<IEntityTransferModule>();
                if (module != null)
                {
                    module.Teleport(presence,
                                    Utils.UIntsToLong((uint)global_coordinates.x, (uint)global_coordinates.y),
                                    region_coordinates.ToVector3(), look_at.ToVector3(),
                                    (uint)TeleportFlags.ViaLocation);
                }
            }
        }
示例#10
0
        public void llTeleportAgent(LSL_Key avatar, LSL_String landmark, LSL_Vector position, LSL_Vector look_at)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) 
                return;

            UUID invItemID = InventorySelf();

            if (invItemID == UUID.Zero)
                return;

            lock (m_host.TaskInventory)
            {
                if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
                {
                    Error("llTeleportAgent", "No permissions to teleport the agent");
                    return;
                }

                if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) == 0)
                {
                    Error("llTeleportAgent", "No permissions to teleport the agent");
                    return;
                }
            }

            TaskInventoryItem item = null;
            lock (m_host.TaskInventory)
            {
                foreach (KeyValuePair<UUID, TaskInventoryItem> inv in m_host.TaskInventory)
                {
                    if (inv.Value.Name == landmark)
                        item = inv.Value;
                }
            }
            if (item == null)
                return;

            IScenePresence presence = World.GetScenePresence(m_host.OwnerID);
            if (presence != null)
            {
                IEntityTransferModule module = World.RequestModuleInterface<IEntityTransferModule>();
                if (module != null)
                {
                    if (landmark != "") {
                        var worldAsset = World.AssetService.Get (item.AssetID.ToString ());
                        if (worldAsset != null) {
                            var lm = new AssetLandmark (worldAsset);
                            worldAsset.Dispose ();

                            module.Teleport (presence, lm.RegionHandle, lm.Position,
                                             look_at.ToVector3 (), (uint)TeleportFlags.ViaLocation);
                            lm.Dispose ();
                            return;

                        }
                    }
                    // no landmark details
                    module.Teleport (presence, World.RegionInfo.RegionHandle,
                                     position.ToVector3 (), look_at.ToVector3 (), (uint)TeleportFlags.ViaLocation);
                    
                }
            }
        }
示例#11
0
        protected void DropAttachmentAt(bool checkPerms, LSL_Vector pos, LSL_Rotation rot)
        {
            if (checkPerms && ShoutErrorOnLackingOwnerPerms(ScriptBaseClass.PERMISSION_ATTACH, "Cannot drop attachment"))
            {
                return;
            }

            IAttachmentsModule attachmentsModule = World.RequestModuleInterface<IAttachmentsModule>();
            IScenePresence sp = attachmentsModule == null ? null : World.GetScenePresence(m_host.OwnerID);

            if (attachmentsModule != null && sp != null)
            {
                attachmentsModule.DetachSingleAttachmentToGround(m_host.ParentEntity.UUID, sp.ControllingClient, pos.ToVector3(), rot.ToQuaternion());
            }
        }
示例#12
0
        // Teleport functions
        public DateTime osTeleportAgent(string agent, int regionX, int regionY, LSL_Vector position, LSL_Vector lookat)
        {
            // High because there is no security check. High griefer potential
            //
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.High, "osTeleportAgent", m_host, "OSSL", m_itemID))
                return DateTime.Now;

            ulong regionHandle = Utils.UIntsToLong(((uint) regionX*Constants.RegionSize),
                                                   ((uint) regionY*Constants.RegionSize));

            UUID agentId = new UUID();
            if (UUID.TryParse(agent, out agentId))
            {
                return TeleportAgent(agentId, regionHandle,
                                     position.ToVector3(),
                                     lookat.ToVector3());
            }
            return DateTime.Now;
        }
示例#13
0
        // Teleport functions
        public DateTime osTeleportAgent(string agent, string regionName, LSL_Vector position, LSL_Vector lookat)
        {
            // High because there is no security check. High griefer potential
            //
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.High, "osTeleportAgent", m_host, "OSSL", m_itemID))
                return DateTime.Now;

            UUID AgentID;
            if (UUID.TryParse(agent, out AgentID))
            {
                List<GridRegion> regions = World.GridService.GetRegionsByName(World.RegionInfo.AllScopeIDs, regionName,
                                                                              0, 1);
                // Try to link the region
                if (regions != null && regions.Count > 0)
                {
                    GridRegion regInfo = regions[0];

                    ulong regionHandle = regInfo.RegionHandle;
                    return TeleportAgent(AgentID, regionHandle,
                                         position.ToVector3(),
                                         lookat.ToVector3());
                }
            }
            return DateTime.Now;
        }
示例#14
0
        public void osNpcMoveToTarget(LSL_Key npc, LSL_Vector target, int options)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.High, "osNpcMoveToTarget", m_host, "OSSL", m_itemID))
                return;

            IBotManager manager = World.RequestModuleInterface<IBotManager>();
            if (manager != null)
            {
                UUID npcId;
                if (!UUID.TryParse(npc.m_string, out npcId))
                    return;

                Vector3 targetPos = target.ToVector3();

                MainConsole.Instance.DebugFormat ("NPC: {0} moving to position: {1}, region: {2}, Options: {3}",
                    npcId, targetPos, World, options);

                manager.MoveToTarget(
                    npcId,
                    targetPos,
                    options,
                    m_host.OwnerID
                );
            }
        }
示例#15
0
        public void llTeleportAgent(LSL_Key avatar, LSL_String landmark, LSL_Vector position, LSL_Vector look_at)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return;
            }

            UUID invItemID = InventorySelf();

            if (invItemID == UUID.Zero)
            {
                return;
            }

            lock (m_host.TaskInventory) {
                if (m_host.TaskInventory[invItemID].PermsGranter == UUID.Zero)
                {
                    Error("llTeleportAgent", "No permissions to teleport the agent");
                    return;
                }

                if ((m_host.TaskInventory[invItemID].PermsMask & ScriptBaseClass.PERMISSION_TELEPORT) == 0)
                {
                    Error("llTeleportAgent", "No permissions to teleport the agent");
                    return;
                }
            }

            TaskInventoryItem item = null;

            lock (m_host.TaskInventory) {
                foreach (KeyValuePair <UUID, TaskInventoryItem> inv in m_host.TaskInventory)
                {
                    if (inv.Value.Name == landmark)
                    {
                        item = inv.Value;
                    }
                }
            }
            if (item == null)
            {
                return;
            }

            IScenePresence presence = World.GetScenePresence(m_host.OwnerID);

            if (presence != null)
            {
                IEntityTransferModule module = World.RequestModuleInterface <IEntityTransferModule>();
                if (module != null)
                {
                    if (landmark != "")
                    {
                        var worldAsset = World.AssetService.Get(item.AssetID.ToString());
                        if (worldAsset != null)
                        {
                            var lm = new AssetLandmark(worldAsset);
                            worldAsset.Dispose();

                            module.Teleport(presence, lm.RegionHandle, lm.Position,
                                            look_at.ToVector3(), (uint)TeleportFlags.ViaLocation);
                            lm.Dispose();
                            return;
                        }
                    }
                    // no landmark details
                    module.Teleport(presence, World.RegionInfo.RegionHandle,
                                    position.ToVector3(), look_at.ToVector3(), (uint)TeleportFlags.ViaLocation);
                }
            }
        }
示例#16
0
        public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
                return new LSL_List();

            LSL_List list = new LSL_List();

            Vector3 rayStart = start.ToVector3();
            Vector3 rayEnd = end.ToVector3();
            Vector3 dir = rayEnd - rayStart;

            float dist = Vector3.Mag(dir);

            int count = 1;
            bool detectPhantom = false;
            int dataFlags = 0;
            int rejectTypes = 0;

            for (int i = 0; i < options.Length; i += 2)
            {
                if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
                    count = options.GetLSLIntegerItem(i + 1);
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
                    detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
                    dataFlags = options.GetLSLIntegerItem(i + 1);
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
                    rejectTypes = options.GetLSLIntegerItem(i + 1);
            }

            if (count > 16)
                count = 16;
            else if (count <= 0)
            {
                Error("llCastRay", "You must request at least one result from llCastRay.");
                return new LSL_List();
            }

            List<ContactResult> results = new List<ContactResult>();

            bool checkTerrain = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
            bool checkAgents = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
            bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
            bool checkPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);


            if (checkAgents)
            {
                ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
                foreach (ContactResult r in agentHits)
                    results.Add(r);
            }

            if (checkPhysical || checkNonPhysical || detectPhantom)
            {
                ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom, count + 2);
                for (int iter = 0; iter < objectHits.Length; iter++)
                {
                    // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler.
                    objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart);
                    results.Add(objectHits[iter]);
                }
            }

            if (checkTerrain)
            {
                ContactResult? groundContact = GroundIntersection(rayStart, rayEnd);
                if (groundContact != null)
                    results.Add((ContactResult)groundContact);
            }

            results.Sort(delegate(ContactResult a, ContactResult b)
            {
                return a.Depth.CompareTo(b.Depth);
            });

            int values = 0;
            ISceneEntity thisgrp = m_host.ParentEntity;

            foreach (ContactResult result in results)
            {
                if (result.Depth > dist)
                    continue;

                // physics ray can return colisions with host prim
                // this is supposed to happen
                if (m_host.LocalId == result.ConsumerID)
                    continue;

                if (!checkTerrain && result.ConsumerID == 0)
                    continue; //Terrain

                UUID itemID = UUID.Zero;
                int linkNum = 0;

                ISceneChildEntity part = World.GetSceneObjectPart(result.ConsumerID);
                // It's a prim!
                if (part != null)
                {
                    // dont detect members of same object ???
                    if (part.ParentEntity == thisgrp)
                        continue;

                    if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
                        itemID = part.ParentEntity.UUID;
                    else
                        itemID = part.UUID;

                    linkNum = part.LinkNum;
                }
                else
                {
                    IScenePresence sp = World.GetScenePresence(result.ConsumerID);
                    /// It it a boy? a girl?
                    if (sp != null)
                        itemID = sp.UUID;
                }

                list.Add(new LSL_String(itemID.ToString()));

                if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
                    list.Add(new LSL_Integer(linkNum));

                list.Add(new LSL_Vector(result.Pos));

                if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
                {
                    Vector3 norm = result.Normal * -1;
                    list.Add(new LSL_Vector(norm));
                }

                values++;
                if (values >= count)
                    break;
            }

            list.Add(new LSL_Integer(values));

            return list;
        }
        public LSL_List llCastRay(LSL_Vector start, LSL_Vector end, LSL_List options)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID))
            {
                return(new LSL_List());
            }

            LSL_List list = new LSL_List();

            Vector3 rayStart = start.ToVector3();
            Vector3 rayEnd   = end.ToVector3();
            Vector3 dir      = rayEnd - rayStart;

            float dist = Vector3.Mag(dir);

            int  count         = 1;
            bool detectPhantom = false;
            int  dataFlags     = 0;
            int  rejectTypes   = 0;

            for (int i = 0; i < options.Length; i += 2)
            {
                if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_MAX_HITS)
                {
                    count = options.GetLSLIntegerItem(i + 1);
                }
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DETECT_PHANTOM)
                {
                    detectPhantom = (options.GetLSLIntegerItem(i + 1) > 0);
                }
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_DATA_FLAGS)
                {
                    dataFlags = options.GetLSLIntegerItem(i + 1);
                }
                else if (options.GetLSLIntegerItem(i) == ScriptBaseClass.RC_REJECT_TYPES)
                {
                    rejectTypes = options.GetLSLIntegerItem(i + 1);
                }
            }

            if (count > 16)
            {
                count = 16;
            }
            else if (count <= 0)
            {
                Error("llCastRay", "You must request at least one result from llCastRay.");
                return(new LSL_List());
            }

            List <ContactResult> results = new List <ContactResult>();

            bool checkTerrain     = !((rejectTypes & ScriptBaseClass.RC_REJECT_LAND) == ScriptBaseClass.RC_REJECT_LAND);
            bool checkAgents      = !((rejectTypes & ScriptBaseClass.RC_REJECT_AGENTS) == ScriptBaseClass.RC_REJECT_AGENTS);
            bool checkNonPhysical = !((rejectTypes & ScriptBaseClass.RC_REJECT_NONPHYSICAL) == ScriptBaseClass.RC_REJECT_NONPHYSICAL);
            bool checkPhysical    = !((rejectTypes & ScriptBaseClass.RC_REJECT_PHYSICAL) == ScriptBaseClass.RC_REJECT_PHYSICAL);


            if (checkAgents)
            {
                ContactResult[] agentHits = AvatarIntersection(rayStart, rayEnd);
                foreach (ContactResult r in agentHits)
                {
                    results.Add(r);
                }
            }

            if (checkPhysical || checkNonPhysical || detectPhantom)
            {
                ContactResult[] objectHits = ObjectIntersection(rayStart, rayEnd, checkPhysical, checkNonPhysical, detectPhantom, count + 2);
                for (int iter = 0; iter < objectHits.Length; iter++)
                {
                    // Redistance the Depth because the Scene RayCaster returns distance from center to make the rezzing code simpler.
                    objectHits[iter].Depth = Vector3.Distance(objectHits[iter].Pos, rayStart);
                    results.Add(objectHits[iter]);
                }
            }

            if (checkTerrain)
            {
                ContactResult?groundContact = GroundIntersection(rayStart, rayEnd);
                if (groundContact != null)
                {
                    results.Add((ContactResult)groundContact);
                }
            }

            results.Sort(delegate(ContactResult a, ContactResult b) {
                return(a.Depth.CompareTo(b.Depth));
            });

            int          values  = 0;
            ISceneEntity thisgrp = m_host.ParentEntity;

            foreach (ContactResult result in results)
            {
                if (result.Depth > dist)
                {
                    continue;
                }

                // physics ray can return colisions with host prim
                // this is supposed to happen
                if (m_host.LocalId == result.ConsumerID)
                {
                    continue;
                }

                if (!checkTerrain && result.ConsumerID == 0)
                {
                    continue; //Terrain
                }
                UUID itemID  = UUID.Zero;
                int  linkNum = 0;

                ISceneChildEntity part = World.GetSceneObjectPart(result.ConsumerID);
                // It's a prim!
                if (part != null)
                {
                    // dont detect members of same object ???
                    if (part.ParentEntity == thisgrp)
                    {
                        continue;
                    }

                    if ((dataFlags & ScriptBaseClass.RC_GET_ROOT_KEY) == ScriptBaseClass.RC_GET_ROOT_KEY)
                    {
                        itemID = part.ParentEntity.UUID;
                    }
                    else
                    {
                        itemID = part.UUID;
                    }

                    linkNum = part.LinkNum;
                }
                else
                {
                    IScenePresence sp = World.GetScenePresence(result.ConsumerID);
                    /// It it a boy? a girl?
                    if (sp != null)
                    {
                        itemID = sp.UUID;
                    }
                }

                list.Add(new LSL_String(itemID.ToString()));

                if ((dataFlags & ScriptBaseClass.RC_GET_LINK_NUM) == ScriptBaseClass.RC_GET_LINK_NUM)
                {
                    list.Add(new LSL_Integer(linkNum));
                }

                list.Add(new LSL_Vector(result.Pos));

                if ((dataFlags & ScriptBaseClass.RC_GET_NORMAL) == ScriptBaseClass.RC_GET_NORMAL)
                {
                    Vector3 norm = result.Normal * -1;
                    list.Add(new LSL_Vector(norm));
                }

                values++;
                if (values >= count)
                {
                    break;
                }
            }

            list.Add(new LSL_Integer(values));

            return(list);
        }