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 Fertilizer v1.2.0
Fertilizer.dll
Decompiled a day agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("Fertilizer")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.2.0.0")] [assembly: AssemblyInformationalVersion("1.2.0+7d1b52e75c7e338fb536dd62114732132e31b572")] [assembly: AssemblyProduct("Fertilizer")] [assembly: AssemblyTitle("Fertilizer")] [assembly: AssemblyVersion("1.2.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Fertilizer { internal class FertilizedScale : MonoBehaviour { } internal static class Fertilization { internal static void Apply(Plant plant) { if ((Object)(object)plant == (Object)null || !ModConfig.EnableMod.Value || (Object)(object)((Component)plant).GetComponent<FertilizedScale>() != (Object)null) { return; } ZNetView component = ((Component)plant).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } ZDO zDO = component.GetZDO(); if (zDO == null) { return; } int num = zDO.GetInt(FertilizerPiece.FertilizedHash, 0); if (num > 0) { Tier tier = Tier.ByLevel(num); if (tier?.Reduction != null) { float num2 = 1f - Mathf.Clamp(tier.Reduction.Value, 0f, 99f) / 100f; plant.m_growTime *= num2; plant.m_growTimeMax *= num2; ((Component)plant).gameObject.AddComponent<FertilizedScale>(); } } } } [HarmonyPatch(typeof(Plant), "GetHoverText")] internal static class PlantHoverTextPatch { private static void Postfix(Plant __instance, ref string __result) { if (!ModConfig.EnableMod.Value || string.IsNullOrEmpty(__result)) { return; } ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return; } int num = component.GetZDO().GetInt(FertilizerPiece.FertilizedHash, 0); if (num > 0) { Tier tier = Tier.ByLevel(num); if (tier != null) { __result = __result + "\n" + tier.DisplayName; } } } } [HarmonyPatch(typeof(Plant), "Awake")] internal static class PlantAwakePatch { private static void Postfix(Plant __instance) { Fertilization.Apply(__instance); } } [HarmonyPatch(typeof(Plant), "SUpdate")] internal static class PlantSUpdatePatch { private static void Prefix(Plant __instance) { Fertilization.Apply(__instance); } } internal class FertilizerPiece : MonoBehaviour, IPlaced { internal static readonly int FertilizedHash = StringExtensionMethods.GetStableHashCode("jelaw_fert_tier"); internal static readonly Func<Plant, float> GetGrowTime = AccessTools.MethodDelegate<Func<Plant, float>>(AccessTools.Method(typeof(Plant), "GetGrowTime", (Type[])null, (Type[])null), (object)null, true); private static int _mask; private static int Mask { get { if (_mask == 0) { return _mask = LayerMask.GetMask(new string[3] { "piece", "piece_nonsolid", "item" }); } return _mask; } } internal static float Radius() { Player localPlayer = Player.m_localPlayer; float num = (((Object)(object)localPlayer != (Object)null) ? ((Character)localPlayer).GetSkillFactor((SkillType)106) : 0f); return Mathf.Lerp(ModConfig.RadiusAtSkill0.Value, ModConfig.RadiusAtSkill100.Value, num); } private void Awake() { } public void OnPlaced() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (!ModConfig.EnableMod.Value) { ZNetScene.instance.Destroy(((Component)this).gameObject); return; } int currentTier = Plugin.CurrentTier; float num = Radius(); int num2 = 0; int num3 = 0; int num4 = 0; int num5 = 0; int num6 = 0; Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, num, Mask); for (int i = 0; i < array.Length; i++) { Plant componentInParent = ((Component)array[i]).GetComponentInParent<Plant>(); if ((Object)(object)componentInParent == (Object)null) { continue; } if ((int)componentInParent.GetStatus() != 0) { num3++; continue; } ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { continue; } if (!component.IsOwner()) { component.ClaimOwnership(); } if (!component.IsOwner()) { num6++; continue; } ZDO zDO = component.GetZDO(); if (zDO.GetInt(FertilizedHash, 0) != 0) { num4++; Float(componentInParent, (TextType)0, "$jelaw_already_fertilized"); continue; } long ticks = zDO.GetLong(ZDOVars.s_plantTime, ZNet.instance.GetTime().Ticks); if ((ZNet.instance.GetTime() - new DateTime(ticks)).TotalSeconds >= (double)GetGrowTime(componentInParent)) { num5++; continue; } zDO.Set(FertilizedHash, currentTier, false); Fertilization.Apply(componentInParent); Float(componentInParent, (TextType)7, $"+{PercentFor(currentTier):0}%"); num2++; } if (num2 > 0) { PlayEffect(); } else { Refund(currentTier); } if (ModConfig.DebugLogging.Value) { float num7 = PercentFor(currentTier); Logger.LogInfo((object)($"Tier {currentTier} ({num7:0}%) fertilized {num2} plant(s) within {num:0.0}m " + $"(skipped: {num4} already fertilized, {num3} unhealthy, " + $"{num5} fully grown, {num6} not owned)")); } ZNetScene.instance.Destroy(((Component)this).gameObject); } private static void Refund(int tierLevel) { Player localPlayer = Player.m_localPlayer; ItemDrop val = Tier.ByLevel(tierLevel)?.Drop; if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)val == (Object)null)) { if (!((Humanoid)localPlayer).GetInventory().AddItem(((Component)val).gameObject, 1)) { Logger.LogWarning((object)"Nothing was fertilized and the bone meal could not be returned - inventory full."); } else if (ModConfig.DebugLogging.Value) { Logger.LogInfo((object)"Nothing fertilized; bone meal returned."); } } } private static float PercentFor(int tierLevel) { return (Tier.ByLevel(tierLevel)?.Reduction?.Value).GetValueOrDefault(); } private static void Float(Plant plant, TextType type, string text) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) if (ModConfig.ShowFloatingText.Value && !((Object)(object)DamageText.instance == (Object)null)) { DamageText.instance.ShowText(type, ((Component)plant).transform.position + Vector3.up * 0.4f, Localization.instance.Localize(text), true); } } private void PlayEffect() { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) string value = ModConfig.PlaceEffect.Value; if (string.IsNullOrEmpty(value)) { return; } GameObject prefab = PrefabManager.Instance.GetPrefab(value); if ((Object)(object)prefab == (Object)null) { if (ModConfig.DebugLogging.Value) { Logger.LogWarning((object)("Effect prefab '" + value + "' not found.")); } } else { Object.Instantiate<GameObject>(prefab, ((Component)this).transform.position, Quaternion.identity); } } } internal static class Icons { internal static Sprite Recolour(Sprite source, Color tint) { //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_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: 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_012f: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } Texture2D texture = source.texture; Rect textureRect = source.textureRect; int num = Mathf.Max(1, (int)((Rect)(ref textureRect)).width); int num2 = Mathf.Max(1, (int)((Rect)(ref textureRect)).height); RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0); RenderTexture active = RenderTexture.active; try { Graphics.Blit((Texture)(object)texture, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(num, num2, (TextureFormat)5, false); val.ReadPixels(new Rect(((Rect)(ref textureRect)).x, ((Rect)(ref textureRect)).y, (float)num, (float)num2), 0, 0); Color[] pixels = val.GetPixels(); for (int i = 0; i < pixels.Length; i++) { Color val2 = pixels[i]; float num3 = val2.r * 0.299f + val2.g * 0.587f + val2.b * 0.114f; pixels[i] = new Color(num3 * tint.r, num3 * tint.g, num3 * tint.b, val2.a); } val.SetPixels(pixels); val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, (float)num, (float)num2), new Vector2(0.5f, 0.5f), source.pixelsPerUnit); } catch (Exception ex) { Logger.LogWarning((object)("Could not tint icon, keeping the original: " + ex.Message)); return null; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } } internal static class ModConfig { internal static ConfigEntry<bool> EnableMod; internal static ConfigEntry<float> RadiusAtSkill0; internal static ConfigEntry<float> RadiusAtSkill100; internal static ConfigEntry<bool> ShowFloatingText; internal static ConfigEntry<string> PlaceEffect; internal static ConfigEntry<string> BasePrefab; internal static ConfigEntry<bool> DebugLogging; private static ConfigurationManagerAttributes Synced => new ConfigurationManagerAttributes { IsAdminOnly = true }; internal static void Bind(ConfigFile cfg) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Expected O, but got Unknown EnableMod = cfg.Bind<bool>("General", "EnableMod", true, new ConfigDescription("Master switch.", (AcceptableValueBase)null, new object[1] { Synced })); RadiusAtSkill0 = cfg.Bind<float>("Area", "RadiusAtSkill0", 1.5f, new ConfigDescription("Radius in metres covered at Farming skill 0.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), new object[1] { Synced })); RadiusAtSkill100 = cfg.Bind<float>("Area", "RadiusAtSkill100", 4f, new ConfigDescription("Radius in metres covered at Farming skill 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), new object[1] { Synced })); float[] array = new float[3] { 25f, 50f, 75f }; Tier[] all = Tier.All; foreach (Tier tier in all) { tier.Reduction = cfg.Bind<float>("Fertilizer", $"Reduction{tier.Level} - {tier.DisplayName}", array[tier.Level - 1], new ConfigDescription("Percent of remaining grow time removed by " + tier.DisplayName + ".", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 100f), new object[1] { Synced })); } ShowFloatingText = cfg.Bind<bool>("Feedback", "ShowFloatingText", true, "Shows a floating figure over each plant as it is fertilized, and over any that were already done."); PlaceEffect = cfg.Bind<string>("Feedback", "PlaceEffect", "vfx_Place_replant", "Vanilla effect prefab played where the fertilizer is spread. Blank for none."); BasePrefab = cfg.Bind<string>("Appearance", "BasePrefab", "cultivate_v2,cultivate,wood_pole", "Which in-game object the placeable borrows its look and ground indicator from, as a comma-separated list - the first one that exists is used. There is rarely any reason to change this."); DebugLogging = cfg.Bind<bool>("Debug", "DebugLogging", false, "Logs how many plants each placement affected, and why any were skipped."); } } [BepInPlugin("elric.Fertilizer", "Fertilizer", "1.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class Plugin : BaseUnityPlugin { public const string PluginGUID = "elric.Fertilizer"; public const string PluginName = "Fertilizer"; public const string PluginVersion = "1.2.0"; private const string ItemBasePrefab = "PowderedDragonEgg"; private const string PiecePrefabName = "jelaw_fertilizer_piece"; internal static int CurrentTier = 1; private static int _lastLoggedTier = -1; private static float _nativeRadius = 2f; private static Vector3 _nativeGhostScale = Vector3.one; private static readonly FieldRef<Player, GameObject> GhostOf = AccessTools.FieldRefAccess<Player, GameObject>("m_placementGhost"); private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) ModConfig.Bind(((BaseUnityPlugin)this).Config); new Harmony("elric.Fertilizer").PatchAll(); PrefabManager.OnVanillaPrefabsAvailable += AddContent; } private void Update() { //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } Tier tier = Selected(localPlayer) ?? Tier.All[0]; CurrentTier = tier.Level; if ((Object)(object)tier.Drop == (Object)null) { return; } Piece selectedPiece = localPlayer.GetSelectedPiece(); if ((Object)(object)selectedPiece == (Object)null || Utils.GetPrefabName(((Component)selectedPiece).gameObject) != "jelaw_fertilizer_piece") { return; } if (selectedPiece.m_resources == null || selectedPiece.m_resources.Length == 0) { selectedPiece.m_resources = (Requirement[])(object)new Requirement[1] { new Requirement() }; if (ModConfig.DebugLogging.Value) { Logger.LogInfo((object)"Fertilizer piece had no requirements; created one."); } } Requirement val = selectedPiece.m_resources[0]; if (val == null) { val = new Requirement(); selectedPiece.m_resources[0] = val; } val.m_resItem = tier.Drop; val.m_amount = 1; val.m_amountPerLevel = 0; val.m_recover = false; if (ModConfig.DebugLogging.Value && _lastLoggedTier != tier.Level) { _lastLoggedTier = tier.Level; Logger.LogInfo((object)("Held piece '" + Utils.GetPrefabName(((Component)selectedPiece).gameObject) + "' cost set to " + $"'{((Object)tier.Drop).name}' (tier {tier.Level})")); } ScaleGhost(localPlayer); } private static Tier Selected(Player player) { Inventory inventory = ((Humanoid)player).GetInventory(); if (inventory == null) { return null; } ItemData val = ((Humanoid)player).GetAmmoItem(); if (val != null && (!inventory.ContainsItem(val) || val.m_shared.m_ammoType != "$ammo_fertilizer")) { val = null; } val = val ?? inventory.GetAmmoItem("$ammo_fertilizer", (string)null); if (val == null || (Object)(object)val.m_dropPrefab == (Object)null) { return null; } return Tier.ByItemName(((Object)val.m_dropPrefab).name); } private static string FirstExisting(string names) { if (string.IsNullOrEmpty(names)) { return null; } string[] array = names.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0 && (Object)(object)Resolve(text) != (Object)null) { return text; } } return null; } private static void CaptureIndicatorScale(GameObject prefab) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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) TerrainOp componentInChildren = prefab.GetComponentInChildren<TerrainOp>(true); if ((Object)(object)componentInChildren != (Object)null && componentInChildren.GetRadius() > 0f) { _nativeRadius = componentInChildren.GetRadius(); } else { TerrainModifier componentInChildren2 = prefab.GetComponentInChildren<TerrainModifier>(true); if ((Object)(object)componentInChildren2 != (Object)null && componentInChildren2.GetRadius() > 0f) { _nativeRadius = componentInChildren2.GetRadius(); } } Transform val = prefab.transform.Find("_GhostOnly"); if ((Object)(object)val != (Object)null) { _nativeGhostScale = val.localScale; } if (ModConfig.DebugLogging.Value) { Logger.LogInfo((object)($"Indicator native radius {_nativeRadius:0.##}m at scale {_nativeGhostScale}" + (((Object)(object)val == (Object)null) ? " (no _GhostOnly child found)" : ""))); } } internal static GameObject Resolve(string name) { GameObject prefab = PrefabManager.Instance.GetPrefab(name); if ((Object)(object)prefab != (Object)null) { return prefab; } if (ZNetScene.instance?.m_prefabs == null) { return null; } foreach (GameObject prefab2 in ZNetScene.instance.m_prefabs) { if ((Object)(object)prefab2 != (Object)null && ((Object)prefab2).name == name) { return prefab2; } } return null; } private static void ScaleGhost(Player player) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) GameObject val = GhostOf.Invoke(player); if (!((Object)(object)val == (Object)null)) { Transform val2 = val.transform.Find("_GhostOnly"); if (!((Object)(object)val2 == (Object)null)) { float num = FertilizerPiece.Radius() / Mathf.Max(_nativeRadius, 0.01f); val2.localScale = _nativeGhostScale * num; } } } private void AddContent() { AddLocalization(); Tier[] all = Tier.All; for (int i = 0; i < all.Length; i++) { AddMeal(all[i]); } AddPlaceable(); PrefabManager.OnVanillaPrefabsAvailable -= AddContent; } private static void AddMeal(Tier tier) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: 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_0159: Expected O, but got Unknown //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Expected O, but got Unknown //IL_00db: Unknown result type (might be due to invalid IL or missing references) GameObject val = PrefabManager.Instance.CreateClonedPrefab(tier.ItemName, "PowderedDragonEgg"); if ((Object)(object)val == (Object)null) { Logger.LogError((object)("Could not clone 'PowderedDragonEgg' for " + tier.DisplayName + ".")); return; } ItemDrop component = val.GetComponent<ItemDrop>(); component.m_itemData.m_shared.m_name = "$" + tier.ItemName; component.m_itemData.m_shared.m_description = "$" + tier.ItemName + "_desc"; component.m_itemData.m_shared.m_itemType = (ItemType)9; component.m_itemData.m_shared.m_ammoType = "$ammo_fertilizer"; component.m_itemData.m_shared.m_maxStackSize = 50; Sprite[] icons = component.m_itemData.m_shared.m_icons; if (icons != null && icons.Length != 0) { Sprite val2 = Icons.Recolour(icons[0], tier.Tint); if ((Object)(object)val2 != (Object)null) { component.m_itemData.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { val2 }; } } ItemConfig val3 = new ItemConfig { Amount = 2, CraftingStation = CraftingStations.Workbench, Requirements = ((IEnumerable<(string, int)>)tier.Ingredients).Select((Func<(string, int), RequirementConfig>)(((string Item, int Amount) i) => new RequirementConfig(i.Item, i.Amount, 0, true))).ToArray() }; ItemManager.Instance.AddItem(new CustomItem(val, false, val3)); tier.Drop = component; } private static void AddPlaceable() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0140: 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) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown PieceConfig val = new PieceConfig(); val.Name = "$jelaw_fertilize"; val.Description = "$jelaw_fertilize_desc"; val.PieceTable = PieceTables.Cultivator; val.Requirements = (RequirementConfig[])(object)new RequirementConfig[1] { new RequirementConfig(Tier.All[0].ItemName, 1, 0, true) }; PieceConfig val2 = val; string text = FirstExisting(ModConfig.BasePrefab.Value); bool num = text != null; if (ModConfig.DebugLogging.Value) { Logger.LogInfo((object)("Fertilizer base prefab: " + (text ?? "none - using a cube"))); } CustomPiece val3; if (num) { val3 = new CustomPiece("jelaw_fertilizer_piece", text, val2); } else { Logger.LogWarning((object)("Base prefab '" + text + "' not found; falling back to a plain cube.")); val3 = new CustomPiece("jelaw_fertilizer_piece", true, val2); } if ((Object)(object)val3.PiecePrefab == (Object)null) { Logger.LogError((object)"Could not create the fertilizer placeable."); return; } CaptureIndicatorScale(val3.PiecePrefab); StripInheritedBehaviour(val3.PiecePrefab); val3.PiecePrefab.AddComponent<FertilizerPiece>(); PieceManager.Instance.AddPiece(val3); Piece component = val3.PiecePrefab.GetComponent<Piece>(); if ((Object)(object)component != (Object)null) { ItemDrop drop = Tier.All[0].Drop; if ((Object)(object)drop != (Object)null) { component.m_resources = (Requirement[])(object)new Requirement[1] { new Requirement { m_resItem = drop, m_amount = 1, m_amountPerLevel = 0, m_recover = false } }; } } if (ModConfig.DebugLogging.Value && (Object)(object)component != (Object)null) { Requirement[] resources = component.m_resources; int num2 = ((resources != null) ? resources.Length : 0); string arg = ((num2 > 0 && (Object)(object)component.m_resources[0]?.m_resItem != (Object)null) ? ((Object)component.m_resources[0].m_resItem).name : "none"); Logger.LogInfo((object)$"Fertilizer piece registered with {num2} requirement(s), first = {arg}"); } if ((Object)(object)component != (Object)null) { component.m_craftingStation = null; component.m_groundOnly = false; component.m_notOnFloor = false; component.m_noInWater = false; component.m_onlyInTeleportArea = false; component.m_allowedInDungeons = true; } } private static void StripInheritedBehaviour(GameObject prefab) { PrivateArea[] componentsInChildren = prefab.GetComponentsInChildren<PrivateArea>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } Container[] componentsInChildren2 = prefab.GetComponentsInChildren<Container>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { Object.Destroy((Object)(object)componentsInChildren2[i]); } CraftingStation[] componentsInChildren3 = prefab.GetComponentsInChildren<CraftingStation>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { Object.Destroy((Object)(object)componentsInChildren3[i]); } TerrainOp[] componentsInChildren4 = prefab.GetComponentsInChildren<TerrainOp>(true); for (int i = 0; i < componentsInChildren4.Length; i++) { Object.Destroy((Object)(object)componentsInChildren4[i]); } TerrainModifier[] componentsInChildren5 = prefab.GetComponentsInChildren<TerrainModifier>(true); for (int i = 0; i < componentsInChildren5.Length; i++) { Object.Destroy((Object)(object)componentsInChildren5[i]); } } private static void AddLocalization() { CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); Dictionary<string, string> dictionary = new Dictionary<string, string> { { "ammo_fertilizer", "Fertilizer" }, { "jelaw_fertilize", "Fertilize" }, { "jelaw_already_fertilized", "Already Fertilized" }, { "jelaw_fertilize_desc", "Spreads the selected bone meal. Covers a wider area as Farming rises." } }; Tier[] all = Tier.All; foreach (Tier tier in all) { dictionary[tier.ItemName] = tier.DisplayName; dictionary[tier.ItemName + "_desc"] = tier.Description; } string text = "English"; localization.AddTranslation(ref text, dictionary); } } internal class Tier { internal const string AmmoType = "$ammo_fertilizer"; internal int Level; internal string ItemName; internal string DisplayName; internal string Description; internal ConfigEntry<float> Reduction; internal Color Tint; internal (string Item, int Amount)[] Ingredients; internal ItemDrop Drop; internal static readonly Tier[] All = new Tier[3] { new Tier { Level = 1, ItemName = "jelaw_bonemeal", DisplayName = "Bone Meal", Description = "Ground bone. Hastens a crop a little.", Tint = new Color(1f, 0.97f, 0.9f), Ingredients = new(string, int)[1] { ("BoneFragments", 5) } }, new Tier { Level = 2, ItemName = "jelaw_bonemeal_enriched", DisplayName = "Enriched Bone Meal", Description = "Bone meal ground with fang and charcoal.", Tint = new Color(0.62f, 0.6f, 0.58f), Ingredients = new(string, int)[3] { ("jelaw_bonemeal", 1), ("WolfFang", 1), ("Coal", 1) } }, new Tier { Level = 3, ItemName = "jelaw_bonemeal_enhanced", DisplayName = "Enhanced Bone Meal", Description = "Bone meal ground with charred bone and sap.", Tint = new Color(0.22f, 0.31f, 0.2f), Ingredients = new(string, int)[3] { ("jelaw_bonemeal", 1), ("CharredBone", 1), ("Sap", 1) } } }; internal static Tier ByItemName(string prefabName) { Tier[] all = All; foreach (Tier tier in all) { if (tier.ItemName == prefabName) { return tier; } } return null; } internal static Tier ByLevel(int level) { Tier[] all = All; foreach (Tier tier in all) { if (tier.Level == level) { return tier; } } return All[0]; } } }