internal static void SetStolenForever(this BSExtraDataList entry)
        {
            var ownerBad = TESForm.LookupFormById(StolenForeverOwnerFormId);

            if (ownerBad == null)
            {
                return;
            }

            var ownerPtr = ownerBad.Cast <TESForm>();

            if (ownerPtr == IntPtr.Zero)
            {
                return;
            }

            var ptr = entry.Cast <BSExtraDataList>();

            if (ptr != IntPtr.Zero)
            {
                Memory.InvokeCdecl(BetterStealingPlugin._SetListOwner_Func, ptr, ownerPtr);
                return;
            }
            throw new ArgumentNullException();
        }
        internal static int GetCount(this BSExtraDataList entry)
        {
            var ptr = entry.Cast <BSExtraDataList>();

            if (ptr != IntPtr.Zero)
            {
                return(Memory.InvokeCdecl(BetterStealingPlugin._GetCount_Func, ptr).ToInt32Safe());
            }
            throw new ArgumentNullException();
        }
Exemple #3
0
 private void ApplyResult(ExtraContainerChanges.ItemEntry entry, BSExtraDataList data, bool detected)
 {
     if (!detected)
     {
         data.SetOwner(null);
     }
     else
     {
         data.SetStolenForever();
     }
 }
        internal static void SetCustomData(this BSExtraDataList entry, uint data)
        {
            var ptr = entry.Cast <BSExtraDataList>();

            if (ptr != IntPtr.Zero)
            {
                var   bytes = BitConverter.GetBytes(data);
                float arg   = BitConverter.ToSingle(bytes, 0);
                Memory.InvokeCdecl(BetterStealingPlugin._SetNorth_Func, ptr, arg);
                return;
            }
            throw new ArgumentNullException();
        }
Exemple #5
0
        internal static void PushContainerItem(TESForm baseForm, BSExtraDataList data, int count)
        {
            if (baseForm == null || count <= 0)
            {
                return;
            }

            if (data == null)
            {
                return;
            }

            var  owner = data.GetOwner();
            uint cdata = data.GetCustomData();

            if (owner == null || (cdata & 0x80000000) != 0)
            {
                return;
            }

            if (owner.FormId == _InventoryExtensions.StolenForeverOwnerFormId)
            {
                return;
            }

            int ndata = ++_cdata_counter;

            if (_cdata_counter >= 0x40000000)
            {
                _cdata_counter = 0;
            }

            data.SetCustomData((uint)ndata);

            var ci = new queued_item();

            ci.BaseForm = baseForm;
            ci.Count    = count;
            ci.Owner    = owner;
            ci.CData    = (uint)ndata;

            lock (Locker)
            {
                if (QueuedContainer != null)
                {
                    QueuedContainer.Add(ci);
                }
            }
        }
        internal static bool HasEnchantment(this BSExtraDataList entry)
        {
            var n = entry.First;

            while (n != null)
            {
                if (n is ExtraEnchantment)
                {
                    return(true);
                }

                n = n.Next;
            }

            return(false);
        }
        internal static uint GetCustomData(this BSExtraDataList entry)
        {
            var ptr = entry.Cast <BSExtraDataList>();

            if (ptr != IntPtr.Zero)
            {
                float arg = Memory.InvokeCdeclF(BetterStealingPlugin._GetNorth_Func, ptr);
                if (arg == 0.0f)
                {
                    return(0);
                }
                var bytes = BitConverter.GetBytes(arg);
                return(BitConverter.ToUInt32(bytes, 0));
            }
            throw new ArgumentNullException();
        }
        internal static void SetOwner(this BSExtraDataList entry, TESForm owner)
        {
            var ownerptr = owner != null?owner.Cast <TESForm>() : IntPtr.Zero;

            if (owner != null && ownerptr == IntPtr.Zero)
            {
                throw new ArgumentOutOfRangeException();
            }
            var ptr = entry.Cast <BSExtraDataList>();

            if (ptr != IntPtr.Zero)
            {
                Memory.InvokeCdecl(BetterStealingPlugin._SetListOwner_Func, ptr, ownerptr);
                return;
            }
            throw new ArgumentNullException();
        }
        internal static bool IsStolenForever(this BSExtraDataList entry)
        {
            var owner = entry.GetOwner();

            return(owner != null && owner.FormId == StolenForeverOwnerFormId);
        }
Exemple #10
0
        internal static void RemoveContainerItem(TESForm baseForm, BSExtraDataList data, int count)
        {
            if (baseForm == null || count <= 0)
            {
                return;
            }

            if (data == null)
            {
                return;
            }

            var  owner = data.GetOwner();
            uint cdata = data.GetCustomData();

            if (owner == null || (cdata & 0x80000000) != 0)
            {
                return;
            }

            if (owner.FormId == _InventoryExtensions.StolenForeverOwnerFormId)
            {
                return;
            }

            if (cdata != 0)
            {
                data.SetCustomData(0);
            }

            lock (Locker)
            {
                if (QueuedContainer == null)
                {
                    return;
                }

                for (int i = QueuedContainer.Count - 1; i >= 0 && count > 0; i--)
                {
                    var ci = QueuedContainer[i];

                    if (!ci.BaseForm.Equals(baseForm))
                    {
                        continue;
                    }

                    if (ci.CData != cdata)
                    {
                        continue;
                    }

                    if (!ci.Owner.Equals(owner))
                    {
                        continue;
                    }

                    if (count >= ci.Count)
                    {
                        QueuedContainer.RemoveAt(i);
                        count -= ci.Count;
                    }
                    else
                    {
                        ci.Count -= count;
                        count     = 0;
                    }
                }
            }
        }
Exemple #11
0
        internal static bool CheckConditions(ExtraContainerChanges.ItemEntry entry, BSExtraDataList data, TESForm item)
        {
            // Game has a hardcoded check to ignore gold when it comes to ownership.
            if (item.FormId == 0xF)
            {
                return(false);
            }

            {
                var excludeForms = BetterStealingPlugin.ExcludeForms;
                if (excludeForms != null && excludeForms.Contains(item.FormId))
                {
                    return(false);
                }
            }

            if (Settings.Instance.ExcludeEnchantedItems)
            {
                if (data != null && data.HasEnchantment())
                {
                    return(false);
                }
            }

            var ls = BetterStealingPlugin.NeverKeywords;

            if (ls.Count != 0)
            {
                foreach (var x in ls)
                {
                    if (item.HasKeywordText(x))
                    {
                        return(false);
                    }
                }
            }

            ls = BetterStealingPlugin.AlwaysKeywords;
            if (ls.Count != 0)
            {
                foreach (var x in ls)
                {
                    if (item.HasKeywordText(x))
                    {
                        return(true);
                    }
                }
            }

            ls = BetterStealingPlugin.RequiredKeywords;
            if (ls.Count != 0)
            {
                bool has = false;
                foreach (var x in ls)
                {
                    if (item.HasKeywordText(x))
                    {
                        has = true;
                        break;
                    }
                }

                if (!has)
                {
                    return(false);
                }
            }

            int maxPrice = BetterStealingPlugin.MaxPrice;

            if (maxPrice > 0)
            {
                int cost;
                if (entry != null)
                {
                    cost = Memory.InvokeCdecl(BetterStealingPlugin._CalcCost_Func, entry.Cast <ExtraContainerChanges.ItemEntry>()).ToInt32Safe();
                }
                else
                {
                    cost = item.GoldValue;
                }

                if (cost > maxPrice)
                {
                    return(false);
                }
            }

            // Price, keyword, ID, type, etc.

            return(true);
        }
Exemple #12
0
        private bool ProcessInventory(ExtraContainerChanges.Data inventory, TESObjectREFR instance, TESForm item, TESForm owner, int count, uint?cdata = null)
        {
            if (inventory == null || item == null)
            {
                return(false);
            }

            // Special case for references, it might already be handled before. Containers have this check elsewhere.
            if (instance != null && instance.ExtraDataList.IsStolenForever())
            {
                return(false);
            }

            ExtraContainerChanges.ItemEntry entry = null;
            BSExtraDataList best      = null;
            int             bestCount = 0;

            foreach (var o in inventory.Objects)
            {
                var template = o.Template;
                if (template == null)
                {
                    continue;
                }

                if (!item.Equals(template))
                {
                    continue;
                }

                entry = o;

                o.ForeachEntry((data, icount) =>
                {
                    // Already not stolen.
                    var iowner = data != null ? data.GetOwner() : null;
                    if (iowner == null)
                    {
                        return;
                    }

                    if (cdata.HasValue && cdata.Value != data.GetCustomData())
                    {
                        return;
                    }

                    if (data.IsStolenForever())
                    {
                        return;
                    }

                    if (!CheckConditions(o, data, item))
                    {
                        return;
                    }

                    if (best == null || Math.Abs(count - bestCount) > Math.Abs(count - icount))
                    {
                        best      = data;
                        bestCount = icount;
                    }
                });

                break;
            }

            if (best == null)
            {
                return(false);
            }

            this.ApplyResult(entry, best, this.WasDetected);
            return(true);
        }