Please disclose if your mod was created primarily 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 Fartheim v1.2.1
Fartheim.dll
Decompiled 4 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("Fartheim")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Fartheim")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("2483fa13-8406-413c-8bad-a5bf7982d98d")] [assembly: AssemblyFileVersion("1.2.1")] [assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.1.0")] [module: UnverifiableCode] namespace Fartheim; public class RecipeStub { public class RequirementStub { public string Component; public int Amount; public int AmountPerLevel; public bool Recoverable = true; private RequirementStub() { } public static RequirementStub Parse(string def) { string[] array = def.Split(new char[1] { ':' }); if (array.Length < 2) { return null; } RequirementStub requirementStub = new RequirementStub(); requirementStub.Component = array[0]; int.TryParse(array[1], out requirementStub.Amount); if (array.Length > 2) { int.TryParse(array[2], out requirementStub.AmountPerLevel); } return requirementStub; } } public ItemDrop Item; public string CraftingStation; public string RepairStation; public int MinStationLevel = 1; public List<RequirementStub> Requirements = new List<RequirementStub>(); public string Name => "Recipe" + ((Object)Item).name; } [HarmonyPatch] public static class AssetHelper { public static readonly List<GameObject> Prefabs = new List<GameObject>(); private static readonly List<RecipeStub> RecipeStubs = new List<RecipeStub>(); private static readonly List<KeyValuePair<string, StatusEffect>> StatusEffects = new List<KeyValuePair<string, StatusEffect>>(); public static AssetBundle LoadAssetBundle(string name) { Assembly callingAssembly = Assembly.GetCallingAssembly(); return AssetBundle.LoadFromStream(callingAssembly.GetManifestResourceStream(callingAssembly.GetName().Name + "." + name)); } public static void RegisterPrefab(GameObject prefab) { Prefabs.Add(prefab); Object.DontDestroyOnLoad((Object)(object)prefab); } public static void RegisterRecipe(RecipeStub rs) { RecipeStubs.Add(rs); } public static void RegisterStatusEffect<T>(string name) where T : StatusEffect { StatusEffects.Add(new KeyValuePair<string, StatusEffect>(name, (StatusEffect)(object)ScriptableObject.CreateInstance<T>())); } public static RecipeStub GetRecipeStub(string itemName) { return RecipeStubs.Find((RecipeStub r) => ((Object)r.Item).name == itemName); } public static Recipe BuildRecipe(RecipeStub rs, ObjectDB odb) { //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown Recipe val = ScriptableObject.CreateInstance<Recipe>(); val.m_item = rs.Item; GameObject itemPrefab = odb.GetItemPrefab(rs.CraftingStation); val.m_craftingStation = ((itemPrefab != null) ? itemPrefab.GetComponentInChildren<CraftingStation>(true) : null); if ((Object)(object)val.m_craftingStation == (Object)null) { ZNetScene instance = ZNetScene.instance; object craftingStation; if (instance == null) { craftingStation = null; } else { GameObject prefab = instance.GetPrefab(rs.CraftingStation); craftingStation = ((prefab != null) ? prefab.GetComponentInChildren<CraftingStation>(true) : null); } val.m_craftingStation = (CraftingStation)craftingStation; if ((Object)(object)val.m_craftingStation == (Object)null) { Plugin.Log.LogInfo((object)("BuildRecipe couldn't find crafting station " + rs.CraftingStation + " for " + rs.Name)); return null; } } if (!string.IsNullOrWhiteSpace(rs.RepairStation)) { GameObject itemPrefab2 = odb.GetItemPrefab(rs.RepairStation); val.m_repairStation = ((itemPrefab2 != null) ? itemPrefab2.GetComponentInChildren<CraftingStation>(true) : null); if ((Object)(object)val.m_repairStation == (Object)null) { ZNetScene instance2 = ZNetScene.instance; object repairStation; if (instance2 == null) { repairStation = null; } else { GameObject prefab2 = instance2.GetPrefab(rs.RepairStation); repairStation = ((prefab2 != null) ? prefab2.GetComponentInChildren<CraftingStation>(true) : null); } val.m_repairStation = (CraftingStation)repairStation; if ((Object)(object)val.m_repairStation == (Object)null) { Plugin.Log.LogInfo((object)("BuildRecipe couldn't find declared repair station " + rs.RepairStation + " for " + rs.Name)); return null; } } if ((Object)(object)val.m_repairStation == (Object)null) { return null; } } val.m_minStationLevel = Mathf.Max(1, rs.MinStationLevel); List<Requirement> list = new List<Requirement>(); foreach (RecipeStub.RequirementStub requirement in rs.Requirements) { GameObject itemPrefab3 = odb.GetItemPrefab(requirement.Component); ItemDrop val2 = ((itemPrefab3 != null) ? itemPrefab3.GetComponentInChildren<ItemDrop>(true) : null); if (!Object.op_Implicit((Object)(object)val2)) { Plugin.Log.LogInfo((object)("BuildRecipe couldn't get requirement component " + requirement.Component + " for " + rs.Name)); return null; } Requirement val3 = new Requirement(); val3.m_resItem = val2; val3.m_amount = requirement.Amount; val3.m_amountPerLevel = requirement.AmountPerLevel; val3.m_recover = requirement.Recoverable; list.Add(val3); } val.m_resources = list.ToArray(); return val; } private static void PopulateObjectDB(ObjectDB odb) { if (Prefabs.Count > 0 && !Object.op_Implicit((Object)(object)odb.m_items.Find((GameObject p) => ((Object)p).name == ((Object)Prefabs[0]).name))) { foreach (GameObject prefab in Prefabs) { if (Object.op_Implicit((Object)(object)prefab.GetComponentInChildren<ItemDrop>(true))) { odb.m_items.Add(prefab); } } odb.UpdateRegisters(); } if (RecipeStubs.Count > 0 && !Object.op_Implicit((Object)(object)odb.GetRecipe(RecipeStubs[0].Item.m_itemData))) { foreach (RecipeStub recipeStub in RecipeStubs) { Recipe val = BuildRecipe(recipeStub, odb); if (Object.op_Implicit((Object)(object)val)) { odb.m_recipes.Add(val); Plugin.Log.LogInfo((object)("Added recipe " + ((Object)val).name)); } } } if (StatusEffects.Count <= 0 || Object.op_Implicit((Object)(object)odb.GetStatusEffect(StringExtensionMethods.GetStableHashCode(StatusEffects[0].Key)))) { return; } foreach (KeyValuePair<string, StatusEffect> statusEffect in StatusEffects) { odb.m_StatusEffects.Add(statusEffect.Value); } } public static void UpdateRecipes() { foreach (RecipeStub recipeStub in RecipeStubs) { Recipe r = BuildRecipe(recipeStub, ObjectDB.instance); if (Object.op_Implicit((Object)(object)r)) { Recipe val = ObjectDB.instance.m_recipes.Find((Recipe rt) => ((Object)rt).name == ((Object)r).name); if (Object.op_Implicit((Object)(object)val)) { ObjectDB.instance.m_recipes.Remove(val); } ObjectDB.instance.m_recipes.Add(r); Plugin.Log.LogInfo((object)("Updated recipe " + ((Object)r).name)); } } } [HarmonyPostfix] [HarmonyPatch(typeof(ObjectDB), "Awake")] public static void AwakePostfix(ObjectDB __instance) { PopulateObjectDB(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static void CopyOtherDBPostfix(ObjectDB __instance, ObjectDB other) { PopulateObjectDB(__instance); } [HarmonyPostfix] [HarmonyPatch(typeof(ZNetScene), "Awake")] public static void AwakePostfix(ZNetScene __instance) { if (Prefabs.Count == 0) { return; } foreach (GameObject prefab in Prefabs) { __instance.m_namedPrefabs[StringExtensionMethods.GetStableHashCode(((Object)prefab).name)] = prefab; } } } public class Farter : MonoBehaviour { private static string[] BoneRoots = new string[3] { "Hip", "Hips", "l_hip" }; private AudioSource AS; private Character Char; private bool Crouching; private float TimeSinceLastFart; private float FartTimerDelay; private ParticleSystem PS; private float SizeScalar = 1f; public void Awake() { //IL_0381: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03a8: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) Char = ((Component)this).GetComponentInChildren<Character>(); AS = ((Component)this).gameObject.AddComponent<AudioSource>(); AS.playOnAwake = false; AS.maxDistance = Plugin.FartNoiseRange.Value; AS.rolloffMode = (AudioRolloffMode)1; AS.spatialBlend = 1f; AS.outputAudioMixerGroup = AudioMan.m_instance.m_ambientMixer; Transform val = null; if (Object.op_Implicit((Object)(object)Char) && !((Object)((Component)this).gameObject).name.StartsWith("Skeleton") && !((Object)((Component)this).gameObject).name.StartsWith("Blob")) { string bone = null; SkinnedMeshRenderer componentInChildren = ((Component)this).gameObject.GetComponentInChildren<SkinnedMeshRenderer>(); if (Object.op_Implicit((Object)(object)componentInChildren)) { if (((Object)((Component)this).gameObject).name.StartsWith("Boar") || ((Object)((Component)this).gameObject).name.StartsWith("Wolf")) { bone = "Pelvis"; } else if (((Object)((Component)this).gameObject).name.StartsWith("Deer")) { bone = "L Thigh"; } else if (((Object)((Component)this).gameObject).name.StartsWith("Dragon")) { bone = "Hips.001"; } else if (((Object)((Component)this).gameObject).name.StartsWith("Draugr")) { bone = "LeftHip"; } else if (((Object)((Component)this).gameObject).name.StartsWith("Eikthyr")) { bone = "Bone.009"; } else if (((Object)((Component)this).gameObject).name.StartsWith("Hatchling")) { bone = "Spine1"; } else if (((Object)((Component)this).gameObject).name.StartsWith("Surtling")) { bone = "mixamorig:Hips"; } else if (((Object)((Component)this).gameObject).name.StartsWith("Troll")) { bone = "Spine0"; } if (bone != null) { val = ((IEnumerable<Transform>)componentInChildren.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => ((Object)t).name == bone)); if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)this).transform; } } else { val = ((IEnumerable<Transform>)componentInChildren.bones).FirstOrDefault((Func<Transform, bool>)((Transform t) => BoneRoots.Contains(((Object)t).name))); } } } if (!Object.op_Implicit((Object)(object)val)) { val = ((Component)this).transform; } GameObject val2 = Object.Instantiate<GameObject>(Plugin.FartSystemPrefab, val); PS = val2.GetComponent<ParticleSystem>(); CapsuleCollider componentInChildren2 = ((Component)this).gameObject.GetComponentInChildren<CapsuleCollider>(); if (Object.op_Implicit((Object)(object)componentInChildren2)) { double num = componentInChildren2.radius; double num2 = componentInChildren2.height; double num3 = 4.1887902047863905 * Math.Pow(num, 3.0); if (num2 - 2.0 * num > 0.0) { num3 += Math.PI * Math.Pow(num, 2.0); } SizeScalar = (float)Math.Sqrt(num3); } else { SphereCollider componentInChildren3 = ((Component)this).gameObject.GetComponentInChildren<SphereCollider>(); if (Object.op_Implicit((Object)(object)componentInChildren3)) { double d = 4.1887902047863905 * Math.Pow(componentInChildren3.radius, 3.0); SizeScalar = (float)Math.Sqrt(d); } } if (SizeScalar != 1f) { MainModule main = PS.main; ((MainModule)(ref main)).startSpeedMultiplier = SizeScalar; ((MainModule)(ref main)).startSizeMultiplier = SizeScalar; VelocityOverLifetimeModule velocityOverLifetime = PS.velocityOverLifetime; ((VelocityOverLifetimeModule)(ref velocityOverLifetime)).speedModifierMultiplier = SizeScalar; } } private void Fart() { //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) List<AudioClip> list = ((Object.op_Implicit((Object)(object)Char) && Char.InWater()) ? Plugin.WetFarts : Plugin.DryFarts); int index = ((!Object.op_Implicit((Object)(object)Char) || !Char.IsPlayer() || !Plugin.BunsOfSteel.Value) ? Mathf.Min(list.Count - 1, (int)(Random.value * (float)list.Count)) : Mathf.Min(list.Count - 1, (int)(TimeSinceLastFart / Plugin.MaxFartTime.Value * (float)list.Count))); AudioClip val = list[index]; AS.pitch = (0.75f + Random.value * 0.5f) / SizeScalar; AS.PlayOneShot(val, Mathf.Clamp(TimeSinceLastFart / Plugin.MaxFartTime.Value, 0.25f, 1f)); FartTimerDelay = val.length + 1f + Random.value; TimeSinceLastFart = 0f; ((Component)PS).transform.rotation = Quaternion.LookRotation(-((Component)this).transform.forward, ((Component)this).transform.up); MainModule main = PS.main; ((MainModule)(ref main)).duration = val.length; PS.Play(); } public void Update() { //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return; } if (!Object.op_Implicit((Object)(object)Char) || !Char.IsPlayer() || !Plugin.BunsOfSteel.Value) { if (FartTimerDelay <= 0f) { TimeSinceLastFart += Time.deltaTime; float num = Random.value * Plugin.MaxFartTime.Value; if (TimeSinceLastFart >= num) { Fart(); } else { FartTimerDelay += 0.5f + Random.value; } } else { FartTimerDelay -= Time.deltaTime; if (TimeSinceLastFart > 0f) { TimeSinceLastFart += Time.deltaTime; } } } else { TimeSinceLastFart += Time.deltaTime; } if (Object.op_Implicit((Object)(object)Char) && Char.IsCrouching()) { if (!Crouching) { Crouching = true; Fart(); } } else if (Crouching) { Crouching = false; } if (Object.op_Implicit((Object)(object)PS)) { ForceOverLifetimeModule forceOverLifetime = PS.forceOverLifetime; if (Object.op_Implicit((Object)(object)Char) && (Char.InInterior() || (Char.IsPlayer() && ((Player)/*isinst with value type is only supported in some contexts*/).InShelter()))) { ((ForceOverLifetimeModule)(ref forceOverLifetime)).x = MinMaxCurve.op_Implicit(0f); ((ForceOverLifetimeModule)(ref forceOverLifetime)).z = MinMaxCurve.op_Implicit(0f); } else { Vector3 windForce = EnvMan.instance.GetWindForce(); ((ForceOverLifetimeModule)(ref forceOverLifetime)).x = MinMaxCurve.op_Implicit(windForce.x * 3f); ((ForceOverLifetimeModule)(ref forceOverLifetime)).z = MinMaxCurve.op_Implicit(windForce.z * 3f); } } } } [HarmonyPatch(typeof(Character))] public class CharacterPatches { [HarmonyPostfix] [HarmonyPatch("Awake")] public static void AwakePostfix(Character __instance) { if (!Plugin.OnlyPlayers.Value || __instance is Player) { ((Component)__instance).gameObject.AddComponent<Farter>(); } } } [HarmonyPatch(typeof(RandomFlyingBird))] public class RandomFlyingBirdPatches { [HarmonyPostfix] [HarmonyPatch("Awake")] public static void AwakePostfix(RandomFlyingBird __instance) { if (Plugin.ShouldBirdsFart.Value) { ((Component)__instance).gameObject.AddComponent<Farter>(); } } } [BepInPlugin("pfhoenix.fartheim", "Fartheim", "1.2.1")] public class Plugin : BaseUnityPlugin { public const string Version = "1.2.1"; public const string ModName = "Fartheim"; private Harmony _Harmony; public static ManualLogSource Log; private AssetBundle AB; public static List<AudioClip> DryFarts = new List<AudioClip>(); public static List<AudioClip> WetFarts = new List<AudioClip>(); public static GameObject FartSystemPrefab; public static ConfigEntry<float> MaxFartTime; public static ConfigEntry<float> FartNoiseRange; public static ConfigEntry<bool> BunsOfSteel; public static ConfigEntry<bool> ShouldBirdsFart; public static ConfigEntry<bool> OnlyPlayers; private void Awake() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Log = new ManualLogSource((string)null); AB = AssetHelper.LoadAssetBundle("fartheim"); AudioClip[] array = AB.LoadAllAssets<AudioClip>(); foreach (AudioClip val in array) { if (((Object)val).name.Contains("water")) { WetFarts.Add(val); } else { DryFarts.Add(val); } } if (DryFarts.Count > 0) { DryFarts = DryFarts.OrderBy((AudioClip f) => f.length).ToList(); } if (WetFarts.Count > 0) { WetFarts = WetFarts.OrderBy((AudioClip f) => f.length).ToList(); } FartSystemPrefab = AB.LoadAsset<GameObject>("Assets\\FartSystem.prefab"); AssetHelper.RegisterPrefab(FartSystemPrefab); MaxFartTime = ((BaseUnityPlugin)this).Config.Bind<float>("Farts", "Maximum Fart Time", 30f, (ConfigDescription)null); FartNoiseRange = ((BaseUnityPlugin)this).Config.Bind<float>("Farts", "Fart Noise Range", 32f, (ConfigDescription)null); BunsOfSteel = ((BaseUnityPlugin)this).Config.Bind<bool>("Farts", "Players Only Fart When Crouching", true, (ConfigDescription)null); ShouldBirdsFart = ((BaseUnityPlugin)this).Config.Bind<bool>("Farts", "Should Birds Fart", true, (ConfigDescription)null); OnlyPlayers = ((BaseUnityPlugin)this).Config.Bind<bool>("Farts", "Only Players Fart (unrealistic)", false, (ConfigDescription)null); _Harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null); } private void OnDestroy() { if (_Harmony != null) { _Harmony.UnpatchSelf(); } } }