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 WoodenCrossbow v1.0.2
plugins/WoodenCrossbow.dll
Decompiled a week agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; using WoodenCrossbow.Configurations; using WoodenCrossbow.Items; using WoodenCrossbow.Localizations; using WoodenCrossbow.Utilities; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("WoodenCrossbow")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("WoodenCrossbow")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("1.0.2")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.2.0")] namespace WoodenCrossbow { [BepInPlugin("com.naexn.WoodenCrossbow", "WoodenCrossbow", "1.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class WoodenCrossbow : BaseUnityPlugin { public const string PluginGUID = "com.naexn.WoodenCrossbow"; public const string PluginName = "WoodenCrossbow"; public const string PluginVersion = "1.0.2"; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); private void Awake() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) Logger.LogInfo((object)"WoodenCrossbow v1.0.2 has landed!"); CrossbowConfig.CreateConfigValues(((BaseUnityPlugin)this).Config); CrossbowConfig.RegisterChangeCallbacks(); ModLocalizationManager.Init(); PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; new Harmony("com.naexn.WoodenCrossbow").PatchAll(); } private void OnVanillaPrefabsAvailable() { PrefabManager.OnVanillaPrefabsAvailable -= OnVanillaPrefabsAvailable; WoodenCrossbowItem.Register(); } } } namespace WoodenCrossbow.Utilities { public static class AssetHelper { public static Sprite LoadSpriteFromFile(string relativePath) { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (directoryName == null) { return null; } string text = Path.Combine(directoryName, relativePath); if (!File.Exists(text)) { Logger.LogWarning((object)("[AssetHelper] File not found at path: " + text)); return null; } return AssetUtils.LoadSpriteFromFile(text); } } public static class AudioHelper { public static void ConfigureWeaponAudio(ItemDrop targetItemDrop, string bowPrefabName, float originalVolume = 0.2f, float bowVolume = 0.8f) { //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Expected O, but got Unknown //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Expected O, but got Unknown if (targetItemDrop?.m_itemData?.m_shared == null) { return; } SharedData shared = targetItemDrop.m_itemData.m_shared; GameObject prefab = PrefabManager.Instance.GetPrefab(bowPrefabName); SharedData val = ((prefab == null) ? null : prefab.GetComponent<ItemDrop>()?.m_itemData?.m_shared); if (val == null) { Logger.LogWarning((object)("[AudioHelper] Could not resolve SharedData for '" + bowPrefabName + "'.")); return; } GameObject val2 = shared.m_triggerEffect?.m_effectPrefabs?.FirstOrDefault((Func<EffectData, bool>)((EffectData e) => (Object)(object)e.m_prefab != (Object)null && IsAudioPrefab(e.m_prefab)))?.m_prefab; GameObject val3 = val.m_triggerEffect?.m_effectPrefabs?.FirstOrDefault((Func<EffectData, bool>)((EffectData e) => (Object)(object)e.m_prefab != (Object)null && IsAudioPrefab(e.m_prefab)))?.m_prefab; if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null)) { string arg = shared.m_name?.Replace("$", "").Replace(" ", "") ?? "CustomWeapon"; GameObject val4 = PrefabManager.Instance.CreateClonedPrefab($"SFX_{arg}_Original_{Mathf.RoundToInt(originalVolume * 100f)}", val2); GameObject val5 = PrefabManager.Instance.CreateClonedPrefab($"SFX_{arg}_Bow_{Mathf.RoundToInt(bowVolume * 100f)}", val3); AdjustVolume(val4, originalVolume); AdjustVolume(val5, bowVolume); PrefabManager.Instance.AddPrefab(val4); PrefabManager.Instance.AddPrefab(val5); List<EffectData> list = shared.m_triggerEffect?.m_effectPrefabs?.Where((EffectData e) => (Object)(object)e.m_prefab != (Object)null && !IsAudioPrefab(e.m_prefab))?.ToList() ?? new List<EffectData>(); list.Add(new EffectData { m_prefab = val4, m_enabled = true, m_attach = true }); list.Add(new EffectData { m_prefab = val5, m_enabled = true, m_attach = true }); shared.m_triggerEffect = new EffectList { m_effectPrefabs = list.ToArray() }; } } private static bool IsAudioPrefab(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return false; } if (((Object)prefab).name.StartsWith("sfx_", StringComparison.OrdinalIgnoreCase)) { return true; } if (!((Object)(object)prefab.GetComponentInChildren<AudioSource>(true) != (Object)null)) { return (Object)(object)prefab.GetComponentInChildren<ZSFX>(true) != (Object)null; } return true; } private static void AdjustVolume(GameObject sfxPrefab, float multiplier) { if (!((Object)(object)sfxPrefab == (Object)null)) { AudioSource[] componentsInChildren = sfxPrefab.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource obj in componentsInChildren) { obj.volume *= multiplier; } ZSFX[] componentsInChildren2 = sfxPrefab.GetComponentsInChildren<ZSFX>(true); foreach (ZSFX obj2 in componentsInChildren2) { obj2.m_minVol *= multiplier; obj2.m_maxVol *= multiplier; } } } } public static class MaterialHelper { public static void ApplyWoodenWeaponsMaterial(GameObject targetPrefab) { if ((Object)(object)targetPrefab == (Object)null) { return; } GameObject prefab = PrefabManager.Instance.GetPrefab("SwordWood"); if ((Object)(object)prefab == (Object)null) { return; } Renderer val = ((IEnumerable<Renderer>)prefab.GetComponentsInChildren<Renderer>(true)).FirstOrDefault((Func<Renderer, bool>)((Renderer r) => r is MeshRenderer || r is SkinnedMeshRenderer)); if ((Object)(object)((val != null) ? val.sharedMaterial : null) == (Object)null) { return; } Material sharedMaterial = val.sharedMaterial; Renderer[] componentsInChildren = targetPrefab.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if (!(val2 is ParticleSystemRenderer)) { val2.sharedMaterial = sharedMaterial; } } } } } namespace WoodenCrossbow.Patches { [HarmonyPatch(typeof(Player))] public static class RecipePatches { [HarmonyPatch("AddKnownItem")] [HarmonyPostfix] private static void Postfix_AddKnownItem(Player __instance, ItemData item) { if (!((Object)(object)__instance == (Object)null) && item != null && WoodenCrossbowItem.UnlockTriggerTokens.Contains(item.m_shared.m_name)) { WoodenCrossbowItem.UnlockRecipeForPlayer(__instance); } } [HarmonyPatch("OnSpawned")] [HarmonyPostfix] private static void Postfix_OnSpawned(Player __instance) { if ((Object)(object)__instance == (Object)null || !((Character)__instance).IsOwner()) { return; } foreach (string unlockTriggerToken in WoodenCrossbowItem.UnlockTriggerTokens) { if (__instance.IsKnownMaterial(unlockTriggerToken)) { WoodenCrossbowItem.UnlockRecipeForPlayer(__instance); break; } } } } } namespace WoodenCrossbow.Localizations { public static class ModLocalizationManager { public static void Init() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); string text = "English"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "item_woodencrossbow", "Wooden Crossbow" } }); text = "Czech"; localization.AddTranslation(ref text, new Dictionary<string, string> { { "item_woodencrossbow", "Dřevěná kuše" } }); } } } namespace WoodenCrossbow.Items { internal class WoodenCrossbowItem { public const string ItemName = "WoodenCrossbow"; private const string BaseBowAudioPrefab = "BowFineWood"; private const float CrossbowSnapVolume = 0.4f; private const float BowReleaseVolume = 0.6f; public static readonly HashSet<string> UnlockTriggerTokens = new HashSet<string> { "$item_crossbow_arbalest", "$item_crossbow_ripper", "$item_crossbow_gold", "$item_crossbow_bloodlightning_gold", "$item_crossbow_frostfire_gold" }; public static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown ItemConfig val = CreateItemConfig(); CustomItem val2 = new CustomItem("WoodenCrossbow", "CrossbowArbalest", val); if (val2.Recipe != null) { val2.Recipe.Recipe.m_enabled = false; } ConfigureItemStats(val2.ItemDrop); Sprite val3 = AssetHelper.LoadSpriteFromFile("Assets/WoodenCrossbow_icon.png"); if ((Object)(object)val3 != (Object)null) { val2.ItemDrop.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val3 }; } MaterialHelper.ApplyWoodenWeaponsMaterial(val2.ItemPrefab); ItemManager.Instance.AddItem(val2); GameObject prefab = PrefabManager.Instance.GetPrefab("WoodenCrossbow"); ItemDrop targetItemDrop = default(ItemDrop); if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref targetItemDrop)) { AudioHelper.ConfigureWeaponAudio(targetItemDrop, "BowFineWood", 0.4f, 0.6f); } } private static ItemConfig CreateItemConfig() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003b: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown ItemConfig val = new ItemConfig { Name = "$item_woodencrossbow", Description = "$item_atgeir_wood_description", CraftingStation = CraftingStations.Workbench, MinStationLevel = 1 }; val.AddRequirement("Wood", 10, 1); val.AddRequirement("FineWood", 5, 1); val.AddRequirement("YggdrasilWood", 2, 1); val.AddRequirement("Root", 2, 1); return val; } private static void ConfigureItemStats(ItemDrop itemDrop) { if (itemDrop?.m_itemData?.m_shared != null) { SharedData shared = itemDrop.m_itemData.m_shared; shared.m_damages.m_pierce = CrossbowConfig.PierceDamage.Value; shared.m_damages.m_chop = 0f; shared.m_attackForce = CrossbowConfig.KnockbackForce.Value; if (shared.m_attack != null) { shared.m_attack.m_recoilPushback = CrossbowConfig.RecoilPushbackForce.Value; Attack attack = shared.m_attack; attack.m_reloadTime *= CrossbowConfig.ReloadTimeMultiplier.Value; Attack attack2 = shared.m_attack; attack2.m_projectileVel *= CrossbowConfig.ProjectileVelocityMultiplier.Value; Attack attack3 = shared.m_attack; attack3.m_projectileVelMin *= CrossbowConfig.ProjectileVelocityMultiplier.Value; } shared.m_maxQuality = 1; shared.m_scaleByQuality = 0f; } } public static void ApplyConfigStats() { GameObject prefab = PrefabManager.Instance.GetPrefab("WoodenCrossbow"); ItemDrop itemDrop = default(ItemDrop); if ((Object)(object)prefab != (Object)null && prefab.TryGetComponent<ItemDrop>(ref itemDrop)) { ConfigureItemStats(itemDrop); } } public static void UnlockRecipeForPlayer(Player player) { CustomItem item = ItemManager.Instance.GetItem("WoodenCrossbow"); if (!((Object)(object)((item != null) ? item.ItemDrop : null) == (Object)null) && !((Object)(object)player == (Object)null)) { ObjectDB instance = ObjectDB.instance; Recipe val = ((instance != null) ? instance.GetRecipe(item.ItemDrop.m_itemData) : null); if ((Object)(object)val != (Object)null) { val.m_enabled = true; player.UpdateKnownRecipesList(); } } } } } namespace WoodenCrossbow.Configurations { public class ConfigurationManagerAttributes { public int? Order; public bool? HideSettingName; public bool? ReadOnly; public bool? IsAdminOnly; } internal static class CrossbowConfig { internal static ConfigEntry<float> PierceDamage; internal static ConfigEntry<float> KnockbackForce; internal static ConfigEntry<float> RecoilPushbackForce; internal static ConfigEntry<float> ReloadTimeMultiplier; internal static ConfigEntry<float> ProjectileVelocityMultiplier; internal static void CreateConfigValues(ConfigFile config) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Expected O, but got Unknown //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Expected O, but got Unknown //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Expected O, but got Unknown ConfigurationManagerAttributes configurationManagerAttributes = new ConfigurationManagerAttributes { IsAdminOnly = true }; config.Bind<string>("Important Notice", "RestartWarning", "Changes require a game restart to take effect.", new ConfigDescription("General mod notice.", (AcceptableValueBase)null, new object[1] { new ConfigurationManagerAttributes { Order = 1000, HideSettingName = true, ReadOnly = true } })); PierceDamage = config.Bind<float>("Stats", "Pierce Damage", 1f, new ConfigDescription("Base pierce damage for the Wooden Crossbow.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 200f), new object[2] { new ConfigurationManagerAttributes { Order = 100 }, configurationManagerAttributes })); KnockbackForce = config.Bind<float>("Stats", "Knockback Force", 5f, new ConfigDescription("Force applied to targets when hit.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), new object[2] { new ConfigurationManagerAttributes { Order = 90 }, configurationManagerAttributes })); RecoilPushbackForce = config.Bind<float>("Stats", "Recoil Pushback Force", 0f, new ConfigDescription("Pushback force applied to the player when firing the crossbow.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), new object[2] { new ConfigurationManagerAttributes { Order = 80 }, configurationManagerAttributes })); ReloadTimeMultiplier = config.Bind<float>("Combat", "Reload Time Multiplier", 0.7f, new ConfigDescription("Multiplier applied to reload duration (0.7 = 30% faster reload).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 2f), new object[2] { new ConfigurationManagerAttributes { Order = 70 }, configurationManagerAttributes })); ProjectileVelocityMultiplier = config.Bind<float>("Combat", "Projectile Velocity Multiplier", 0.4f, new ConfigDescription("Multiplier for bolt velocity relative to base Arbalest. Visual only.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 1f), new object[2] { new ConfigurationManagerAttributes { Order = 60 }, configurationManagerAttributes })); } internal static void RegisterChangeCallbacks() { PierceDamage.SettingChanged += delegate { UpdateLiveWeaponStats(); }; KnockbackForce.SettingChanged += delegate { UpdateLiveWeaponStats(); }; RecoilPushbackForce.SettingChanged += delegate { UpdateLiveWeaponStats(); }; ReloadTimeMultiplier.SettingChanged += delegate { UpdateLiveWeaponStats(); }; ProjectileVelocityMultiplier.SettingChanged += delegate { UpdateLiveWeaponStats(); }; } private static void UpdateLiveWeaponStats() { WoodenCrossbowItem.ApplyConfigStats(); } } }