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 BreedingInPen v1.0.0
plugins/BreedingInPen.dll
Decompiled 3 days 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 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("BreedingInPen")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+a132911eeaa2f387033c9213b83b8d67d0146b7f")] [assembly: AssemblyProduct("BreedingInPen")] [assembly: AssemblyTitle("BreedingInPen")] [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; } } } [BepInPlugin("Tie.BreedingInPen", "BreedingInPen", "1.0.0")] public class BreedingInPenPlugin : BaseUnityPlugin { private sealed class Breeder { public string Name; public ConfigEntry<int> MaxCreatures; public int Default; public float SpawnOffset; public float SpawnOffsetMax; public float PartnerRange; } public const string Guid = "Tie.BreedingInPen"; public const string Version = "1.0.0"; private static readonly int s_hasFields = StringExtensionMethods.GetStableHashCode("HasFields"); private static readonly int s_hasProcreationFields = StringExtensionMethods.GetStableHashCode("HasFieldsProcreation"); private static readonly int s_maxCreaturesField = StringExtensionMethods.GetStableHashCode("Procreation.m_maxCreatures"); private static readonly int s_spawnOffsetField = StringExtensionMethods.GetStableHashCode("Procreation.m_spawnOffset"); private static readonly int s_spawnOffsetMaxField = StringExtensionMethods.GetStableHashCode("Procreation.m_spawnOffsetMax"); private static readonly int KeyPlaced = StringExtensionMethods.GetStableHashCode("BreedingInPen_placed"); private ConfigEntry<float> _tickSeconds; private ConfigEntry<bool> _debugLog; private ConfigEntry<bool> _birthAtParent; private ConfigEntry<bool> _birthBetweenParents; private ConfigEntry<float> _newbornSeconds; private readonly Dictionary<int, Breeder> _breeders = new Dictionary<int, Breeder>(); private readonly Dictionary<int, List<int>> _parentsOf = new Dictionary<int, List<int>>(); private readonly List<ZDO> _sectorObjects = new List<ZDO>(); private readonly HashSet<ZDOID> _seen = new HashSet<ZDOID>(); private readonly List<ZDO> _adults = new List<ZDO>(); private readonly List<ZDO> _young = new List<ZDO>(); private bool _resolved; private float _timer; private void Awake() { _tickSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TickSeconds", 2f, "How often (seconds) creatures near players are checked. Newborns are moved on the first check after birth."); _debugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLog", false, "Log every creature changed or newborn moved."); _birthAtParent = ((BaseUnityPlugin)this).Config.Bind<bool>("Pen", "BirthAtParent", true, "Babies appear where the mother stands instead of up to 2 m behind her, so they never start on the other side of a pen fence."); _birthBetweenParents = ((BaseUnityPlugin)this).Config.Bind<bool>("Pen", "BirthBetweenParents", true, "A newborn is moved between its mother and her nearest tamed partner a moment after birth (it may visibly jump once). Both parents are inside the pen, so the baby is too."); _newbornSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Pen", "NewbornSeconds", 20f, "Only tamed babies younger than this are moved, so babies that already walked around are left alone."); } private void Update() { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { _resolved = false; return; } _timer += Time.deltaTime; if (_timer < Mathf.Max(0.5f, _tickSeconds.Value)) { return; } _timer = 0f; try { if (!_resolved) { Resolve(); } Tick(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } private void Resolve() { _resolved = true; _breeders.Clear(); _parentsOf.Clear(); foreach (GameObject item in ZNetScene.instance.m_prefabs.OrderBy<GameObject, string>((GameObject g) => ((Object)g).name, StringComparer.Ordinal)) { Procreation component = item.GetComponent<Procreation>(); if ((Object)(object)component == (Object)null || (Object)(object)item.GetComponent<Character>() == (Object)null || (Object)(object)item.GetComponent<Tameable>() == (Object)null || (Object)(object)item.GetComponent<ZNetView>() == (Object)null) { continue; } _breeders[StringExtensionMethods.GetStableHashCode(((Object)item).name)] = new Breeder { Name = ((Object)item).name, MaxCreatures = ((BaseUnityPlugin)this).Config.Bind<int>("MaxCreatures", ((Object)item).name, -1, $"Tamed {((Object)item).name} stop breeding when this many {((Object)item).name} and their young are within {component.m_totalCheckRange:0.#} m (the game's check). -1 keeps the game's value, {component.m_maxCreatures}."), Default = component.m_maxCreatures, SpawnOffset = component.m_spawnOffset, SpawnOffsetMax = component.m_spawnOffsetMax, PartnerRange = component.m_partnerCheckRange }; GameObject val = (((Object)(object)component.m_offspring == (Object)null) ? null : ZNetScene.instance.GetPrefab(((Object)component.m_offspring).name)); if ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)item && (Object)(object)val.GetComponent<Character>() != (Object)null) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((Object)val).name); if (!_parentsOf.TryGetValue(stableHashCode, out var value)) { value = (_parentsOf[stableHashCode] = new List<int>()); } value.Add(StringExtensionMethods.GetStableHashCode(((Object)item).name)); } } string text = string.Join(", ", (from b in _breeders.Values where b.MaxCreatures.Value >= 0 select b.Name + " " + b.MaxCreatures.Value).DefaultIfEmpty("game values")); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} breeding creature(s): {1}. Limits: {2}. Birth at parent: {3}, between parents: {4}.", _breeders.Count, string.Join(", ", _breeders.Values.Select((Breeder b) => b.Name)), text, _birthAtParent.Value, _birthBetweenParents.Value)); } private void Tick() { if (_breeders.Count == 0) { return; } Collect(); foreach (ZDO adult in _adults) { ApplyOverrides(adult); } if (!_birthBetweenParents.Value) { return; } foreach (ZDO item in _young) { PlaceNewborn(item); } } private void Collect() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) _adults.Clear(); _young.Clear(); _seen.Clear(); SimulationDistance syncedSimulationDistance = ZNet.instance.GetSyncedSimulationDistance(); SimulationDistance val = default(SimulationDistance); ((SimulationDistance)(ref val))..ctor(((SimulationDistance)(ref syncedSimulationDistance)).NearSimulationDistance, 0, ((SimulationDistance)(ref syncedSimulationDistance)).IsClassic); List<Vector3> list = (from p in ZNet.instance.GetPeers() select p.GetRefPos()).ToList(); if (!ZNet.instance.IsDedicated()) { list.Add(ZNet.instance.GetReferencePosition()); } foreach (Vector3 item in list) { _sectorObjects.Clear(); ZDOMan.instance.FindSectorObjects(ZoneSystem.GetZone(item), val, _sectorObjects, (List<ZDO>)null); foreach (ZDO sectorObject in _sectorObjects) { if (sectorObject.IsValid() && _seen.Add(sectorObject.m_uid) && sectorObject.GetBool(ZDOVars.s_tamed, false)) { int prefab = sectorObject.GetPrefab(); if (_breeders.ContainsKey(prefab)) { _adults.Add(sectorObject); } else if (_parentsOf.ContainsKey(prefab)) { _young.Add(sectorObject); } } } } } private void ApplyOverrides(ZDO zdo) { //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) Breeder breeder = _breeders[zdo.GetPrefab()]; bool value = _birthAtParent.Value; if (Override(zdo, s_maxCreaturesField, (breeder.MaxCreatures.Value >= 0) ? new int?(breeder.MaxCreatures.Value) : ((int?)null), breeder.Default) | Override(zdo, s_spawnOffsetField, value ? new float?(0f) : ((float?)null), breeder.SpawnOffset) | Override(zdo, s_spawnOffsetMaxField, value ? new float?(0f) : ((float?)null), breeder.SpawnOffsetMax)) { zdo.Set(s_hasFields, true); zdo.Set(s_hasProcreationFields, true); ZDO val = Replace(zdo, zdo.GetPosition()); Debug($"{breeder.Name} {zdo.m_uid}: breeding limit {zdo.GetInt(s_maxCreaturesField, breeder.Default)}, birth at parent {value}; replaced by {val.m_uid}."); } } private static bool Override(ZDO zdo, int key, int? wanted, int gameValue) { int num = default(int); bool flag = zdo.GetInt(key, ref num); int num2 = wanted ?? gameValue; if ((!wanted.HasValue && !flag) || (flag && num == num2)) { return false; } zdo.Set(key, num2, false); return true; } private static bool Override(ZDO zdo, int key, float? wanted, float gameValue) { float num = default(float); bool flag = zdo.GetFloat(key, ref num); float num2 = wanted ?? gameValue; if ((!wanted.HasValue && !flag) || (flag && num == num2)) { return false; } zdo.Set(key, num2); return true; } private void PlaceNewborn(ZDO baby) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: 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_0146: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) long num = baby.GetLong(ZDOVars.s_spawnTime, 0L); if (num == 0L || !baby.GetBool(ZDOVars.s_tamed, false) || baby.GetBool(KeyPlaced, false) || (ZNet.instance.GetTime() - new DateTime(num)).TotalSeconds > (double)_newbornSeconds.Value) { return; } Vector3 pos = baby.GetPosition(); List<int> parents = _parentsOf[baby.GetPrefab()]; ZDO mother = _adults.Where(delegate(ZDO z) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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_0032: Unknown result type (might be due to invalid IL or missing references) if (parents.Contains(z.GetPrefab()) && z.GetBool(ZDOVars.s_tamed, false)) { Vector3 val4 = z.GetPosition() - pos; return ((Vector3)(ref val4)).sqrMagnitude <= 16f; } return false; }).OrderBy(delegate(ZDO z) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) Vector3 val4 = z.GetPosition() - pos; return ((Vector3)(ref val4)).sqrMagnitude; }).FirstOrDefault(); if (mother == null) { return; } Vector3 at = mother.GetPosition(); float range = Mathf.Max(_breeders[mother.GetPrefab()].PartnerRange, 3f) + 5f; ZDO val = _adults.Where(delegate(ZDO z) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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 (z != mother && z.GetPrefab() == mother.GetPrefab() && z.GetBool(ZDOVars.s_tamed, false)) { Vector3 val4 = z.GetPosition() - at; return ((Vector3)(ref val4)).sqrMagnitude <= range * range; } return false; }).OrderBy(delegate(ZDO z) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) Vector3 val4 = z.GetPosition() - at; return ((Vector3)(ref val4)).sqrMagnitude; }).FirstOrDefault(); baby.Set(KeyPlaced, true); if (val != null) { Vector3 val2 = Vector3.Lerp(at, val.GetPosition(), Random.Range(0.3f, 0.7f)); val2.y = Mathf.Max(at.y, val.GetPosition().y) + 0.5f; ZDO val3 = Replace(baby, val2); Debug($"{((Object)ZNetScene.instance.GetPrefab(baby.GetPrefab())).name} {baby.m_uid} born at ({pos.x:0}, {pos.y:0}, {pos.z:0}) moved between its parents to ({val2.x:0}, {val2.y:0}, {val2.z:0}) as {val3.m_uid}."); } } private static ZDO Replace(ZDO zdo, Vector3 pos) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown //IL_0019: 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) ZPackage val = new ZPackage(); zdo.Serialize(val); val.SetPos(0); ZDO obj = ZDOMan.instance.CreateNewZDO(pos, zdo.GetPrefab()); obj.Deserialize(val); obj.SetPosition(pos); obj.SetOwner(0L); zdo.SetOwnerInternal(ZDOMan.GetSessionID()); ZDOMan.instance.DestroyZDO(zdo); return obj; } private void Debug(string text) { if (_debugLog.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)text); } } }