Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RacesOfValheim v1.4.20
RacesOfValheim.dll
Decompiled 6 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; using Valheim.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("RacesOfValheim")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RacesOfValheim")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] namespace RacesOfValheim; public static class AswidBatForm { public const string BatZdoKey = "Aswid_IsBatForm"; private static readonly int BatFormHash = StringExtensionMethods.GetStableHashCode("SE_BatForm"); private static int unmaskDepth; public static bool Unmasked => unmaskDepth > 0; public static void PushUnmask() { unmaskDepth++; } public static void PopUnmask() { if (unmaskDepth > 0) { unmaskDepth--; } } public static bool IsBat(Player player) { if ((Object)(object)player == (Object)null) { return false; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid() && component.GetZDO().GetBool("Aswid_IsBatForm", false)) { return true; } if ((Object)(object)player == (Object)(object)Player.m_localPlayer && ((Character)player).GetSEMan() != null) { return ((Character)player).GetSEMan().HaveStatusEffect(BatFormHash); } return false; } } [HarmonyPatch(typeof(Player), "InDebugFlyMode")] public static class Aswid_BatIsVisibleToAI_Patch { public static void Postfix(Player __instance, ref bool __result) { if (__result && (AswidConfig.BatFormAggro == null || AswidConfig.BatFormAggro.Value) && AswidBatForm.IsBat(__instance)) { __result = false; } } } [HarmonyPatch(typeof(Player), "IsDebugFlying")] public static class Aswid_BatIsDebugFlying_Patch { public static void Postfix(Player __instance, ref bool __result) { if (__result && AswidBatForm.Unmasked && AswidBatForm.IsBat(__instance)) { __result = false; } } } [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class Aswid_BatTakesDamage_Patch { public static void Prefix(Character __instance, ref bool __state) { int num; if (AswidConfig.BatFormVulnerable == null || AswidConfig.BatFormVulnerable.Value) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { num = (AswidBatForm.IsBat(val) ? 1 : 0); goto IL_0027; } } num = 0; goto IL_0027; IL_0027: __state = (byte)num != 0; if (__state) { AswidBatForm.PushUnmask(); } } public static void Finalizer(bool __state) { if (__state) { AswidBatForm.PopUnmask(); } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] public static class Aswid_BatTakesRemoteDamage_Patch { public static void Prefix(Character __instance, ref bool __state) { int num; if (AswidConfig.BatFormVulnerable == null || AswidConfig.BatFormVulnerable.Value) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { num = (AswidBatForm.IsBat(val) ? 1 : 0); goto IL_0027; } } num = 0; goto IL_0027; IL_0027: __state = (byte)num != 0; if (__state) { AswidBatForm.PushUnmask(); } } public static void Finalizer(bool __state) { if (__state) { AswidBatForm.PopUnmask(); } } } [HarmonyPatch(typeof(MonsterAI), "UpdateSleep")] public static class Aswid_BatWakesSleepers_Patch { public static void Prefix(ref bool __state) { __state = AswidConfig.BatFormAggro == null || AswidConfig.BatFormAggro.Value; if (__state) { AswidBatForm.PushUnmask(); } } public static void Finalizer(bool __state) { if (__state) { AswidBatForm.PopUnmask(); } } } [HarmonyPatch(typeof(Player), "OnDeath")] public static class Aswid_BatDiesAsBat_Patch { public static void Prefix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !((Object)(object)AswidRace.Instance == (Object)null)) { AswidRace.Instance.HardResetBatForm(); } } } [HarmonyPatch(typeof(Character), "UpdateDebugFly")] public static class Aswid_BatFlightSpeed_Patch { public static void Postfix(Character __instance, Vector3 ___m_currentVel, Rigidbody ___m_body) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if (AswidConfig.BatFormFlightSpeed == null) { return; } float value = AswidConfig.BatFormFlightSpeed.Value; if (!Mathf.Approximately(value, 1f)) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !((Object)(object)___m_body == (Object)null) && AswidBatForm.IsBat(val)) { ___m_body.linearVelocity = ___m_currentVel * value; } } } } public static class AswidBloodPotions { public const string BaseName = "MeadBaseBloodPotion"; public const string PotionName = "MeadBloodPotion"; public const string SuperiorBaseName = "MeadBaseSuperiorBloodPotion"; public const string SuperiorPotionName = "MeadSuperiorBloodPotion"; private const string PotionDisplayName = "Blood Potion"; private const string SuperiorPotionDisplayName = "Superior Blood Potion"; private const float HealDuration = 8f; private const float HealFraction = 0.05f; private const float SuperiorHealFraction = 0.1f; private const int BottlesPerBrew = 5; public const double FermentSpeedMultiplier = 4.0; private static readonly MethodInfo GetContentMethod = AccessTools.Method(typeof(Fermenter), "GetContent", (Type[])null, (Type[])null); public static void Register() { //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Expected O, but got Unknown //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Expected O, but got Unknown //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Expected O, but got Unknown //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown SE_BloodPotion effect = CreateEffect("SE_BloodPotion", "Blood Potion", 0.05f, "BloodEssence", "GemstoneRed"); SE_BloodPotion effect2 = CreateEffect("SE_SuperiorBloodPotion", "Superior Blood Potion", 0.1f, "SuperiorBloodEssence", "MoltenCore"); GameObject val = CloneItem("MeadBaseBloodPotion", "MeadBaseHealthMinor", "Blood Potion Mead Base", "Blood, berries and crypt light, waiting on a barrel."); GameObject val2 = CloneItem("MeadBloodPotion", "MeadHealthMinor", "Blood Potion", "Drink and the hunger stops mattering for a while. Fills every stomach with blood essence, full or not, and knits the flesh back together."); GameObject val3 = CloneItem("MeadBaseSuperiorBloodPotion", "MeadBaseHealthMedium", "Superior Blood Potion Mead Base", "The twice-rendered draught, still raw."); GameObject val4 = CloneItem("MeadSuperiorBloodPotion", "MeadHealthMedium", "Superior Blood Potion", "The same mercy, twice as deep."); AttachEffect(val2, effect); AttachEffect(val4, effect2); AddRecipe("SuperiorBloodEssence", (RequirementConfig[])(object)new RequirementConfig[1] { new RequirementConfig("BloodEssence", 5, 0, true) }); AddRecipe("MeadBaseBloodPotion", (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("BloodEssence", 3, 0, true), new RequirementConfig("Blueberries", 5, 0, true), new RequirementConfig("MushroomYellow", 5, 0, true) }); AddRecipe("MeadBaseSuperiorBloodPotion", (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("SuperiorBloodEssence", 3, 0, true), new RequirementConfig("Sap", 5, 0, true), new RequirementConfig("Cloudberry", 5, 0, true) }); AddFermenterConversion(val, val2); AddFermenterConversion(val3, val4); } private static GameObject CloneItem(string prefabName, string source, string displayName, string description) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab(prefabName, source); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)("[Aswid] Could not clone '" + source + "'; " + displayName + " not registered.")); return null; } ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return null; } SharedData shared = component.m_itemData.m_shared; shared.m_name = displayName; shared.m_description = description; shared.m_consumeStatusEffect = null; ItemManager.Instance.AddItem(new CustomItem(val, false)); return val; } private static void AttachEffect(GameObject potion, SE_BloodPotion effect) { ItemDrop val = (((Object)(object)potion != (Object)null) ? potion.GetComponent<ItemDrop>() : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)effect == (Object)null)) { val.m_itemData.m_shared.m_consumeStatusEffect = (StatusEffect)(object)effect; } } private static void AddRecipe(string item, RequirementConfig[] requirements) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown ItemManager.Instance.AddRecipe(new CustomRecipe(new RecipeConfig { Item = item, Amount = 1, CraftingStation = CraftingStations.MeadKetill, Requirements = requirements })); } private static void AddFermenterConversion(GameObject from, GameObject to) { //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Expected O, but got Unknown if ((Object)(object)from == (Object)null || (Object)(object)to == (Object)null) { return; } GameObject prefab = Cache.GetPrefab<GameObject>("fermenter"); Fermenter val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Fermenter>() : null); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"[Aswid] No fermenter prefab; blood potions cannot be brewed."); return; } ItemDrop component = from.GetComponent<ItemDrop>(); ItemDrop component2 = to.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null || (Object)(object)component2 == (Object)null) { return; } foreach (ItemConversion item in val.m_conversion) { if (item != null && (Object)(object)item.m_from == (Object)(object)component) { return; } } val.m_conversion.Add(new ItemConversion { m_from = component, m_to = component2, m_producedItems = 5 }); } private static SE_BloodPotion CreateEffect(string name, string displayName, float fraction, string essencePrefab, string iconSource) { //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown SE_BloodPotion sE_BloodPotion = ScriptableObject.CreateInstance<SE_BloodPotion>(); ((Object)sE_BloodPotion).name = name; ((StatusEffect)sE_BloodPotion).m_name = displayName; ((StatusEffect)sE_BloodPotion).m_tooltip = $"Stomachs filled with blood. Healing {Mathf.RoundToInt(fraction * 100f)}% over {8f:0} seconds."; ((StatusEffect)sE_BloodPotion).m_ttl = 8f; sE_BloodPotion.m_healFraction = fraction; sE_BloodPotion.m_essencePrefab = essencePrefab; ((SE_Stats)sE_BloodPotion).m_healthOverTimeDuration = 8f; ((SE_Stats)sE_BloodPotion).m_healthOverTimeInterval = 1f; ItemDrop prefab = Cache.GetPrefab<ItemDrop>(iconSource); Sprite[] array = (((Object)(object)prefab != (Object)null && prefab.m_itemData != null && prefab.m_itemData.m_shared != null) ? prefab.m_itemData.m_shared.m_icons : null); if (array != null && array.Length != 0) { ((StatusEffect)sE_BloodPotion).m_icon = array[0]; } ItemManager.Instance.AddStatusEffect(new CustomStatusEffect((StatusEffect)(object)sE_BloodPotion, false)); return sE_BloodPotion; } public static void FillStomachs(Player player, string essencePrefabName) { if ((Object)(object)player == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(essencePrefabName); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)val == (Object)null) { return; } Traverse val2 = Traverse.Create((object)player); IList value = val2.Field("m_foods").GetValue<IList>(); if (value != null) { value.Clear(); for (int i = 0; i < 3; i++) { value.Add(MakeFood(val, itemPrefab, essencePrefabName)); } if (AswidRace.IsAswid() && BossProgressionManager.GetCurrentProgressionState() >= 8) { ItemData val3 = val.m_itemData.Clone(); val3.m_dropPrefab = itemPrefab; AswidFoodManager.SetExtraFood(player, val3); } val2.Method("UpdateFood", new object[2] { 0f, true }).GetValue(); } } public static bool IsBloodBrew(Fermenter fermenter) { if ((Object)(object)fermenter == (Object)null || GetContentMethod == null) { return false; } int num = Convert.ToInt32(GetContentMethod.Invoke(fermenter, null)); if (num != 0) { if (num != StringExtensionMethods.GetStableHashCode("MeadBaseBloodPotion")) { return num == StringExtensionMethods.GetStableHashCode("MeadBaseSuperiorBloodPotion"); } return true; } return false; } private static Food MakeFood(ItemDrop drop, GameObject prefab, string prefabName) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown ItemData val = drop.m_itemData.Clone(); val.m_dropPrefab = prefab; return new Food { m_name = prefabName, m_item = val, m_time = val.m_shared.m_foodBurnTime, m_health = val.m_shared.m_food, m_stamina = val.m_shared.m_foodStamina, m_eitr = val.m_shared.m_foodEitr }; } } [HarmonyPatch(typeof(Fermenter), "GetFermentationTime")] public static class AswidBloodPotionFermentPatch { public static void Postfix(Fermenter __instance, ref double __result) { if (!(__result <= 0.0) && AswidBloodPotions.IsBloodBrew(__instance)) { __result *= 4.0; } } } public class SE_BloodPotion : SE_Stats { public float m_healFraction = 0.05f; public string m_essencePrefab = ""; public override void Setup(Character character) { if ((Object)(object)character != (Object)null) { base.m_healthOverTime = character.GetMaxHealth() * m_healFraction; } ((SE_Stats)this).Setup(character); AswidBloodPotions.FillStomachs((Player)(object)((character is Player) ? character : null), m_essencePrefab); } } public static class AswidBloodRefinery { public const string PieceName = "AswidBloodRefinery"; public const string EssenceName = "BloodEssence"; public const string SuperiorEssenceName = "SuperiorBloodEssence"; public const string CoreName = "BloodCore"; public const string EssenceDisplayName = "Blood Essence"; public const string SuperiorEssenceDisplayName = "Superior Blood Essence"; public const string CoreDisplayName = "Blood Core"; public const string PieceDisplayName = "Blood Refinery"; private const float RegenPerHealth = 12f; private const float ModelScale = 0.5f; private static readonly Color BodyTint = new Color(0.13f, 0.07f, 0.07f, 1f); private static readonly Color BodyEmission = new Color(0.2f, 0.01f, 0.01f, 1f); private static readonly Color EssenceTint = new Color(0.62f, 0.03f, 0.04f, 1f); private static readonly Color SuperiorEssenceTint = new Color(0.85f, 0f, 0.02f, 1f); private static readonly Color EssenceEmission = new Color(0.16f, 0f, 0f, 1f); public static readonly Dictionary<string, int> BoneValues = new Dictionary<string, int> { { "BoneFragments", 1 }, { "CharredBone", 2 }, { "Charredskull", 3 }, { "WitheredBone", 3 }, { "AsksvinCarrionNeck", 2 }, { "AsksvinCarrionPelvic", 2 }, { "AsksvinCarrionRibcage", 3 }, { "AsksvinCarrionSkull", 3 }, { "UndeadBjornRibcage", 3 } }; private static readonly string[] CookingStationPrefabs = new string[2] { "piece_cookingstation", "piece_cookingstation_iron" }; private static Dictionary<string, string> meatToCooked; public static GameObject EssencePrefab { get; private set; } public static GameObject SuperiorEssencePrefab { get; private set; } public static void Register() { RegisterCore(); RegisterEssence(); RegisterPiece(); AswidBloodPotions.Register(); } public static bool IsAswidMeal(ItemData item) { if (item == null || item.m_shared == null || item.m_shared.m_name == null) { return false; } if (!item.m_shared.m_name.StartsWith("Aswid Food:") && !(item.m_shared.m_name == "Blood Essence")) { return IsEssence(item); } return true; } public static bool IsEssence(ItemData item) { if (item == null || item.m_shared == null || item.m_shared.m_name == null) { return false; } if (!(item.m_shared.m_name == "Blood Essence")) { return item.m_shared.m_name == "Superior Blood Essence"; } return true; } private static void RegisterCore() { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab("BloodCore", "Bloodbag"); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"[Aswid] Could not clone Bloodbag; Blood Core not registered."); return; } ItemDrop component = val.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { SharedData shared = component.m_itemData.m_shared; shared.m_name = "Blood Core"; shared.m_description = "A knot of clotted blood kept beating by something that is not a heart. The dead trade them; only the dead know how they are made."; shared.m_itemType = (ItemType)1; shared.m_food = 0f; shared.m_foodStamina = 0f; shared.m_foodEitr = 0f; shared.m_weight = 0.5f; shared.m_maxStackSize = 20; Sprite val2 = BorrowIcon("MorgenHeart"); if ((Object)(object)val2 != (Object)null) { shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 }; } ItemManager.Instance.AddItem(new CustomItem(val, false)); } } private static void RegisterEssence() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) EssencePrefab = BuildEssence("BloodEssence", "Blood Essence", "Blood rendered down to what it actually is. The only real food an Aswid can still chew, and the base of every draught worth brewing.", 60f, EssenceTint, "GemstoneRed"); SuperiorEssencePrefab = BuildEssence("SuperiorBloodEssence", "Superior Blood Essence", "The same blood, rendered twice. Darker, thicker, and worth five of the first pass.", 80f, SuperiorEssenceTint, "MoltenCore"); } private static GameObject BuildEssence(string prefabName, string displayName, string description, float food, Color tint, string iconSource) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab(prefabName, "Eitr"); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)("[Aswid] Could not clone Eitr; " + displayName + " not registered.")); return null; } StripOffensive(val, prefabName); StripGlow(val, prefabName); Recolour(val, tint, EssenceEmission); RedShiftEffects(val, tint); ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return null; } SharedData shared = component.m_itemData.m_shared; shared.m_name = displayName; shared.m_description = description; shared.m_itemType = (ItemType)2; shared.m_weight = 0.2f; shared.m_food = food; shared.m_foodStamina = 60f; shared.m_foodEitr = 0f; shared.m_foodBurnTime = 2400f; shared.m_foodRegen = food / 12f; shared.m_consumeStatusEffect = null; Sprite val2 = BorrowIcon(iconSource); if ((Object)(object)val2 != (Object)null) { shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 }; } ItemManager.Instance.AddItem(new CustomItem(val, false)); return val; } private static void RegisterPiece() { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Expected O, but got Unknown //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Expected O, but got Unknown //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Expected O, but got Unknown GameObject val = PrefabManager.Instance.CreateClonedPrefab("AswidBloodRefinery", "eitrrefinery"); if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)"[Aswid] Could not clone eitrrefinery; Blood Refinery not registered."); return; } Smelter componentInChildren = val.GetComponentInChildren<Smelter>(true); if ((Object)(object)componentInChildren == (Object)null) { Logger.LogWarning((object)"[Aswid] eitrrefinery clone has no Smelter; Blood Refinery not registered."); return; } BloodRefineryBehaviour bloodRefineryBehaviour = ((Component)componentInChildren).gameObject.AddComponent<BloodRefineryBehaviour>(); bloodRefineryBehaviour.m_addMeatSwitch = componentInChildren.m_addOreSwitch; bloodRefineryBehaviour.m_addBoneSwitch = componentInChildren.m_addWoodSwitch; bloodRefineryBehaviour.m_outputPoint = componentInChildren.m_outputPoint; bloodRefineryBehaviour.m_enabledObject = componentInChildren.m_enabledObject; bloodRefineryBehaviour.m_disabledObject = componentInChildren.m_disabledObject; bloodRefineryBehaviour.m_haveBoneObject = componentInChildren.m_haveFuelObject; bloodRefineryBehaviour.m_haveMeatObject = componentInChildren.m_haveOreObject; bloodRefineryBehaviour.m_noMeatObject = componentInChildren.m_noOreObject; bloodRefineryBehaviour.m_animators = componentInChildren.m_animators; bloodRefineryBehaviour.m_meatAddedEffects = componentInChildren.m_oreAddedEffects; bloodRefineryBehaviour.m_boneAddedEffects = componentInChildren.m_fuelAddedEffects; bloodRefineryBehaviour.m_produceEffects = componentInChildren.m_produceEffects; bloodRefineryBehaviour.m_smokeSpawner = componentInChildren.m_smokeSpawner; Object.DestroyImmediate((Object)(object)componentInChildren); StripOffensive(val, "AswidBloodRefinery"); SanitiseEffects(bloodRefineryBehaviour.m_meatAddedEffects, "AswidBloodRefinery.oreAdded"); SanitiseEffects(bloodRefineryBehaviour.m_boneAddedEffects, "AswidBloodRefinery.fuelAdded"); SanitiseEffects(bloodRefineryBehaviour.m_produceEffects, "AswidBloodRefinery.produce"); val.transform.localScale = Vector3.one * 0.5f; Recolour(val, BodyTint, BodyEmission); RedShiftEffects(val); Piece component = val.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { component.m_craftingStation = null; component.m_resources = (Requirement[])(object)new Requirement[0]; component.m_name = "Blood Refinery"; } PieceConfig val2 = new PieceConfig(); val2.Name = "Blood Refinery"; val2.Description = "Flesh goes in, bone goes in, and what is left of both comes out red."; val2.PieceTable = PieceTables.Hammer; val2.Category = PieceCategories.Crafting; val2.Requirements = (RequirementConfig[])(object)new RequirementConfig[3] { new RequirementConfig("BloodCore", 1, 0, true), new RequirementConfig("Stone", 20, 0, true), new RequirementConfig("Bronze", 10, 0, true) }; PieceConfig val3 = val2; PieceManager.Instance.AddPiece(new CustomPiece(val, false, val3)); } public static void EnsureKnown(Player player) { if (!((Object)(object)player == (Object)null)) { GameObject prefab = PrefabManager.Instance.GetPrefab("AswidBloodRefinery"); Piece val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Piece>() : null); if (!((Object)(object)val == (Object)null)) { Traverse val2 = Traverse.Create((object)player); val2.Method("AddKnownPiece", new object[1] { val }).GetValue(); val2.Method("UpdateAvailablePiecesList", Array.Empty<object>()).GetValue(); } } } public static int BloodValue(string prefabName) { EnsureMeatMap(); if (string.IsNullOrEmpty(prefabName) || !meatToCooked.TryGetValue(prefabName, out var value)) { return 0; } SharedData val = SharedOf(value) ?? SharedOf(prefabName); if (val == null) { return 1; } int num = Mathf.CeilToInt((val.m_food + val.m_foodStamina) / 20f); return Mathf.Max(1, num); } public static int FleshValue(string prefabName) { return BloodValue(prefabName); } public static int BoneValue(string prefabName) { if (string.IsNullOrEmpty(prefabName)) { return 0; } if (!BoneValues.TryGetValue(prefabName, out var value)) { return 0; } return value; } private static void EnsureMeatMap() { if (meatToCooked != null) { return; } meatToCooked = new Dictionary<string, string>(DraughFoodPatches.rawToCookedMapping); meatToCooked.Remove("GreydwarfEye"); meatToCooked["AsksvinMeat"] = "CookedAsksvinMeat"; meatToCooked["BoneMawSerpentMeat"] = "CookedBoneMawSerpentMeat"; string[] cookingStationPrefabs = CookingStationPrefabs; for (int i = 0; i < cookingStationPrefabs.Length; i++) { GameObject prefab = Cache.GetPrefab<GameObject>(cookingStationPrefabs[i]); CookingStation val = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<CookingStation>() : null); if ((Object)(object)val == (Object)null || val.m_conversion == null) { continue; } foreach (ItemConversion item in val.m_conversion) { if (item != null && !((Object)(object)item.m_from == (Object)null) && !((Object)(object)item.m_to == (Object)null)) { string name = ((Object)((Component)item.m_from).gameObject).name; if (!meatToCooked.ContainsKey(name)) { meatToCooked[name] = ((Object)((Component)item.m_to).gameObject).name; } } } } } private static SharedData SharedOf(string prefabName) { GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab(prefabName) : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if (!((Object)(object)val2 != (Object)null)) { return null; } return val2.m_itemData.m_shared; } internal static void StripOffensive(GameObject root, string label) { MonoBehaviour[] componentsInChildren = root.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && IsOffensive(val)) { Logger.LogInfo((object)("[Aswid] " + label + ": stripped " + ((object)val).GetType().Name + " from '" + ((Object)((Component)val).gameObject).name + "'.")); Object.DestroyImmediate((Object)(object)val); } } } private static bool IsOffensive(MonoBehaviour behaviour) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Invalid comparison between Unknown and I4 if (behaviour is Radiator) { return true; } if (behaviour is IProjectile || behaviour is Aoe || behaviour is Turret) { return true; } EffectArea val = (EffectArea)(object)((behaviour is EffectArea) ? behaviour : null); if ((Object)(object)val == (Object)null) { return false; } return (val.m_type & 0xB) > 0; } private static bool IsOffensivePrefab(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return false; } if (((Object)prefab).name.ToLowerInvariant().Contains("radiation")) { return true; } MonoBehaviour[] componentsInChildren = prefab.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val in componentsInChildren) { if ((Object)(object)val != (Object)null && IsOffensive(val)) { return true; } } return false; } private static void SanitiseEffects(EffectList list, string label) { if (list == null || list.m_effectPrefabs == null) { return; } List<EffectData> list2 = new List<EffectData>(); EffectData[] effectPrefabs = list.m_effectPrefabs; foreach (EffectData val in effectPrefabs) { if (val != null && !((Object)(object)val.m_prefab == (Object)null)) { if (IsOffensivePrefab(val.m_prefab)) { Logger.LogInfo((object)("[Aswid] " + label + ": dropped effect '" + ((Object)val.m_prefab).name + "' (carries damage).")); } else { Logger.LogInfo((object)("[Aswid] " + label + ": kept effect '" + ((Object)val.m_prefab).name + "'.")); list2.Add(val); } } } list.m_effectPrefabs = list2.ToArray(); } private static void StripGlow(GameObject root, string label) { LightFlicker[] componentsInChildren = root.GetComponentsInChildren<LightFlicker>(true); foreach (LightFlicker val in componentsInChildren) { if ((Object)(object)val != (Object)null) { Object.DestroyImmediate((Object)(object)val); } } LightLod[] componentsInChildren2 = root.GetComponentsInChildren<LightLod>(true); foreach (LightLod val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null) { Object.DestroyImmediate((Object)(object)val2); } } Light[] componentsInChildren3 = root.GetComponentsInChildren<Light>(true); foreach (Light val3 in componentsInChildren3) { if ((Object)(object)val3 != (Object)null) { Object.DestroyImmediate((Object)(object)val3); } } Transform[] componentsInChildren4 = root.GetComponentsInChildren<Transform>(true); foreach (Transform val4 in componentsInChildren4) { if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4 == (Object)(object)root.transform)) { string text = ((Object)((Component)val4).gameObject).name.ToLowerInvariant(); if (text.Contains("radiation") || text.Contains("gamma") || text.Contains("halo") || text.Contains("glow")) { Logger.LogInfo((object)("[Aswid] " + label + ": removed glow child '" + ((Object)((Component)val4).gameObject).name + "'.")); Object.DestroyImmediate((Object)(object)((Component)val4).gameObject); } } } } private static void RedShiftEffects(GameObject root) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) RedShiftEffects(root, EssenceTint); } private static void RedShiftEffects(GameObject root, Color tint) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) ParticleSystem[] componentsInChildren = root.GetComponentsInChildren<ParticleSystem>(true); foreach (ParticleSystem val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { MainModule main = val.main; ((MainModule)(ref main)).startColor = new MinMaxGradient(tint); } } Light[] componentsInChildren2 = root.GetComponentsInChildren<Light>(true); foreach (Light val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null) { val2.color = tint; } } } private static Sprite BorrowIcon(string prefabName) { ItemDrop prefab = Cache.GetPrefab<ItemDrop>(prefabName); Sprite[] array = (((Object)(object)prefab != (Object)null && prefab.m_itemData != null && prefab.m_itemData.m_shared != null) ? prefab.m_itemData.m_shared.m_icons : null); if (array != null && array.Length != 0 && (Object)(object)array[0] != (Object)null) { return array[0]; } Logger.LogWarning((object)("[Aswid] Could not borrow the icon from '" + prefabName + "'.")); return null; } private static void Recolour(GameObject root, Color tint, Color emission) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = root.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || val is ParticleSystemRenderer) { continue; } Material[] materials = val.materials; foreach (Material val2 in materials) { if (!((Object)(object)val2 == (Object)null)) { val2.color = tint; if (val2.HasProperty("_Color")) { val2.SetColor("_Color", tint); } if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", emission); } } } } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public static class AswidBloodRefineryKnownPatch { public static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { AswidBloodRefinery.EnsureKnown(__instance); } } } [HarmonyPatch(typeof(Player), "CanConsumeItem")] public static class AswidBloodEssenceGatePatch { public static void Postfix(Player __instance, ItemData item, ref bool __result) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && item != null && item.m_shared != null && AswidBloodRefinery.IsEssence(item) && !AswidRace.IsAswid()) { __result = false; } } } [HarmonyPatch(typeof(Humanoid), "UseItem")] public static class AswidBloodEssenceMessagePatch { public static bool Prefix(Humanoid __instance, ItemData item) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || item == null || item.m_shared == null) { return true; } if (!AswidBloodRefinery.IsEssence(item)) { return true; } if (AswidRace.IsAswid()) { return true; } ((Character)val).Message((MessageType)2, "Living blood curdles in a living throat.", 0, (Sprite)null, false); return false; } } public class AswidClaws : RaceClawSet { public static readonly AswidClaws Instance = new AswidClaws(); public override string RaceId => "Aswid"; public override string ItemName => "AswidBeastClaws"; public override string DisplayName => "Claws of the Beast"; public override string Description => "Grown in the dark, and darker for it. They do not come off."; public override string[] ModelPrefabs => new string[4] { "FistBjornClaw", "FistBjornUndeadClaw", "FistBjornClawUndead", "FistUnbjornClaw" }; public override string StateZdoKey => "RacesOfValheim_AswidState"; public override Color? Tint => new Color(AswidConfig.ClawTintRed.Value, AswidConfig.ClawTintGreen.Value, AswidConfig.ClawTintBlue.Value, 1f); public override bool IsTransformed(Player player) { if ((Object)(object)player == (Object)null) { return false; } if ((Object)(object)player == (Object)(object)Player.m_localPlayer && (Object)(object)AswidRace.Instance != (Object)null && AswidRace.Instance.IsTransformed) { return true; } ZNetView component = ((Component)player).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { if (!component.GetZDO().GetBool("Aswid_IsBatForm", false)) { return component.GetZDO().GetBool("Aswid_IsMistForm", false); } return true; } return false; } } public static class AswidConfig { public static ConfigEntry<KeyboardShortcut> BatFormKey; public static ConfigEntry<KeyboardShortcut> MistFormKey; public static ConfigEntry<KeyboardShortcut> EclipseKey; public static ConfigEntry<KeyboardShortcut> TameKey; public static ConfigEntry<KeyboardShortcut> ToggleDevourKey; public static ConfigEntry<float> DamageBonusPerState; public static ConfigEntry<float> ArmorBonusPerState; public static ConfigEntry<float> SpeedBonusPerState; public static ConfigEntry<float> NightMultiplier; public static ConfigEntry<float> BloodMagicSkillGainMultiplier; public static ConfigEntry<float> SurtlingFormDamageBonus; public static ConfigEntry<bool> BatFormAggro; public static ConfigEntry<bool> BatFormVulnerable; public static ConfigEntry<float> BatFormFlightSpeed; public static ConfigEntry<float> AuraTickInterval; public static ConfigEntry<float> AuraRadiusDay; public static ConfigEntry<float> AuraRadiusNight; public static ConfigEntry<float> AuraBaseDamage; public static ConfigEntry<float> AuraBloodMagicScaling; public static ConfigEntry<float> AuraExecuteThreshold; public static ConfigEntry<float> SensesRadius; public static ConfigEntry<float> SensesRefreshInterval; public static ConfigEntry<float> SensesLightRange; public static ConfigEntry<float> SensesLightIntensity; public static ConfigEntry<float> EclipseCooldown; public static ConfigEntry<float> EclipseCastTime; public static ConfigEntry<float> EclipseDuration; public static ConfigEntry<float> DevourCooldown; public static ConfigEntry<float> EnslaveCooldown; public static ConfigEntry<float> ThrallLifetime; public static ConfigEntry<string> EyeSourceModel; public static ConfigEntry<int> EyeFinalStage; public static ConfigEntry<float> EarlyEyeColorRed; public static ConfigEntry<float> EarlyEyeColorGreen; public static ConfigEntry<float> EarlyEyeColorBlue; public static ConfigEntry<float> EarlyEyeGlowStrength; public static ConfigEntry<float> EyeColorRed; public static ConfigEntry<float> EyeColorGreen; public static ConfigEntry<float> EyeColorBlue; public static ConfigEntry<float> EyeGlowStrength; public static ConfigEntry<float> EyeSizeMultiplier; public static ConfigEntry<float> EyeForwardOffset; public static ConfigEntry<float> EyeHeightOffset; public static ConfigEntry<float> EyeSeparationOffset; public static ConfigEntry<float> EyeRotationX; public static ConfigEntry<float> EyeRotationY; public static ConfigEntry<float> EyeRotationZ; public static ConfigEntry<bool> EyeSmoke; public static ConfigEntry<bool> EyeFlatColorShader; public static ConfigEntry<float> ClawTintRed; public static ConfigEntry<float> ClawTintGreen; public static ConfigEntry<float> ClawTintBlue; public static void Bind(ConfigFile config) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Expected O, but got Unknown //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Expected O, but got Unknown //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Expected O, but got Unknown //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Expected O, but got Unknown //IL_02f2: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Expected O, but got Unknown //IL_032a: Unknown result type (might be due to invalid IL or missing references) //IL_0334: Expected O, but got Unknown //IL_0362: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Expected O, but got Unknown //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03a4: Expected O, but got Unknown //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03dc: Expected O, but got Unknown //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_0414: Expected O, but got Unknown //IL_0442: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Expected O, but got Unknown //IL_047a: Unknown result type (might be due to invalid IL or missing references) //IL_0484: Expected O, but got Unknown //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04bc: Expected O, but got Unknown //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_04f4: Expected O, but got Unknown //IL_0522: Unknown result type (might be due to invalid IL or missing references) //IL_052c: Expected O, but got Unknown //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_0564: Expected O, but got Unknown //IL_0592: Unknown result type (might be due to invalid IL or missing references) //IL_059c: Expected O, but got Unknown //IL_05ca: Unknown result type (might be due to invalid IL or missing references) //IL_05d4: Expected O, but got Unknown //IL_0602: Unknown result type (might be due to invalid IL or missing references) //IL_060c: Expected O, but got Unknown //IL_063a: Unknown result type (might be due to invalid IL or missing references) //IL_0644: Expected O, but got Unknown BatFormKey = config.Bind<KeyboardShortcut>("Aswid - Keybinds", "Bat Form", new KeyboardShortcut((KeyCode)103, Array.Empty<KeyCode>()), new ConfigDescription("Transform into (or revert from) a Bat, tier 2+ (night only) / tier 3+ (any time).", (AcceptableValueBase)null, Array.Empty<object>())); MistFormKey = config.Bind<KeyboardShortcut>("Aswid - Keybinds", "Mist Form Toggle", new KeyboardShortcut((KeyCode)104, Array.Empty<KeyCode>()), new ConfigDescription("Become (or revert from) mist, tier 7+.", (AcceptableValueBase)null, Array.Empty<object>())); EclipseKey = config.Bind<KeyboardShortcut>("Aswid - Keybinds", "Cast Eclipse", new KeyboardShortcut((KeyCode)106, Array.Empty<KeyCode>()), new ConfigDescription("Casts Eclipse, tier 6+. Fails silently at night.", (AcceptableValueBase)null, Array.Empty<object>())); TameKey = config.Bind<KeyboardShortcut>("Aswid - Keybinds", "Tame", new KeyboardShortcut((KeyCode)117, Array.Empty<KeyCode>()), new ConfigDescription("Tames the creature under your cursor, if your tier allows it.", (AcceptableValueBase)null, Array.Empty<object>())); ToggleDevourKey = config.Bind<KeyboardShortcut>("Aswid - Keybinds", "Toggle Devour Ability", new KeyboardShortcut((KeyCode)105, Array.Empty<KeyCode>()), new ConfigDescription("Turns the Vampiric Aura and the automatic Devour-on-kill behavior on or off together. Turn this off before talking to Haldor/Hildir - the aura does not recognize traders and will attack them.", (AcceptableValueBase)null, Array.Empty<object>())); DamageBonusPerState = config.Bind<float>("Aswid - Passive Combat", "Damage Bonus Per State", 2f, new ConfigDescription("Flat physical damage added to equipped weapons, per progression state.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); ArmorBonusPerState = config.Bind<float>("Aswid - Passive Combat", "Armor Bonus Per State", 1f, new ConfigDescription("Flat armor added, per progression state.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); SpeedBonusPerState = config.Bind<float>("Aswid - Passive Combat", "Speed Bonus Per State", 0.01f, new ConfigDescription("Move/jump speed multiplier added, per progression state (0.01 = 1%).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 0.1f), Array.Empty<object>())); NightMultiplier = config.Bind<float>("Aswid - Passive Combat", "Night Multiplier", 2f, new ConfigDescription("Multiplies the speed, armor, damage, and lifesteal bonuses above while it is night.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 5f), Array.Empty<object>())); BloodMagicSkillGainMultiplier = config.Bind<float>("Aswid - Passive Combat", "Blood Magic Skill Gain Multiplier", 2f, new ConfigDescription("Multiplies how fast the Blood Magic skill levels up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 5f), Array.Empty<object>())); SurtlingFormDamageBonus = config.Bind<float>("Aswid - Passive Combat", "Surtling Form Damage Bonus", 30f, new ConfigDescription("Flat damage added to every attack once the tier 8 Surtling form is unlocked.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>())); BatFormAggro = config.Bind<bool>("Aswid - Bat Form", "Monsters Notice The Bat", true, new ConfigDescription("Lets monsters see, hear and wake up for a player in Bat Form. Vanilla refuses to notice anyone flying on the debug-fly flag, which is the flag the form uses - turn this off to go back to a bat nothing ever looks at.", (AcceptableValueBase)null, Array.Empty<object>())); BatFormVulnerable = config.Bind<bool>("Aswid - Bat Form", "The Bat Can Be Hurt", true, new ConfigDescription("Lets damage land on a player in Bat Form. Same cause as the setting above: vanilla drops every hit on a debug-flying character. Turn this off for a bat that is noticed and chased but cannot be killed.", (AcceptableValueBase)null, Array.Empty<object>())); BatFormFlightSpeed = config.Bind<float>("Aswid - Bat Form", "Flight Speed", 1f, new ConfigDescription("How fast the bat flies, as a multiplier on the game's own flight speed (20 m/s, and 2.5x that while the run key is held). 1 is untouched, 2 is twice as fast, 0.5 is half. Local only - it changes how your own bat moves, not anyone else's.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.25f, 3f), Array.Empty<object>())); AuraTickInterval = config.Bind<float>("Aswid - Vampiric Aura", "Tick Interval", 0.25f, new ConfigDescription("Seconds between aura damage/lifesteal ticks.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.05f, 2f), Array.Empty<object>())); AuraRadiusDay = config.Bind<float>("Aswid - Vampiric Aura", "Radius (Day)", 3f, new ConfigDescription("Meters from the player that the aura drains during the day.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>())); AuraRadiusNight = config.Bind<float>("Aswid - Vampiric Aura", "Radius (Night)", 6f, new ConfigDescription("Meters from the player that the aura drains at night.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 20f), Array.Empty<object>())); AuraBaseDamage = config.Bind<float>("Aswid - Vampiric Aura", "Base Damage", 1f, new ConfigDescription("Damage per tick before the Blood Magic skill bonus, at human form's 0.5x multiplier.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); AuraBloodMagicScaling = config.Bind<float>("Aswid - Vampiric Aura", "Blood Magic Damage Scaling", 5f, new ConfigDescription("Extra damage per tick at 100 Blood Magic skill (scales linearly from 0).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 20f), Array.Empty<object>())); AuraExecuteThreshold = config.Bind<float>("Aswid - Vampiric Aura", "Execute Threshold", 0.2f, new ConfigDescription("Non-boss enemies at or below this fraction of max health are executed by the aura instead of merely damaged.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>())); SensesRadius = config.Bind<float>("Aswid - Superhuman Senses", "Detection Radius", 100f, new ConfigDescription("Meters within which nearby creatures are marked, tier 5+.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 300f), Array.Empty<object>())); SensesRefreshInterval = config.Bind<float>("Aswid - Superhuman Senses", "Refresh Interval", 1f, new ConfigDescription("Seconds between detection sweeps.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 5f), Array.Empty<object>())); SensesLightRange = config.Bind<float>("Aswid - Superhuman Senses", "Marker Light Range", 10f, new ConfigDescription("Range of the light placed on a detected creature.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 30f), Array.Empty<object>())); SensesLightIntensity = config.Bind<float>("Aswid - Superhuman Senses", "Marker Light Intensity", 2f, new ConfigDescription("Intensity of the light placed on a detected creature.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 10f), Array.Empty<object>())); EclipseCooldown = config.Bind<float>("Aswid - Eclipse", "Cooldown", 900f, new ConfigDescription("Seconds between casts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3600f), Array.Empty<object>())); EclipseCastTime = config.Bind<float>("Aswid - Eclipse", "Cast Time", 2f, new ConfigDescription("Seconds the player is rooted while casting.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>())); EclipseDuration = config.Bind<float>("Aswid - Eclipse", "Duration", 60f, new ConfigDescription("Seconds the forced night lasts.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 600f), Array.Empty<object>())); DevourCooldown = config.Bind<float>("Aswid - Devour", "Consume Cooldown", 5f, new ConfigDescription("How long one body stays drunk-dry, in seconds. A single death is reported to the devour more than once - by two damage patches, by the aura's execute, by a thrall's kill - and this is the window that keeps those from feeding you twice off the same corpse. It is per body, not per player: killing a whole pack at once devours every one of them. One second is used as the floor, so no corpse feeds you twice even at 0.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 60f), Array.Empty<object>())); EnslaveCooldown = config.Bind<float>("Aswid - Domination", "Enslave Cooldown", 900f, new ConfigDescription("Seconds between dominating a creature, tier 6+.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3600f), Array.Empty<object>())); ThrallLifetime = config.Bind<float>("Aswid - Domination", "Thrall Lifetime", 60f, new ConfigDescription("Seconds a dominated thrall survives before it dies on its own.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 600f), Array.Empty<object>())); BindEyes(config); BindClaws(config); } private static void BindClaws(ConfigFile config) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown ClawTintRed = config.Bind<float>("Aswid - Claws", "Claw Tint Red", 0.12f, new ConfigDescription("Multiplied into the claw model's own colours. All three near zero is what makes them read as almost black.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 30 } })); ClawTintGreen = config.Bind<float>("Aswid - Claws", "Claw Tint Green", 0.11f, new ConfigDescription("As above, green channel.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 29 } })); ClawTintBlue = config.Bind<float>("Aswid - Claws", "Claw Tint Blue", 0.13f, new ConfigDescription("As above, blue channel. A shade above the other two keeps the black cold rather than muddy.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), new object[1] { new ConfigurationManagerAttributes { Order = 28 } })); } private static void BindEyes(ConfigFile config) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Expected O, but got Unknown //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Expected O, but got Unknown //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_030f: Expected O, but got Unknown //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Expected O, but got Unknown //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Expected O, but got Unknown //IL_03ef: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Expected O, but got Unknown //IL_043d: Unknown result type (might be due to invalid IL or missing references) //IL_0447: Expected O, but got Unknown //IL_048b: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Expected O, but got Unknown //IL_04d9: Unknown result type (might be due to invalid IL or missing references) //IL_04e3: Expected O, but got Unknown //IL_0527: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Expected O, but got Unknown //IL_0563: Unknown result type (might be due to invalid IL or missing references) //IL_056d: Expected O, but got Unknown //IL_059f: Unknown result type (might be due to invalid IL or missing references) //IL_05a9: Expected O, but got Unknown EyeSourceModel = config.Bind<string>("Aswid - Eyes", "Eye Source Model", "Skeleton", new ConfigDescription("Which creature's eye lights to wear. The plain skeleton's are smaller and dimmer than the poison one's; Hildir's are its own. Changing this rebuilds the pair.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Skeleton", "Skeleton_Poison", "Skeleton_Hildir" }), new object[1] { new ConfigurationManagerAttributes { Order = 100 } })); EyeFinalStage = config.Bind<int>("Aswid - Eyes", "Eye Final Stage", 8, new ConfigDescription("The progression state at which the eyes turn red. Below it they burn the spectral green set out just under here; 8 is Fader, the last one.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 8), new object[1] { new ConfigurationManagerAttributes { Order = 95 } })); EarlyEyeColorRed = config.Bind<float>("Aswid - Eyes", "Early Eye Colour Red", 0.08f, new ConfigDescription("Red channel of the pre-final tint. Near zero: what little there is only keeps the green from reading as pure cyan.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), new object[1] { new ConfigurationManagerAttributes { Order = 94 } })); EarlyEyeColorGreen = config.Bind<float>("Aswid - Eyes", "Early Eye Colour Green", 1.4f, new ConfigDescription("Green channel of the pre-final tint - the one doing the work.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), new object[1] { new ConfigurationManagerAttributes { Order = 93 } })); EarlyEyeColorBlue = config.Bind<float>("Aswid - Eyes", "Early Eye Colour Blue", 0.5f, new ConfigDescription("Blue channel of the pre-final tint. A third of the green is what makes it read as cold and spectral rather than as a leaf.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), new object[1] { new ConfigurationManagerAttributes { Order = 92 } })); EarlyEyeGlowStrength = config.Bind<float>("Aswid - Eyes", "Early Eye Glow Strength", 0.8f, new ConfigDescription("How bright the green burns. Deliberately below the red's, so arriving at the last stage is a visible change and not just a hue swap.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), new object[1] { new ConfigurationManagerAttributes { Order = 91 } })); EyeColorRed = config.Bind<float>("Aswid - Eyes", "Eye Colour Red", 2f, new ConfigDescription("Red channel of the final-stage tint. Past 1 is HDR, which is what the bloom pass needs to make it glow rather than merely be red.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), new object[1] { new ConfigurationManagerAttributes { Order = 90 } })); EyeColorGreen = config.Bind<float>("Aswid - Eyes", "Eye Colour Green", 0.05f, new ConfigDescription("Green channel of the final-stage tint. Near zero is what keeps a bright red from washing out to pink.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), new object[1] { new ConfigurationManagerAttributes { Order = 89 } })); EyeColorBlue = config.Bind<float>("Aswid - Eyes", "Eye Colour Blue", 0.02f, new ConfigDescription("Blue channel of the final-stage tint. Near zero, same reason as green.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 8f), new object[1] { new ConfigurationManagerAttributes { Order = 88 } })); EyeGlowStrength = config.Bind<float>("Aswid - Eyes", "Eye Glow Strength", 1f, new ConfigDescription("How bright the final-stage red burns - the single knob for it, since the hue is already pure. Expect a floor: below the bloom threshold the eyes stop glowing and become flat dots.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 3f), new object[1] { new ConfigurationManagerAttributes { Order = 87 } })); EyeSizeMultiplier = config.Bind<float>("Aswid - Eyes", "Eye Size Multiplier", 1.1f, new ConfigDescription("Scales both sockets. 1 is the size the source creature wears them at.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 50f), new object[1] { new ConfigurationManagerAttributes { Order = 80 } })); EyeForwardOffset = config.Bind<float>("Aswid - Eyes", "Eye Forward Offset", 0.013f, new ConfigDescription("Moves both eyes out of (or into) the face, in metres. Positive is forward, out of the skull.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), new object[1] { new ConfigurationManagerAttributes { Order = 70 } })); EyeHeightOffset = config.Bind<float>("Aswid - Eyes", "Eye Height Offset", 0.004f, new ConfigDescription("Moves both eyes up or down the face, in metres. Positive is up.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), new object[1] { new ConfigurationManagerAttributes { Order = 69 } })); EyeSeparationOffset = config.Bind<float>("Aswid - Eyes", "Eye Separation Offset", 0.007f, new ConfigDescription("Pushes the two eyes apart (or together), in metres. Each moves away from the centre of the face, so this is half the change in the gap.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-0.5f, 0.5f), new object[1] { new ConfigurationManagerAttributes { Order = 68 } })); EyeRotationX = config.Bind<float>("Aswid - Eyes", "Eye Rotation X", 0f, new ConfigDescription("Turns both eyes on the spot. Only matters if the borrowed socket is flat enough to be seen edge-on.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { new ConfigurationManagerAttributes { Order = 60 } })); EyeRotationY = config.Bind<float>("Aswid - Eyes", "Eye Rotation Y", 22.068f, new ConfigDescription("As above, around the second axis - but MIRRORED: the left eye turns the opposite way, so the pair toes in or out together instead of both pointing off the same shoulder.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { new ConfigurationManagerAttributes { Order = 59 } })); EyeRotationZ = config.Bind<float>("Aswid - Eyes", "Eye Rotation Z", -180f, new ConfigDescription("As above, around the third axis. The default half turn is what rights the borrowed socket, which arrives upside down on a player's head bone.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-180f, 180f), new object[1] { new ConfigurationManagerAttributes { Order = 58 } })); EyeSmoke = config.Bind<bool>("Aswid - Eyes", "Eye Smoke", true, new ConfigDescription("Lights the smoke the creature carries inside its own sockets and leaves switched off. Tinted to match the eyes, so it turns with them at the last stage.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 50 } })); EyeFlatColorShader = config.Bind<bool>("Aswid - Eyes", "Eye Flat Colour Shader", false, new ConfigDescription("Escape hatch: if the borrowed material refuses the red tint, this repaints the sockets with a plain colour shader instead - guaranteed red, but the socket loses its own texture. Changing this rebuilds the pair.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 49 } })); } } [HarmonyPatch] public static class AswidExtraFoodUI { private static GameObject AswidFoodUIBase; private static Image AswidFoodIcon; private static GameObject AswidFoodTimeObj; [HarmonyPatch(typeof(Hud), "Awake")] [HarmonyPostfix] public static void Awake_Postfix(Hud __instance) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)__instance).transform.Find("hudroot/healthpanel"); if ((Object)(object)val == (Object)null) { return; } Transform val2 = val.Find("food1"); Transform val3 = val.Find("food2"); if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null)) { GameObject val4 = Object.Instantiate<GameObject>(((Component)val3).gameObject, val); ((Object)val4).name = "AswidExtraFoodSlot"; float num = val3.localPosition.y - val2.localPosition.y; val4.transform.localPosition = val3.localPosition + new Vector3(0f, num, 0f); AswidFoodUIBase = val4; Transform obj = val4.transform.Find("foodicon2"); AswidFoodIcon = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null); if ((Object)(object)AswidFoodIcon == (Object)null) { Transform obj2 = val4.transform.Find("icon"); AswidFoodIcon = ((obj2 != null) ? ((Component)obj2).GetComponent<Image>() : null); } Transform obj3 = val4.transform.Find("time"); AswidFoodTimeObj = ((obj3 != null) ? ((Component)obj3).gameObject : null); AswidFoodUIBase.SetActive(false); } } [HarmonyPatch(typeof(Hud), "UpdateFood")] [HarmonyPostfix] public static void UpdateFood_Postfix(Hud __instance) { if (!((Object)(object)AswidFoodUIBase == (Object)null)) { bool flag = BossProgressionManager.GetCurrentProgressionState() >= 8; if ((Object)(object)Player.m_localPlayer == (Object)null || !AswidRace.IsAswid() || !flag) { AswidFoodUIBase.SetActive(false); return; } AswidFoodUIBase.SetActive(true); UpdateSlotUI(Player.m_localPlayer, AswidFoodManager.ExtraFoods, AswidFoodIcon, AswidFoodTimeObj); } } private static void UpdateSlotUI(Player player, Dictionary<Player, Food> dict, Image icon, GameObject timeObj) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) if (dict.TryGetValue(player, out var value) && value != null) { if ((Object)(object)icon != (Object)null) { icon.sprite = value.m_item.GetIcon(); ((Component)icon).gameObject.SetActive(true); if (value.m_time >= value.m_item.m_shared.m_foodBurnTime * 0.5f) { ((Graphic)icon).color = new Color(1f, 1f, 1f, Mathf.Sin(Time.time * 10f) * 0.5f + 0.5f); } else { ((Graphic)icon).color = Color.white; } } if ((Object)(object)timeObj != (Object)null) { timeObj.SetActive(true); float num = value.m_item.m_shared.m_foodBurnTime - value.m_time; if (num < 0f) { num = 0f; } string text = ((num < 60f) ? (Mathf.CeilToInt(num) + "s") : (Mathf.CeilToInt(num / 60f) + "m")); Color color = (Color)((value.m_time >= value.m_item.m_shared.m_foodBurnTime * 0.5f) ? new Color(1f, 0.5f, 0.5f, Mathf.Sin(Time.time * 10f) * 0.5f + 0.5f) : Color.white); UpdateTextComponent(timeObj, text, color); } } else { if ((Object)(object)icon != (Object)null) { ((Component)icon).gameObject.SetActive(false); } if ((Object)(object)timeObj != (Object)null) { timeObj.SetActive(false); } } } private static void UpdateTextComponent(GameObject obj, string text, Color color) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) Text component = obj.GetComponent<Text>(); if ((Object)(object)component != (Object)null) { component.text = text; ((Graphic)component).color = color; } Component component2 = obj.GetComponent("TMPro.TMP_Text"); if ((Object)(object)component2 != (Object)null) { PropertyInfo property = ((object)component2).GetType().GetProperty("text"); if (property != null) { property.SetValue(component2, text, null); } PropertyInfo property2 = ((object)component2).GetType().GetProperty("color"); if (property2 != null) { property2.SetValue(component2, color, null); } } } } public static class AswidFoodManager { public static Dictionary<Player, Food> ExtraFoods = new Dictionary<Player, Food>(); public static void LoadFood(Player player) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown if ((Object)(object)player == (Object)null) { return; } if (!AswidRace.IsAswid()) { ClearFood(player); } else { if (!player.m_customData.ContainsKey("AswidFood_Prefab")) { return; } string text = player.m_customData["AswidFood_Prefab"]; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text); if ((Object)(object)itemPrefab == (Object)null) { return; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null)) { Food val = new Food(); val.m_item = component.m_itemData.Clone(); if (player.m_customData.TryGetValue("AswidFood_Time", out var value) && float.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { val.m_time = result; } val.m_health = component.m_itemData.m_shared.m_food; val.m_stamina = component.m_itemData.m_shared.m_foodStamina; val.m_eitr = component.m_itemData.m_shared.m_foodEitr; ExtraFoods[player] = val; } } } public static void SaveFood(Player player) { if (!((Object)(object)player == (Object)null)) { if (ExtraFoods.TryGetValue(player, out var value) && value != null && value.m_item != null) { player.m_customData["AswidFood_Prefab"] = ((Object)value.m_item.m_dropPrefab).name; player.m_customData["AswidFood_Time"] = value.m_time.ToString(CultureInfo.InvariantCulture); } else { player.m_customData.Remove("AswidFood_Prefab"); player.m_customData.Remove("AswidFood_Time"); } } } public static void ClearFood(Player player) { ExtraFoods.Remove(player); if ((Object)(object)player != (Object)null) { player.m_customData.Remove("AswidFood_Prefab"); player.m_customData.Remove("AswidFood_Time"); } } public static void SetExtraFood(Player player, ItemData item) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown Food val = new Food(); val.m_item = item.Clone(); val.m_time = 0f; val.m_health = item.m_shared.m_food; val.m_stamina = item.m_shared.m_foodStamina; val.m_eitr = item.m_shared.m_foodEitr; ExtraFoods[player] = val; SaveFood(player); } } [HarmonyPatch(typeof(VisEquipment), "UpdateColors")] public static class AswidSkinColorPatch { private static readonly Color SkinColor = new Color(0.96f, 0.97f, 0.98f, 1f); private static readonly Color HairColor = new Color(1f, 1f, 1f, 1f); public static void Postfix(VisEquipment __instance) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) if (!__instance.m_isPlayer) { return; } Player component = ((Component)__instance).GetComponent<Player>(); if ((Object)(object)component == (Object)null) { return; } string text = "Human"; ZNetView component2 = ((Component)component).GetComponent<ZNetView>(); string value; if ((Object)(object)component2 != (Object)null && component2.IsValid()) { text = component2.GetZDO().GetString("RacesOfValheim_Race", "Human"); } else if (component.m_customData != null && component.m_customData.TryGetValue("Race", out value)) { text = value; } AswidVisuals.ApplyEyes(component); if (text != "Aswid") { return; } int num = 0; if ((Object)(object)component2 != (Object)null && component2.IsValid()) { num = component2.GetZDO().GetInt("RacesOfValheim_AswidState", 0); } Color val = (Color)((num >= 8) ? new Color(0.02f, 0.02f, 0.02f, 1f) : HairColor); if ((Object)(object)__instance.m_bodyModel != (Object)null && (Object)(object)((Renderer)__instance.m_bodyModel).material != (Object)null) { ((Renderer)__instance.m_bodyModel).material.SetColor("_SkinColor", SkinColor); } GameObject value2 = Traverse.Create((object)__instance).Field("m_hairItemInstance").GetValue<GameObject>(); Renderer[] componentsInChildren; if ((Object)(object)value2 != (Object)null) { componentsInChildren = value2.GetComponentsInChildren<Renderer>(); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2.material != (Object)null) { val2.material.SetColor("_SkinColor", val); } } } GameObject value3 = Traverse.Create((object)__instance).Field("m_beardItemInstance").GetValue<GameObject>(); if (!((Object)(object)value3 != (Object)null)) { return; } componentsInChildren = value3.GetComponentsInChildren<Renderer>(); foreach (Renderer val3 in componentsInChildren) { if ((Object)(object)val3.material != (Object)null) { val3.material.SetColor("_SkinColor", val); } } } } [HarmonyPatch(typeof(SEMan), "AddStatusEffect", new Type[] { typeof(int), typeof(bool), typeof(int), typeof(float), typeof(short) })] public static class AswidSEManPatch { public static bool Prefix(SEMan __instance, ref int nameHash) { if ((Object)(object)Traverse.Create((object)__instance).Field<Character>("m_character").Value == (Object)(object)Player.m_localPlayer && AswidRace.IsAswid() && BossProgressionManager.GetCurrentProgressionState() >= 5 && nameHash == StringExtensionMethods.GetStableHashCode("Freezing")) { return false; } return true; } } [HarmonyPatch(typeof(Attack), "Start")] public static class Aswid_BloodMagicCost_Patch { private static float savedHealthCost; private static float savedHealthPercentage; public static void Prefix(Attack __instance, Humanoid character, ref bool __state) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Invalid comparison between Unknown and I4 ItemData value = Traverse.Create((object)__instance).Field("m_weapon").GetValue<ItemData>(); if (value == null) { value = Traverse.Create((object)__instance).Method("GetWeapon", Array.Empty<object>()).GetValue<ItemData>(); } if ((Object)(object)character == (Object)(object)Player.m_localPlayer && AswidRace.IsAswid() && value != null && (int)value.m_shared.m_skillType == 10) { __state = true; savedHealthCost = value.m_shared.m_attack.m_attackHealth; savedHealthPercentage = value.m_shared.m_attack.m_attackHealthPercentage; value.m_shared.m_attack.m_attackHealth = 0f; value.m_shared.m_attack.m_attackHealthPercentage = 0f; } else { __state = false; } } public static void Postfix(Attack __instance, Humanoid character, bool __state) { ItemData value = Traverse.Create((object)__instance).Field("m_weapon").GetValue<ItemData>(); if (value == null) { value = Traverse.Create((object)__instance).Method("GetWeapon", Array.Empty<object>()).GetValue<ItemData>(); } if (__state && value != null) { value.m_shared.m_attack.m_attackHealth = savedHealthCost; value.m_shared.m_attack.m_attackHealthPercentage = savedHealthPercentage; } } } public static class AswidPatches { public static Dictionary<ZDOID, float> RecentlyLifeDrained = new Dictionary<ZDOID, float>(); } [HarmonyPatch(typeof(Character), "Damage")] public static class Aswid_LifeDrainKill_Patch { public static void Postfix(Character __instance, HitData hit) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) if (hit != null) { ZDOID attacker = hit.m_attacker; Player localPlayer = Player.m_localPlayer; ZDOID? val = ((localPlayer != null) ? new ZDOID?(((Character)localPlayer).GetZDOID()) : ((ZDOID?)null)); if (val.HasValue && attacker == val.GetValueOrDefault()) { Debug.LogWarning((object)$"[Aswid_Patch] Local player damaged {((Object)__instance).name}. IsDead: {__instance.IsDead()}"); } } if (!__instance.IsDead() || hit == null || !((Object)(object)Player.m_localPlayer != (Object)null) || !(hit.m_attacker == ((Character)Player.m_localPlayer).GetZDOID())) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (AswidRace.IsAswid() && (Object)(object)component != (Object)null && component.IsValid()) { ZDOID zDOID = __instance.GetZDOID(); if (AswidPatches.RecentlyLifeDrained.TryGetValue(zDOID, out var value) && Time.time - value < 1f) { Debug.LogWarning((object)("[Aswid] " + ((Object)__instance).name + " died within 1s of LifeDrain. Consuming!")); AswidRace.TryConsumeMob(__instance, __instance.GetMaxHealth()); AswidPatches.RecentlyLifeDrained.Remove(zDOID); } } } } [HarmonyPatch(typeof(Character), "Awake")] public static class Aswid_Awake_Patch { public static void Postfix(Character __instance) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 if ((Object)(object)((Component)__instance).GetComponent<MonsterAI>() != (Object)null && !__instance.IsBoss() && (int)__instance.m_faction != 4 && (Object)(object)((Component)__instance).GetComponent<Tameable>() == (Object)null && (Object)(object)((Component)__instance).GetComponent<AswidThrall>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<AswidThrall>(); } } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] public static class Aswid_ArmorBonus_Patch { public static void Postfix(Player __instance, ref float __result) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && AswidRace.IsAswid()) { int currentProgressionState = BossProgressionManager.GetCurrentProgressionState(); float num = (((Object)(object)EnvMan.instance != (Object)null && EnvMan.IsNight()) ? AswidConfig.NightMultiplier.Value : 1f); __result += AswidConfig.ArmorBonusPerState.Value * (float)currentProgressionState * num; } } } [HarmonyPatch] public static class Aswid_DamageBonus_Patch { [HarmonyTargetMethod] public static MethodBase TargetMethod() { return AccessTools.GetDeclaredMethods(typeof(ItemData)).FirstOrDefault((MethodInfo m) => m.Name == "GetDamage" && m.ReturnType == typeof(DamageTypes)); } public static void Postfix(ItemData __instance, ref DamageTypes __result) { if (!((Object)(object)Player.m_localPlayer != (Object)null) || !AswidRace.IsAswid() || !((Humanoid)Player.m_localPlayer).GetInventory().ContainsItem(__instance)) { return; } int currentProgressionState = BossProgressionManager.GetCurrentProgressionState(); if (currentProgressionState > 0) { float num = (((Object)(object)EnvMan.instance != (Object)null && EnvMan.IsNight()) ? AswidConfig.NightMultiplier.Value : 1f); float num2 = AswidConfig.DamageBonusPerState.Value * (float)currentProgressionState * num; if (__result.m_slash > 0f) { __result.m_slash += num2; } if (__result.m_blunt > 0f) { __result.m_blunt += num2; } if (__result.m_pierce > 0f) { __result.m_pierce += num2; } if (__result.m_chop > 0f) { __result.m_chop += num2; } if (__result.m_pickaxe > 0f) { __result.m_pickaxe += num2; } } } } [HarmonyPatch(typeof(Humanoid), "StartAttack")] public static class Aswid_Attack_Patch { public static bool Prefix(Humanoid __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { if ((Object)(object)((Component)__instance).GetComponentInChildren<BatFormBehavior>() != (Object)null) { return false; } if (((Character)__instance).GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_MistForm"))) { return false; } } return true; } } [HarmonyPatch(typeof(Character), "SetRun")] public static class Aswid_Run_Patch { public static void Prefix(Character __instance, ref bool run) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && ((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_MistForm"))) { run = false; } } } [HarmonyPatch(typeof(Character), "Jump")] public static class Aswid_Jump_Patch { public static bool Prefix(Character __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && ((Character)Player.m_localPlayer).GetSEMan().HaveStatusEffect(StringExtensionMethods.GetStableHashCode("SE_MistForm"))) { return false; } return true; } } [HarmonyPatch(typeof(Player), "OnSpawned")] public static class Aswid_PlayerOnSpawned_Patch { public static void Postfix(Player __instance) { if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer) { AswidFoodManager.LoadFood(__instance); } } } [HarmonyPatch(typeof(Player), "CanConsumeItem")] public static class Aswid_CanConsumeItem_Patch { public static void Postfix(Player __instance, ItemData item, ref bool __result) { if (!((Object)(object)__instance == (Object)(object)Player.m_localPlayer) || !AswidRace.IsAswid() || !AswidBloodRefinery.IsAswidMeal(item)) { return; } IList value = Traverse.Create((object)__instance).Field("m_foods").GetValue<IList>(); if (value == null) { return; } if (value.Count >= 3) { bool num = BossProgressionManager.GetCurrentProgressionState() >= 8; Food value2; bool flag = AswidFoodManager.ExtraFoods.TryGetValue(__instance, out value2) && value2 != null; if (num && (!flag || value2.m_time >= value2.m_item.m_shared.m_foodBurnTime * 0.5f)) { __result = true; return; } bool flag2 = false; foreach (object item2 in value) { Food val = (Food)((item2 is Food) ? item2 : null); if (val != null && val.m_item.m_shared.m_name == item.m_shared.m_name && val.CanEatAgain()) { flag2 = true; break; } } if (flag2) { __result = true; } else { __result = false; } } else { __result = true; } } } [HarmonyPatch(typeof(Player), "EatFood")] public static class Aswid_EatFood_Patch { private static List<object> hiddenFoods = new List<object>(); public static bool Prefix(Player __instance, ItemData item, ref bool __result) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) hiddenFoods.Clear(); if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && AswidRace.IsAswid() && AswidBloodRefinery.IsAswidMeal(item)) { IList value = Traverse.Create((object)__instance).Field("m_foods").GetValue<IList>(); if (value != null) { if (value.Count >= 3) { if (BossProgressionManager.GetCurrentProgressionState() >= 8 && (!AswidFoodManager.ExtraFoods.TryGetValue(__instance, out var value2) || value2 == null || value2.m_time >= value2.m_item.m_shared.m_foodBurnTime * 0.5f)) { AswidFoodManager.SetExtraFood(__instance, item); EffectList value3 = Traverse.Create((object)__instance).Field("m_consumeItemEffects").GetValue<EffectList>(); if (value3 != null) { value3.Create(((Component)__instance).transform.position, Quaternion.identity, ((Component)__instance).transform, 1f, -1, default(ZDOID)); } ZSyncAnimation value4 = Traverse.Create((object)__instance).Field("m_zanim").GetValue<ZSyncAnimation>(); if ((Object)(object)value4 != (Object)null) { value4.SetTrigger("eat"); } if (item.m_shared.m_food > 0f) { ((Character)__instance).Heal(item.m_shared.m_food, true); } __result = true; return false; } bool flag = false; foreach (object item2 in value) { Food val = (Food)((item2 is Food) ? item2 : null); if (val != null && val.m_item.m_shared.m_name == item.m_shared.m_name && val.CanEatAgain()) { RaceFoodRefresh.Refresh(__instance, val, item); flag = true; break; } } if (flag) { __result = true; return false; } __result = false; return false; } for (int num = value.Count - 1; num >= 0; num--) { object obj = value[num]; ItemData value5 = Traverse.Create(obj).Field("m_item").GetValue<ItemData>(); if (value5 != null && value5.m_shared.m_name == item.m_shared.m_name) { hiddenFoods.Add(obj); value.RemoveAt(num); } } } } return true; } public static void Postfix(Player __instance, ItemData item, ref bool __result) { if (hiddenFoods.Count <= 0) { return; } IList value = Traverse.Create((object)__instance).Field("m_foods").GetValue<IList>(); if (value != null) { foreach (object hiddenFood in hiddenFoods) { value.Add(hiddenFood); } } hiddenFoods.Clear(); } } [HarmonyPatch(typeof(Tameable), "GetHoverText")] public static class Aswid_TameHoverText_Patch { public static void Postfix(Tameable __instance, ref string __result) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null || !AswidRace.IsAswid()) { return; } Character component = ((Component)__instance).GetComponent<Character>(); if (component == null || !component.IsTamed()) { string text = ((Object)((Component)__instance).gameObject).name.ToLower(); int currentProgressionState = BossProgressionManager.GetCurrentProgressionState(); bool flag = false; if (currentProgressionState >= 2 && text.Contains("boar")) { flag = true; } if (currentProgressionState >= 5 && text.Contains("wolf")) { flag = true; } if (currentProgressionState >= 6 && text.Contains("lox")) { flag = true; } if (currentProgressionState >= 8 && text.Contains("asksvin")) { flag = true; } if (flag) { string obj = __result; KeyboardShortcut value = AswidConfig.TameKey.Value; __result = obj + $"\n[<color=yellow><b>{((KeyboardShortcut)(ref value)).MainKey}</b></color>] Tame"; } } } } [HarmonyPatch(typeof(Hud), "UpdateStamina")] public static class Aswid_HideStamina_Patch { public static bool Prefix(Hud __instance, Player player) { if ((Object)(object)player == (Object)(object)Player.m_localPlayer && (AswidRace.IsAswid() || DraughRace.IsDraugh())) { if ((Object)(object)__instance.m_staminaBar2Root != (Object)null && ((Component)__instance.m_staminaBar2Root).gameObject.activeSelf) { ((Component)__instance.m_staminaBar2Root).gameObject.SetActive(false); } return false; } return true; } } [HarmonyPatch(typeof(StatusEffect), "Setup")] public static class Aswid_ColdStatus_Patch { public static void Prefix(StatusEffect __instance, Character character) { if ((Object)(object)character == (Object)(object)Player.m_localPlayer && AswidRace.IsAswid() && (((Object)__instance).name.Contains("Cold") || __instance.m_name == "$se_cold_name")) { ItemDrop prefab = Cache.GetPrefab<ItemDrop>("TrophyWraith"); if ((Object)(object)prefab != (Object)null && prefab.m_itemData.m_shared.m_icons.Length != 0) { __instance.m_icon = prefab.m_itemData.m_shared.m_icons[0]; } else { __instance.m_icon = null; } __instance.m_name = "Night Aura"; __instance.m_startMessage = ""; __instance.m_tooltip = "The cold strengthens your beastly senses."; SE_Stats val = (SE_Stats)(object)((__instance is SE_Stats) ? __instance : null); if (val != null) { val.m_healthRegenMultiplier = 1f; val.m_staminaRegenMultiplier = 1f; val.m_staminaDrainPerSec = 0f; val.m_speedModifier = 0f; } } } } [HarmonyPatch(typeof(Player), "Update")] public static class Aswid_PlayerUpdate_Patch { public static void Postfix(Player __instance) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if (!((Object)(object)component != (Object)null) || !component.IsValid() || !(component.GetZDO().GetString("RacesOfValheim_Race", "Human") == "Aswid")) { return; } if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer && RaceInput.Allowed && AswidConfig.ToggleDevourKey.Value.IsDownIgnoringHeldKeys()) { AswidRace.DevourEnabled = !AswidRace.DevourEnabled; AswidRace.AuraEnabled = AswidRace.DevourEnabled; string text = (AswidRace.DevourEnabled ? "Vampiric Aura: ENABLED" : "Vampiric Aura: DISABLED"); ((Character)__instance).Message((MessageType)2, text, 0, (Sprite)null, false); } AswidProgression.AswidRules rules = AswidProgression.GetRules(BossProgressionManager.GetCurrentProgressionState()); if ((Object)(object)AswidRace.Instance != (Object)null && !AswidRace.Instance.IsTransformed) { if (rules != null && rules.HasSurtlingForm) { ((Component)__instance).transform.localScale = new Vector3(1.1f, 1.1f, 1.1f); } else { ((Component)__instance).transform.localScale = Vector3.one; } } } } [HarmonyPatch(typeof(VisEquipment), "UpdateVisuals")] public static class Aswid_MultiplayerVisuals_Patch { public static void Postfix(VisEquipment __instance) { //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) if (!__instance.m_isPlayer) { return; } Player component = ((Component)__instance).GetComponent<Player>(); if ((Object)(object)component == (Object)null || ((Character)component).IsOwner()) { return; } ZNetView component2 = ((Component)component).GetComponent<ZNetView>(); if (!((Object)(object)component2 != (Object)null) || !component2.IsValid() || !(component2.GetZDO().GetString("RacesOfValheim_Race", "Human") == "Aswid")) { return; } bool flag = component2.GetZDO().GetBool("Aswid_IsBatForm", false); bool flag2 = component2.GetZDO().GetBool("Aswid_IsMistForm", false); Transform playerVisual = ((Component)component).transform.Find("Visual"); Transform val = ((Component)component).transform.Find("AswidBody_Bat"); if (flag && (Object)(object)val == (Object)null) { GameObject prefab = Cache.GetPrefab<GameObject>("Bat"); if ((Object)(object)prefab != (Object)null) { Animator componentInChildren = prefab.GetComponentInChildren<Animator>(); GameObject val2 = ((componentInChildren != null) ? ((Component)componentInChildren).gameObject : null); if ((Object)(object)val2 != (Object)null) { GameObject obj = Object.Instantiate<GameObject>(val2, ((Component)component).transform.position, ((Component)component).transform.rotation, ((Component)component).transform); ((Object)obj).name = "AswidBody_Bat"; obj.transform.localPosition = Vector3.zero; } } } else if (!flag && (Object)(object)val != (Object)null) { Object.Destroy((Object)(object)((Component)val).gameObject); } Transform val3 = ((Component)component).transform.Find("AswidBody_Mist"); if (flag2 && (Object)(object)val3 == (Object)null) { GameObject prefab2 = Cache.GetPrefab<GameObject>("Wraith"); if ((Object)(object)prefab2 != (Object)null) { Transform obj2 = prefab2.transform.Find("Visual"); GameObject val4 = ((obj2 != null) ? ((Component)obj2).gameObject : null); if ((Object)(object)val4 != (Object)null) { GameObject obj3 = Object.Instantiate<GameObject>(val4, ((Component)component).transform.position, ((Component)component).transform.rotation, ((Component)component).transform); ((Object)obj3).name = "AswidBody_Mist"; obj3.transform.localPosition = Vector3.zero; obj3.transform.localScale = Vector3.one; Renderer[] componentsInChildren = obj3.GetComponentsInChildren<Renderer>(); foreach (Renderer val5 in componentsInChildren) { if ((Object)(object)val5.material != (Object)null && val5.material.HasProperty("_Color")) { Color color = val5.material.GetColor("_Color"); color.a = 0.3f; val5.material.SetColor("_Color", color); } } } } } else if (!flag2 && (Object)(object)val3 != (Object)null) { Object.Destroy((Object)(object)((Component)val3).gameObject); } if (flag || flag2) { PlayerVisualHider.Hide(playerVisual, "aswid-remote-form"); } else { PlayerVisualHider.Show(playerVisual, "aswid-remote-revert"); } } } [HarmonyPatch(typeof(Character), "Damage")] public static class Aswid_Damage_Patch { [HarmonyPatch(typeof(Character), "TryUseEitr")] public static class Character_TryUseEitr_Patch { public static bool Prefix(Character __instance, ref bool __result) { if (!IsLocalAswidWieldingBloodMagic(__instance)) { return true; } __result = true; return false; } } [HarmonyPatch(typeof(Player), "HaveEitr")] public static class Player_HaveEitr_Patch { public static void Postfix(Player __instance, ref bool __result) { if (IsLocalAswidWieldingBloodMagic((Character)(object)__instance)) { __result = true; } } } [HarmonyPatch(typeof(Player), "UseEitr")] public static class Player_UseEitr_Patch { public static bool Prefix(Player __instance) { if (IsLocalAswidWieldingBloodMagic((Character)(object)__instance)) { return false; } return true; } } [HarmonyPatch(typeof(Skills), "RaiseSkill")] public static class Aswid_Skills_RaiseSkill_Patch { public static void Prefix(Skills __instance, SkillType skillType, ref float factor) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 Player value = Traverse.Create((object)__instance).Field("m_player").GetValue<Player>(); if ((Object)(object)value != (Object)null && (Object)(object)value == (Object)(object)Player.m_localPlayer && AswidRace.IsAswid() && (int)skillType == 10) { factor *= AswidConfig.BloodMagicSkillGainMultiplier.Value; } } } public static void Prefix(Character __instance, HitData hit, out float __state) { __state = (((Object)(object)__instance != (Object)null) ? __instance.GetHealth() : 0f); } public static void Postfix(Character __instance, HitData hit, float __state) { if (hit == null || (Object)(object)__instance == (Object)null || __instance.IsPlayer()) { return; } Character attacker = hit.GetAttacker(); if (!((Object)(object)attacker != (Object)null) || !attacker.IsPlayer() || !((Object)(object)attacker == (Object)(object)Player.m_localPlayer)) { return; } ZNetView component = ((Component)attacker).GetComponent<ZNetView>(); if (!((Object)(object)component != (Object)null) || !component.IsValid() || !(component.GetZDO().GetString("RacesOfValheim_Race", "Human") == "Aswid")) { return; } float num = hit.m_damage.m_blunt + hit.m_damage.m_slash + hit.m_damage.m_pierce + hit.m_damage.m_chop + hit.m_damage.m_pickaxe + hit.m_damage.m_damage; if (num > 0f) { float num2 = AswidProgression.GetRules(BossProgressionManager.GetCurrentProgressionState()).LifestealPercent; if ((Object)(object)EnvMan.instance != (Object)null && EnvMan.IsNight()) { num2 *= AswidConfig.NightMultiplier.Value; } if (num2 > 0f) { float num3 = num * num2; ((Character)Player.m_localPlayer).Heal(num3, true); } } if (__state > 0f && __instance.GetHealth() <= 0f && num > 0f) { AswidRace.TryConsumeMob(__instance, __instance.GetMaxHealth()); } } public static bool IsLocalAswidWieldingBloodMagic(Character character) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Invalid comparison between Unknown and I4 if ((Object)(object)character == (Object)null || (Object)(object)character != (Object)(object)Player.m_localPlayer) { return false; } if (!AswidRace.IsAswid()) { return false; } ItemData currentWeapon = ((Humanoid)Player.m_localPlayer).GetCurrentWeapon(); if (currentWeapon != null && currentWeapon.m_shared != null)