Aurora.ScriptEngine.AuroraDotNetEngine.APIs.LSL_Api.llPushObject C# (CSharp) Метод

llPushObject() публичный Метод

public llPushObject ( string target, Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3 impulse, Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3 ang_impulse, int local ) : void
target string
impulse Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3
ang_impulse Aurora.ScriptEngine.AuroraDotNetEngine.LSL_Types.Vector3
local int
Результат void
        public void llPushObject(string target, LSL_Vector impulse, LSL_Vector ang_impulse, int local)
        {
            if (!ScriptProtection.CheckThreatLevel(ThreatLevel.None, "LSL", m_host, "LSL", m_itemID)) return;

            bool pushAllowed = false;

            bool pusheeIsAvatar = false;
            UUID targetID = UUID.Zero;

            if (!UUID.TryParse(target, out targetID))
                return;

            IScenePresence pusheeav = null;
            Vector3 PusheePos = Vector3.Zero;
            ISceneChildEntity pusheeob = null;

            IScenePresence avatar = World.GetScenePresence(targetID);
            if (avatar != null)
            {
                pusheeIsAvatar = true;

                // Pushee is in GodMode this pushing object isn't owned by them
                if (avatar.GodLevel > 0 && m_host.OwnerID != targetID)
                    return;

                pusheeav = avatar;

                // Find pushee position
                // Pushee Linked?
                if (pusheeav.ParentID != UUID.Zero)
                {
                    ISceneChildEntity parentobj = World.GetSceneObjectPart(pusheeav.ParentID);
                    PusheePos = parentobj != null ? parentobj.AbsolutePosition : pusheeav.AbsolutePosition;
                }
                else
                {
                    PusheePos = pusheeav.AbsolutePosition;
                }
            }

            if (!pusheeIsAvatar)
            {
                // not an avatar so push is not affected by parcel flags
                pusheeob = World.GetSceneObjectPart(UUID.Parse(target));

                // We can't find object
                if (pusheeob == null)
                    return;

                // Object not pushable.  Not an attachment and has no physics component
                if (!pusheeob.IsAttachment && pusheeob.PhysActor == null)
                    return;

                PusheePos = pusheeob.AbsolutePosition;
                pushAllowed = true;
            }
            else
            {
                IParcelManagementModule parcelManagement = World.RequestModuleInterface<IParcelManagementModule>();
                if (World.RegionInfo.RegionSettings.RestrictPushing)
                {
                    pushAllowed = m_host.OwnerID == targetID || m_host.ParentEntity.Scene.Permissions.IsGod(m_host.OwnerID);
                }
                else
                {
                    if (parcelManagement != null)
                    {
                        ILandObject targetlandObj = parcelManagement.GetLandObject(PusheePos.X, PusheePos.Y);
                        if (targetlandObj == null)
                            // We didn't find the parcel but region isn't push restricted so assume it's ok
                            pushAllowed = true;
                        else
                        {
                            // Parcel push restriction
                            pushAllowed = (targetlandObj.LandData.Flags & (uint)ParcelFlags.RestrictPushObject) !=
                                          (uint)ParcelFlags.RestrictPushObject ||
                                          m_host.ParentEntity.Scene.Permissions.CanPushObject(m_host.OwnerID,
                                                                                              targetlandObj);
                        }
                    }
                }
            }
            if (pushAllowed)
            {
                float distance = (PusheePos - m_host.AbsolutePosition).Length();
                float distance_term = distance * distance * distance; // Script Energy
                float pusher_mass = m_host.GetMass();

                const float PUSH_ATTENUATION_DISTANCE = 17f;
                const float PUSH_ATTENUATION_SCALE = 5f;
                float distance_attenuation = 1f;
                if (distance > PUSH_ATTENUATION_DISTANCE)
                {
                    float normalized_units = 1f + (distance - PUSH_ATTENUATION_DISTANCE) / PUSH_ATTENUATION_SCALE;
                    distance_attenuation = 1f / normalized_units;
                }

                Vector3 applied_linear_impulse = new Vector3((float)impulse.x, (float)impulse.y, (float)impulse.z);
                {
                    float impulse_length = applied_linear_impulse.Length();

                    float desired_energy = impulse_length * pusher_mass;
                    if (desired_energy > 0f)
                        desired_energy += distance_term;

                    float scaling_factor = 1f;
                    scaling_factor *= distance_attenuation;
                    applied_linear_impulse *= scaling_factor;

                }
                if (pusheeIsAvatar)
                {
                    if (pusheeav.PhysicsActor != null)
                    {
                        if (local != 0)
                        {
                            applied_linear_impulse *= m_host.GetWorldRotation();
                        }
                        //Put a limit on it...
                        int MaxPush = (int)pusheeav.PhysicsActor.Mass * 25;

                        if (applied_linear_impulse.X > 0 &&
                            Math.Abs(applied_linear_impulse.X) > MaxPush)
                            applied_linear_impulse.X = MaxPush;
                        if (applied_linear_impulse.X < 0 &&
                            Math.Abs(applied_linear_impulse.X) > MaxPush)
                            applied_linear_impulse.X = -MaxPush;

                        if (applied_linear_impulse.Y > 0 &&
                            Math.Abs(applied_linear_impulse.X) > MaxPush)
                            applied_linear_impulse.Y = MaxPush;
                        if (applied_linear_impulse.Y < 0 &&
                            Math.Abs(applied_linear_impulse.X) > MaxPush)
                            applied_linear_impulse.Y = -MaxPush;

                        if (applied_linear_impulse.Z > 0 &&
                            Math.Abs(applied_linear_impulse.X) > MaxPush)
                            applied_linear_impulse.Z = MaxPush;
                        if (applied_linear_impulse.Z < 0 &&
                            Math.Abs(applied_linear_impulse.Z) > MaxPush)
                            applied_linear_impulse.Z = -MaxPush;

                        pusheeav.PhysicsActor.AddForce(applied_linear_impulse, true);
                    }
                }
                else
                {
                    if (pusheeob.PhysActor != null)
                    {
                        pusheeob.ApplyImpulse(applied_linear_impulse, local != 0);
                    }
                }
            }
        }
LSL_Api