using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using DG.Tweening; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using UnityEngine.Localization; using UnityEngine.Localization.Settings; using UnityEngine.Localization.Tables; using UnityEngine.ResourceManagement.AsyncOperations; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("KinkoCraft.FarmerOwl")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Farmer Owl")] [assembly: AssemblyTitle("KinkoCraft.FarmerOwl")] [assembly: AssemblyVersion("1.0.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 KinkoCraft.FarmerOwl { public abstract class FarmerStateBase : StateBase { protected HelperCleaner Owner => base.stateMachine.Owner; protected HelperBase Helper => (HelperBase)(object)base.stateMachine.Owner; protected ContainerNet Container => ((HelperBase)base.stateMachine.Owner).containerRef.containerNet; protected FarmerStateBase(HelperCleanerStateMachine sm) : base(sm) { } protected void GoTo(StateBase next) { base.stateMachine.ChangeState(next); } public override void ExecutePerFrame() { Owner.SetAnimatorMoveSpeed(); } public override void OnExit() { } public override void ExecutePerSecond() { } } public class FarmerIdleState : FarmerStateBase { private readonly FarmTask presetTask; public FarmerIdleState(HelperCleanerStateMachine sm, FarmTask presetTask = null) : base(sm) { this.presetTask = presetTask; } public override void OnEnter() { FarmTask farmTask = presetTask ?? FarmScheduler.GetNextTask(base.Owner); if (farmTask != null) { GoTo(new FarmerMoveToBedState(((StateBase)this).stateMachine, farmTask)); } else { GoTo(new FarmerReturnHomeState(((StateBase)this).stateMachine)); } } } public class FarmerMoveToBedState : FarmerStateBase { private readonly FarmTask task; private Vector3 movePos; public FarmerMoveToBedState(HelperCleanerStateMachine sm, FarmTask task) : base(sm) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) this.task = task; movePos = task.movePos; } public override void OnEnter() { HelperCleaner owner = base.Owner; owner.OnDespawn = (Action)Delegate.Combine(owner.OnDespawn, new Action(Unsubscribe)); FurnitureManager instance = FurnitureManager.Instance; instance.OnFurniturePlaced = (Action)Delegate.Combine(instance.OnFurniturePlaced, new Action(OnFurniturePlaced)); } public override void OnExit() { Unsubscribe(); } private void Unsubscribe() { FurnitureManager instance = FurnitureManager.Instance; instance.OnFurniturePlaced = (Action)Delegate.Remove(instance.OnFurniturePlaced, new Action(OnFurniturePlaced)); HelperCleaner owner = base.Owner; owner.OnDespawn = (Action)Delegate.Remove(owner.OnDespawn, new Action(Unsubscribe)); } private void OnFurniturePlaced() { ((MonoBehaviour)base.Owner).StartCoroutine(Recalculate()); } private IEnumerator Recalculate() { yield return (object)new WaitForSeconds(1f); Vector3 val = default(Vector3); if (HelpersManager.Instance.GetReachablePointOnNavMesh(base.Helper, movePos, ref val, 20f)) { movePos = val; } } public override void ExecutePerFrame() { //IL_0016: 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_0021: 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) base.Owner.SetAnimatorMoveSpeed(); if (Vector2.Distance(FlatDistanceExtension.xz(((Component)base.Owner).transform.position), FlatDistanceExtension.xz(movePos)) <= ((HelperBase)base.Owner).targetDetectDistance) { GoTo(new FarmerWorkState(((StateBase)this).stateMachine, task)); } } public override void ExecutePerSecond() { //IL_0019: Unknown result type (might be due to invalid IL or missing references) if (base.Owner.CanMove()) { ((HelperBase)base.Owner).agent.SetDestination(movePos); } } } public class FarmerWorkState : FarmerStateBase { private static int _plowHits = -1; private readonly FarmTask task; public FarmerWorkState(HelperCleanerStateMachine sm, FarmTask task) : base(sm) { this.task = task; } public override void OnEnter() { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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) ((HelperBase)base.Owner).animator.SetBool("Cleanup", true); ((HelperBase)base.Owner).agent.isStopped = true; IEnumerator enumerator = task.kind switch { FarmTask.Kind.Plow => PlowRoutine(task.bed, task.item), FarmTask.Kind.Plant => PlantRoutine(task.bed, task.item), FarmTask.Kind.Fertilize => FertilizeRoutine(task.bed), FarmTask.Kind.Water => WaterRoutine(task.bed, task.item), FarmTask.Kind.Harvest => HarvestRoutine(task.bed), _ => throw new NotImplementedException("Unknown farm task kind"), }; ((MonoBehaviour)base.Owner).StartCoroutine(enumerator); ShortcutExtensions.DOLookAt(((Component)base.Owner).transform, ((Component)task.bed).transform.position, 0.5f, (AxisConstraint)4, (Vector3?)null); } public override void OnExit() { ((Behaviour)((HelperBase)base.Owner).agent).enabled = true; ((HelperBase)base.Owner).agent.isStopped = false; ((HelperBase)base.Owner).animator.SetBool("Cleanup", false); } private IEnumerator PlowRoutine(GardenBed bed, Item hoe) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((int)bed.state.Value == 0 && !bed.isInactive.Value) { bed.PlowBedServerRpc((byte)PlowHits()); ConsumeDurability(hoe.id); yield return (object)new WaitForSeconds(1f); } Done(); } private IEnumerator PlantRoutine(GardenBed bed, Item seed) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Item val = default(Item); if ((int)bed.state.Value == 1 && bed.currentSeedId.Value == 0 && !bed.isInactive.Value && base.Container.GetItemById(seed.id, ref val, false) && val.amount > 0 && GardenManager.Instance.IsSeed((uint)val.dataId)) { PlantData plantData = GardenManager.Instance.GetPlantData((uint)val.dataId); if ((Object)(object)plantData != (Object)null) { val.amount--; bed.rarity = val.rarity; if (val.amount == 0) { base.Container.RemoveItemById(val.id); } else { base.Container.SetItemById(val.id, val); } bed.currentSeedId.Value = val.dataId; bed.remainingGrowTime = (int)plantData.growTime; bed.state.Value = (State)2; Game instance = Game.Instance; if (instance != null) { instance.InvokeGameEvent((GameEvent)73, (uint)val.dataId, 1); } yield return (object)new WaitForSeconds(1f); } } Done(); } private IEnumerator FertilizeRoutine(GardenBed bed) { if (!bed.isFertilized.Value && IsGrowable(bed) && base.Container.GetItemAmount((ushort)280) != 0) { base.Container.RemoveAmount((ushort)280, (ushort)1); bed.isFertilized.Value = true; yield return (object)new WaitForSeconds(1f); } Done(); } private IEnumerator WaterRoutine(GardenBed bed, Item can) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Item val = default(Item); if (!bed.isWatered.Value && IsGrowable(bed) && base.Container.GetItemById(can.id, ref val, false) && val.charge > 0) { if (val.charge > 1) { val.charge--; base.Container.SetItemById(val.id, val); } else { base.Container.RemoveItemById(val.id); } bed.isWatered.Value = true; yield return (object)new WaitForSeconds(1f); } Done(); } private IEnumerator HarvestRoutine(GardenBed bed) { if ((int)bed.state.Value == 3 && bed.currentSeedId.Value != 0 && !bed.isInactive.Value) { PlantData plantData = GardenManager.Instance.GetPlantData((uint)bed.currentSeedId.Value); if ((Object)(object)plantData != (Object)null && (Object)(object)plantData.grownPlantItem != (Object)null) { ItemData grownPlantItem = plantData.grownPlantItem; Item val = default(Item); ((Item)(ref val))..ctor(grownPlantItem); val.amount = plantData.takeAmount; Item val2 = val; if (grownPlantItem.hasRarity && (int)bed.rarity != 255) { val2.rarity = bed.rarity; } if (!grownPlantItem.quest && bed.isFertilized.Value) { val2.amount = (ushort)Mathf.CeilToInt(1.5f * (float)(int)val2.amount); } base.Container.AddNewItem(val2, ((Component)bed).transform.position, false); bed.state.Value = (State)0; Game instance = Game.Instance; if (instance != null) { instance.InvokeGameEvent((GameEvent)74, (uint)grownPlantItem.id, 1); } yield return (object)new WaitForSeconds(1f); } } Done(); } private static bool IsGrowable(GardenBed bed) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 if (!bed.isInactive.Value) { if ((int)bed.state.Value != 1) { return (int)bed.state.Value == 2; } return true; } return false; } private void ConsumeDurability(uint toolId) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) Item val = default(Item); ItemData val2 = default(ItemData); if (base.Container.GetItemById(toolId, ref val, false) && ItemManager.Instance.GetItemData((uint)val.dataId, ref val2)) { if (val.durability > val2.durabilityPerHit) { val.durability -= val2.durabilityPerHit; base.Container.SetItemById(val.id, val); } else { base.Container.RemoveItemById(val.id); } } } private static int PlowHits() { if (_plowHits > 0) { return _plowHits; } _plowHits = 2; GardenBed[] array = GardenManager.Instance?.gardenBeds; if (array != null && array.Length != 0) { FieldInfo field = typeof(GardenBed).GetField("targetHoeHitCount", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { _plowHits = Mathf.Clamp((int)field.GetValue(array[0]), 1, 100); } } return _plowHits; } private void Done() { GoTo(new FarmerIdleState(((StateBase)this).stateMachine)); } } public class FarmerReturnHomeState : FarmerStateBase { public FarmerReturnHomeState(HelperCleanerStateMachine sm) : base(sm) { } public override void OnEnter() { ((StateBase)this).ExecutePerSecond(); } public override void ExecutePerSecond() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) if (base.Owner.CanMove() && ((Behaviour)((HelperBase)base.Owner).agent).isActiveAndEnabled) { ((HelperBase)base.Owner).agent.SetDestination(((HelperBase)base.Owner).defaultPos); } if (Vector3.Distance(((Component)base.Owner).transform.position, ((HelperBase)base.Owner).defaultPos) <= ((HelperBase)base.Owner).targetDetectDistance) { GoTo(new FarmerNestState(((StateBase)this).stateMachine)); } } } public class FarmerNestState : FarmerStateBase { private const float JumpDuration = 1.2f; private readonly bool jumpOnEnter; private bool jumped; private FarmTask pendingTask; public FarmerNestState(HelperCleanerStateMachine sm, bool jumpOnEnter = true) : base(sm) { this.jumpOnEnter = jumpOnEnter; } public override void OnEnter() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) ((Behaviour)((HelperBase)base.Owner).agent).enabled = false; ((HelperBase)base.Owner).animator.SetBool("NestSit", true); if (jumpOnEnter) { Jump(((HelperBase)base.Owner).defaultPos); } if (PlayerManager.Instance.isLocalPlayerSpawned) { SoundManager.Instance.PlayServerRpc((SoundEvent)8010, ((Component)base.Owner).transform.position, false, default(ServerRpcParams)); } } public override void ExecutePerSecond() { if (!jumped && ((HelperBase)base.Owner).isActivated) { pendingTask = FarmScheduler.GetNextTask(base.Owner); if (pendingTask != null) { ((MonoBehaviour)base.Owner).StartCoroutine(JumpOff()); } } } private IEnumerator JumpOff() { jumped = true; Jump(((HelperBase)base.Owner).landingPos.position); ((HelperBase)base.Owner).animator.SetBool("NestSit", false); if (PlayerManager.Instance.isLocalPlayerSpawned) { SoundManager.Instance.PlayServerRpc((SoundEvent)8000, ((Component)base.Owner).transform.position, false, default(ServerRpcParams)); } yield return (object)new WaitForSeconds(1.2f); ((Behaviour)((HelperBase)base.Owner).agent).enabled = true; GoTo(new FarmerIdleState(((StateBase)this).stateMachine, pendingTask)); } private void Jump(Vector3 endPos) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) ((HelperBase)base.Owner).networkAnimator.SetTrigger("Jump"); ShortcutExtensions.DOJump(((Component)base.Owner).transform, endPos, 1f, 1, 1.2f, false); ShortcutExtensions.DORotate(((Component)base.Owner).transform, ((HelperBase)base.Owner).defaultRot, 1.2f, (RotateMode)0); } } public class FarmTask { public enum Kind { Plow, Plant, Fertilize, Water, Harvest } public readonly Vector3 movePos; public readonly GardenBed bed; public readonly Kind kind; public readonly Item item; public FarmTask(GardenBed bed, Kind kind, Item item = default(Item)) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0027: Unknown result type (might be due to invalid IL or missing references) this.bed = bed; this.kind = kind; this.item = item; movePos = ((Component)bed).transform.position; } } internal static class FarmScheduler { public static FarmTask GetNextTask(HelperCleaner owner) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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_009a: 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_00a1: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Invalid comparison between Unknown and I4 //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Invalid comparison between Unknown and I4 //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0227: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) GardenManager instance = GardenManager.Instance; if ((Object)(object)instance == (Object)null || instance.gardenBeds == null) { return null; } ContainerNet containerNet = ((HelperBase)owner).containerRef.containerNet; if ((Object)(object)containerNet == (Object)null) { return null; } List source = StringExtension.ToList(containerNet.items); Item val = ((IEnumerable)source).FirstOrDefault((Func)IsHoe); Item val2 = ((IEnumerable)source).FirstOrDefault((Func)IsPlantableSeed); Item val3 = ((IEnumerable)source).FirstOrDefault((Func)IsWateringCan); bool flag = val.id != 0; bool flag2 = val2.id != 0; bool flag3 = val3.id != 0; bool flag4 = containerNet.GetItemAmount((ushort)280) != 0; bool flag5 = !containerNet.IsFull(); if (!(flag || flag2 || flag3 || flag4 || flag5)) { return null; } GardenBed[] gardenBeds = instance.gardenBeds; if (flag5) { GardenBed[] array = gardenBeds; foreach (GardenBed val4 in array) { if (Active(val4) && (int)val4.state.Value == 3 && val4.currentSeedId.Value != 0) { return new FarmTask(val4, FarmTask.Kind.Harvest); } } } if (flag2) { GardenBed[] array = gardenBeds; foreach (GardenBed val5 in array) { if (Active(val5) && (int)val5.state.Value == 1 && val5.currentSeedId.Value == 0) { return new FarmTask(val5, FarmTask.Kind.Plant, val2); } } } if (flag) { GardenBed[] array = gardenBeds; foreach (GardenBed val6 in array) { if (Active(val6) && (int)val6.state.Value == 0) { return new FarmTask(val6, FarmTask.Kind.Plow, val); } } } if (flag4) { GardenBed[] array = gardenBeds; foreach (GardenBed val7 in array) { if (Active(val7) && !val7.isFertilized.Value && Growable(val7)) { return new FarmTask(val7, FarmTask.Kind.Fertilize); } } } if (flag3) { GardenBed[] array = gardenBeds; foreach (GardenBed val8 in array) { if (Active(val8) && !val8.isWatered.Value && Growable(val8)) { return new FarmTask(val8, FarmTask.Kind.Water, val3); } } } return null; } private static bool Active(GardenBed bed) { if ((Object)(object)bed != (Object)null) { return !bed.isInactive.Value; } return false; } private static bool Growable(GardenBed bed) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if ((int)bed.state.Value != 1) { return (int)bed.state.Value == 2; } return true; } public static bool IsHoe(Item item) { //IL_0000: 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_0016: Unknown result type (might be due to invalid IL or missing references) if (item.amount > 0) { if (item.dataId != 302) { return item.dataId == 307; } return true; } return false; } public static bool IsWateringCan(Item item) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) if (item.dataId == 303) { return item.charge > 0; } return false; } public static bool IsPlantableSeed(Item item) { //IL_0000: 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) if (item.amount > 0 && (Object)(object)GardenManager.Instance != (Object)null) { return GardenManager.Instance.IsSeed((uint)item.dataId); } return false; } } internal static class Ids { public const ushort CleanerHouse = 1156; public const ushort Compost = 280; public const ushort Hoe = 302; public const ushort ProHoe = 307; public const ushort WateringCan = 303; public const ushort FarmerOwlHouse = 47801; public const string OwlMarker = "FarmerOwl_Helper"; public const string ItemNameKey = "ItemDataNameFarmerOwlHouse"; public const string ItemDescrKey = "ItemDataDescrFarmerOwlHouse"; public const string OwlTitleKey = "InteractiveNameFarmerOwl"; public const string HouseName = "Farmer Owl House"; public const string HouseDescr = "A farmer owl that plows, plants seeds, waters, fertilizes and harvests your garden beds."; public const string OwlName = "Farmer Owl"; } public class ItemRegistrationPatch { [HarmonyPatch(typeof(ItemManager), "Awake")] [HarmonyPrefix] private static void AddFarmerOwlHouse(ItemManager __instance) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Expected O, but got Unknown ItemData val = ((IEnumerable)__instance.itemDataHub.itemData).FirstOrDefault((Func)((ItemData d) => d.id == 1156)); if ((Object)(object)val == (Object)null) { FarmerOwlPlugin.Log.LogWarning((object)"Cleaner House item not found; Farmer Owl House not registered."); return; } ItemData element = new ItemData { id = 47801, name = "ItemDataNameFarmerOwlHouse", itemDescription = "ItemDataDescrFarmerOwlHouse", icon = val.icon, type = (Type)10, maxStack = 1, price = 1800, shopItem = true, levelDependant = 0, collectiblePrefab = val.collectiblePrefab, fpPrefab = val.fpPrefab, tpPrefab = val.tpPrefab, netPrefab = val.netPrefab }; __instance.itemDataHub.itemData = __instance.itemDataHub.itemData.Append(element).ToArray(); FarmerOwlPlugin.Log.LogInfo((object)"Registered Farmer Owl House item."); } } public class PrefabPatch { private static readonly Color FarmerGreen = new Color(0.192f, 1f, 0.086f); private static CodeMatch InstantiateReturning(Type returnType) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown return new CodeMatch((Func)((CodeInstruction i) => i.opcode == OpCodes.Call && (i.operand as MethodInfo)?.Name == "Instantiate" && (i.operand as MethodInfo)?.ReturnType == returnType), (string)null); } [HarmonyPatch(typeof(FurnitureManager), "OnNetworkSpawn")] [HarmonyTranspiler] private static IEnumerable Furniture_OnNetworkSpawn(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { InstantiateReturning(typeof(GameObject)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldloc_2, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(SavedDevice), "itemDataId")), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PrefabPatch), "InstantiateFurnitureOnLoad", (Type[])null, (Type[])null)) }).RemoveInstruction() .Instructions(); } [HarmonyPatch(typeof(FurnitureManager), "PlaceFurnitureServerRpc", new Type[] { typeof(uint), typeof(Vector3), typeof(Quaternion), typeof(ServerRpcParams) })] [HarmonyTranspiler] private static IEnumerable PlaceFurniture_Free(IEnumerable instructions) { return RouteInstantiateThroughDataId(instructions); } [HarmonyPatch(typeof(FurnitureManager), "PlaceFurnitureServerRpc", new Type[] { typeof(uint), typeof(ushort), typeof(ServerRpcParams) })] [HarmonyTranspiler] private static IEnumerable PlaceFurniture_Slot(IEnumerable instructions) { return RouteInstantiateThroughDataId(instructions); } private static IEnumerable RouteInstantiateThroughDataId(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { InstantiateReturning(typeof(GameObject)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldloc_2, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(Item), "dataId")), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PrefabPatch), "InstantiateFurniture", (Type[])null, (Type[])null)) }).RemoveInstruction() .Instructions(); } [HarmonyPatch(typeof(HelperHouse), "OnNetworkSpawn")] [HarmonyTranspiler] private static IEnumerable Helper_OnNetworkSpawn(IEnumerable instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { InstantiateReturning(typeof(HelperBase)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(HelperHouse), "furniture")), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(PrefabPatch), "InstantiateHelper", (Type[])null, (Type[])null)) }).RemoveInstruction() .Instructions(); } public static GameObject InstantiateFurnitureOnLoad(GameObject original, Vector3 pos, Quaternion rot, Transform parent, uint itemId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(original, pos, rot, parent); if (itemId == 47801) { TintHouse(val); } return val; } public static GameObject InstantiateFurniture(GameObject original, Vector3 pos, Quaternion rot, uint itemId) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate(original, pos, rot); if (itemId == 47801) { TintHouse(val); } return val; } public static HelperBase InstantiateHelper(HelperBase original, Vector3 pos, Quaternion rot, Furniture source) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) HelperBase val = Object.Instantiate(original, pos, rot); if ((Object)(object)val != (Object)null && source.itemData.id == 47801) { TintSkinned(((Component)val).transform.Find("HalloweenOwl_Gr/coat_low")); TintSkinned(((Component)val).transform.Find("HalloweenOwl_Gr/hood_low")); ((Object)val).name = "FarmerOwl_Helper"; ((Component)val).GetComponent().ObjectTitle = "InteractiveNameFarmerOwl"; } return val; } private static void TintHouse(GameObject house) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) Transform val = house.transform.Find("Container/Owls_Nest/Owls_Nest/Owls_Nest"); if ((Object)(object)val != (Object)null) { ((Renderer)((Component)val).GetComponent()).material.color = FarmerGreen; } Furniture component = house.GetComponent(); ItemData itemData = default(ItemData); if ((Object)(object)component != (Object)null && ItemManager.Instance.GetItemData(47801u, ref itemData)) { component.itemData = itemData; } } private static void TintSkinned(Transform t) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) SkinnedMeshRenderer val = (((Object)(object)t != (Object)null) ? ((Component)t).GetComponent() : null); if ((Object)(object)val != (Object)null) { ((Renderer)val).material.color = FarmerGreen; } } } internal static class StateMachineAccess { private static readonly FieldInfo SmField = typeof(HelperCleaner).GetField("stateMachine", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo IsTransition = typeof(HelperCleanerStateMachine).GetField("isTransition", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo CurrentState = typeof(HelperCleanerStateMachine).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); private static readonly FieldInfo PreviousState = typeof(HelperCleanerStateMachine).GetField("k__BackingField", BindingFlags.Instance | BindingFlags.NonPublic); public static HelperCleanerStateMachine Of(HelperCleaner cleaner) { object? obj = SmField?.GetValue(cleaner); return (HelperCleanerStateMachine)((obj is HelperCleanerStateMachine) ? obj : null); } public static void ForceTransition(HelperCleanerStateMachine sm, StateBase newState) { sm.Owner.currentStateName = ((object)newState).GetType().Name; IsTransition.SetValue(sm, true); sm.CurrentState.OnExit(); PreviousState.SetValue(sm, sm.CurrentState); CurrentState.SetValue(sm, newState); sm.CurrentState.OnEnter(); IsTransition.SetValue(sm, false); } } internal class HelperRoutingPatch { [HarmonyPatch(typeof(HelperCleaner), "OnNetworkSpawn")] [HarmonyPostfix] private static void OnNetworkSpawn(HelperCleaner __instance) { if (((NetworkBehaviour)__instance).IsServer && !(((Object)((Component)__instance).gameObject).name != "FarmerOwl_Helper")) { HelperCleanerStateMachine val = StateMachineAccess.Of(__instance); if (val != null) { val.SetInitState((StateBase)new FarmerNestState(val, jumpOnEnter: false)); } } } [HarmonyPatch(typeof(HelperCleaner), "Activate")] [HarmonyPrefix] private static bool Activate(HelperCleaner __instance) { if (!((NetworkBehaviour)__instance).IsServer) { return true; } HelperCleanerStateMachine val = StateMachineAccess.Of(__instance); if (val == null || !(val.CurrentState is FarmerStateBase)) { return true; } ((HelperBase)__instance).isActivated = true; if (val.CurrentState is FarmerReturnHomeState) { val.ChangeState((StateBase)new FarmerIdleState(val)); } return false; } [HarmonyPatch(typeof(HelperCleaner), "Deactivate")] [HarmonyPrefix] private static bool Deactivate(HelperCleaner __instance) { if (!((NetworkBehaviour)__instance).IsServer) { return true; } HelperCleanerStateMachine val = StateMachineAccess.Of(__instance); if (val == null || !(val.CurrentState is FarmerStateBase)) { return true; } val.ChangeState((StateBase)new FarmerReturnHomeState(val)); HelpersManager.Instance.RemoveFromTaskList((HelperBase)(object)__instance); ((HelperBase)__instance).isActivated = false; return false; } [HarmonyPatch(typeof(HelperCleaner), "CheckContainerChanged")] [HarmonyPrefix] private static bool CheckContainerChanged(HelperCleaner __instance) { if (!((NetworkBehaviour)__instance).IsServer) { return true; } HelperCleanerStateMachine val = StateMachineAccess.Of(__instance); if (val == null || !(val.CurrentState is FarmerStateBase)) { return true; } if (val.CurrentState is FarmerMoveToBedState) { val.ChangeState((StateBase)new FarmerIdleState(val)); } return false; } } internal class StateMachinePatch { [HarmonyPatch(typeof(HelperCleanerStateMachine), "ChangeState")] [HarmonyPrefix] private static bool ChangeState(HelperCleanerStateMachine __instance, StateBase newState) { if (!((HelperBase)__instance.Owner).isActivated && newState is FarmerNestState) { StateMachineAccess.ForceTransition(__instance, newState); return false; } return true; } } internal static class PluginMeta { public const string Guid = "KinkoCraft.FarmerOwl"; public const string Name = "Farmer Owl"; public const string Version = "1.0.0"; } [BepInPlugin("KinkoCraft.FarmerOwl", "Farmer Owl", "1.0.0")] public class FarmerOwlPlugin : BaseUnityPlugin { internal static ManualLogSource Log; private void Awake() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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) Log = ((BaseUnityPlugin)this).Logger; Harmony val = new Harmony("KinkoCraft.FarmerOwl"); val.PatchAll(typeof(ItemRegistrationPatch)); val.PatchAll(typeof(PrefabPatch)); val.PatchAll(typeof(HelperRoutingPatch)); val.PatchAll(typeof(StateMachinePatch)); ((MonoBehaviour)this).StartCoroutine(RegisterLocalization()); LocalizationSettings.SelectedLocaleChanged += OnLocaleChanged; Log.LogInfo((object)"Farmer Owl v1.0.0 loaded."); } private void OnDestroy() { LocalizationSettings.SelectedLocaleChanged -= OnLocaleChanged; } private void OnLocaleChanged(Locale locale) { ((MonoBehaviour)this).StartCoroutine(RegisterLocalization()); } private IEnumerator RegisterLocalization() { AsyncOperationHandle init = LocalizationSettings.InitializationOperation; while (!init.IsDone) { yield return null; } Locale locale = LocalizationSettings.SelectedLocale; if (!((Object)(object)locale == (Object)null)) { LocalizedDatabase db = (LocalizedDatabase)(object)LocalizationSettings.StringDatabase; AsyncOperationHandle itemTableOp = db.GetTableAsync(TableReference.op_Implicit("ItemData"), locale); while (!itemTableOp.IsDone) { yield return null; } SetEntry(itemTableOp.Result, "ItemDataNameFarmerOwlHouse", "Farmer Owl House"); SetEntry(itemTableOp.Result, "ItemDataDescrFarmerOwlHouse", "A farmer owl that plows, plants seeds, waters, fertilizes and harvests your garden beds."); AsyncOperationHandle interactiveTableOp = db.GetTableAsync(TableReference.op_Implicit("Interactive"), locale); while (!interactiveTableOp.IsDone) { yield return null; } SetEntry(interactiveTableOp.Result, "InteractiveNameFarmerOwl", "Farmer Owl"); } } private static void SetEntry(StringTable table, string key, string value) { if (!((Object)(object)table == (Object)null)) { StringTableEntry entry = ((DetailedLocalizationTable)(object)table).GetEntry(key); if (entry == null) { ((DetailedLocalizationTable)(object)table).AddEntry(key, value); } else { entry.Value = value; } } } } }