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 bool GetOverwriteWeaponNode(TESForm obj, NiPoint3 pt) { if (!this.IsEnabled) { return(false); } if (obj == null || obj.FormId != this.LastTargetFormId) { return(false); } var pcam = PlayerCamera.Instance; if (pcam == null) { return(false); } var pn = pcam.Node; if (pn == null) { return(false); } var pos = pn.WorldTransform.Position; pt.X = pos.X; pt.Y = pos.Y; pt.Z = pos.Z - 10.0f; return(true); }
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); } } }
/// <summary> /// Checks if the given actor is a creature by checking if it /// has the creature keyword. /// </summary> /// <param name="actor">The Actor</param> /// <returns><c>true</c> if creature, <c>false</c> if not</returns> public static bool IsCreature([NotNull] this Actor actor) { if (_creatureKeyword != null) { return(actor.Race.HasKeyword(_creatureKeyword)); } var keywordForm = TESForm.LookupFormById(CreatureKeywordID); if (keywordForm is BGSKeyword keyword) { _creatureKeyword = keyword; } return(actor.Race.HasKeyword(_creatureKeyword)); }
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(); }
private void init() { if (_t_init) { return; } _t_init = true; var id = Settings.Instance.LichTransformationEffectId; var file = Settings.Instance.LichTransformationEffectFile; if (id == 0 || string.IsNullOrEmpty(file)) { return; } _effect = TESForm.LookupFormFromFile(id, file) as EffectSetting; }
private void init() { if (_t_init) { return; } _t_init = true; uint id = Settings.Instance.WerewolfTransformationEffectId; string file = Settings.Instance.WerewolfTransformationEffectFile; if (id == 0 || string.IsNullOrEmpty(file)) { return; } _effect = TESForm.LookupFormFromFile <EffectSetting>(id, file); }
/// <summary> /// Tries to get a <see cref="TESForm"/> from a plugin file. /// </summary> /// <typeparam name="T">Type of <see cref="TESForm"/> you want to get</typeparam> /// <param name="formID">Form ID as <c>0x1234</c> of the <see cref="TESForm"/></param> /// <param name="fileName">Name of the plugin</param> /// <param name="value">The resulting value if return true</param> /// <returns>True if successful, false if not</returns> public static bool TryGetFormFromFile <T>(uint formID, string fileName, out T value) where T : TESForm { value = default; var form = TESForm.LookupFormFromFile(formID, fileName); if (form == null) { return(false); } if (!(form is T tForm)) { return(false); } value = tForm; return(true); }
private void init() { _is_inited = true; TESForm.ForEachForm(form => { var book = form as TESObjectBOOK; if (book != null) { var type = this.DetermineBookType(book); if (type.HasValue) { this.all[(int)type.Value].Add(book); this.all[max_booktypes].Add(book); this.type_map[book.FormId] = type.Value; } } return(true); }); }
private static void _Hook_SmithingTemper(CPURegisters ctx) { TESForm item = null; { var ptr = Memory.ReadPointer(ctx.BX); if (ptr != IntPtr.Zero) { ptr = Memory.ReadPointer(ptr); item = MemoryObject.FromAddress <TESForm>(ptr); } } double value = 0.0; if (item != null) { value = item.GoldValue; } if (value < 1.0) { value = 1.0; } float oldQuality = Memory.ReadFloat(ctx.BX + 0x18); float newQuality = Memory.ReadFloat(ctx.BX + 0x1C); var temperForm = MemoryObject.FromAddress <BGSConstructibleObject>(Memory.ReadPointer(ctx.BX + 0x10)); if (temperForm == null) { return; } float amount = 0.0f; TESContainer req = temperForm.Requirements; int max = req.ContainerEntriesCount; for (int i = 0; i < max; i++) { var entry = req.GetContainerEntry(i); if (entry == null) { break; } int gold = entry.Item.GoldValue; if (gold <= 0) { continue; } amount += gold * entry.Count; } var plr = PlayerCharacter.Instance; float skill = 5.0f; if (plr != null) { skill = plr.GetActorValue(ActorValueIndices.Smithing); } float xp = Formula_Tempering((newQuality - oldQuality) * (float)value, amount, skill); if (xp < 0.0f) { xp = 0.0f; } if (Settings.DebugMode > 0) { WriteToDebugFile("Tempering: original XP was " + ctx.XMM2f.ToString(System.Globalization.CultureInfo.InvariantCulture) + " and we replaced it with " + xp.ToString(System.Globalization.CultureInfo.InvariantCulture)); } ctx.XMM2f = xp; }
private List <NiAVObject> GetHelmetNodes(NiNode root) { var ls = new List <NiAVObject>(); if (root != null) { bool hadHead = false; foreach (var ch in root.Children) { if (ch == null) { continue; } string nm = ch.Name.Text; if (string.IsNullOrEmpty(nm) || !nm.EndsWith("]")) { continue; } int ix = nm.LastIndexOf('('); if (ix < 0) { continue; } nm = nm.Substring(ix + 1); ix = nm.IndexOf(')'); if (ix < 0) { continue; } nm = nm.Substring(0, ix); uint formId = 0; if (!uint.TryParse(nm, System.Globalization.NumberStyles.HexNumber, null, out formId)) { continue; } var form = TESForm.LookupFormById(formId); if (form == null || form.FormType != FormTypes.Armor) { continue; } uint biped = NetScriptFramework.Memory.ReadUInt32(form.Address + 0x1B8); if ((biped & this.IsHelmetBipedMask) != 0 && (biped & this.NotHelmetBipedMask) == 0) { if ((biped & this.IsHeadBipedMask) != 0) { hadHead = true; } ls.Add(ch); } } this.HadHeadInHelmetNodes = hadHead; } return(ls); }
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); }
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); }
private void OnUsedItem(Actor actor, TESForm obj, ref int removeCount) { if (actor == null || obj == null || !actor.Equals(PlayerCharacter.Instance)) { return; } switch (obj.FormType) { case FormTypes.Potion: { var potion = obj as AlchemyItem; if (potion != null) { if ((potion.Data.Flags & AlchemyItem.AlchemyItemFlags.FoodItem) != AlchemyItem.AlchemyItemFlags.None) { if (settings.alwaysApplySpellOnFoodUse.Value != null) { actor.CastSpell(settings.alwaysApplySpellOnFoodUse.Value, actor, null); } if (removeCount > 0 && settings.chanceNotRemoveFood.Value > 0.0) { if (NetScriptFramework.Tools.Randomizer.Roll(settings.chanceNotRemoveFood.Value * 0.01)) { removeCount = 0; } } } else if ((potion.Data.Flags & AlchemyItem.AlchemyItemFlags.Poison) != AlchemyItem.AlchemyItemFlags.None) { if (settings.alwaysApplySpellOnPoisonUse.Value != null) { actor.CastSpell(settings.alwaysApplySpellOnPoisonUse.Value, actor, null); } if (removeCount > 0 && settings.chanceNotRemovePoison.Value > 0.0) { if (NetScriptFramework.Tools.Randomizer.Roll(settings.chanceNotRemovePoison.Value * 0.01)) { removeCount = 0; } } } else { if (settings.alwaysApplySpellOnPotionUse.Value != null) { actor.CastSpell(settings.alwaysApplySpellOnPotionUse.Value, actor, null); } if (removeCount > 0 && settings.chanceNotRemovePotion.Value > 0.0) { if (NetScriptFramework.Tools.Randomizer.Roll(settings.chanceNotRemovePotion.Value * 0.01)) { removeCount = 0; } } } } } break; case FormTypes.Ingredient: { } break; } }
private string CanUseItem(Actor actor, TESForm obj) { if (actor == null || obj == null || !actor.Equals(PlayerCharacter.Instance)) { return(null); } switch (obj.FormType) { case FormTypes.Potion: { var potion = obj as AlchemyItem; if (potion != null) { MagicItem itm = null; if ((potion.Data.Flags & AlchemyItem.AlchemyItemFlags.FoodItem) != AlchemyItem.AlchemyItemFlags.None) { if (settings.blockFoodInCombat.Value && actor.IsInCombat) { return(settings.blockFoodInCombatMsg.Value ?? ""); } if (mekw_food != null && mekw_food.Any(q => actor.HasMagicEffectWithKeywordText(q, ref itm))) { return(settings.blockFoodWhenMagicEffectKeywordMsg.Value ?? ""); } } else if ((potion.Data.Flags & AlchemyItem.AlchemyItemFlags.Poison) != AlchemyItem.AlchemyItemFlags.None) { if (settings.blockPoisonInCombat.Value && actor.IsInCombat) { return(settings.blockPoisonInCombatMsg.Value ?? ""); } if (mekw_poison != null && mekw_poison.Any(q => actor.HasMagicEffectWithKeywordText(q, ref itm))) { return(settings.blockPoisonWhenMagicEffectKeywordMsg.Value ?? ""); } } else { if (settings.blockPotionInCombat.Value && actor.IsInCombat) { return(settings.blockPotionInCombatMsg.Value ?? ""); } if (mekw_potion != null && mekw_potion.Any(q => actor.HasMagicEffectWithKeywordText(q, ref itm))) { return(settings.blockPotionWhenMagicEffectKeywordMsg.Value ?? ""); } } } } break; case FormTypes.Ingredient: { } break; } return(null); }
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; } } } }
public static TESForm TESFormLookupFormFromFile(uint id, string fileName) { return(TESForm.LookupFormFromFile(id, fileName)); }