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 ServerTaming v1.1.6
plugins/ServerTaming.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; 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("ServerTaming")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+1908868251c689d0a9ff071b0cfbc94108a893e1")] [assembly: AssemblyProduct("ServerTaming")] [assembly: AssemblyTitle("ServerTaming")] [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 ServerTaming { [BepInPlugin("Tie.ServerTaming", "ServerTaming", "1.1.6")] public sealed class ServerTamingPlugin : BaseUnityPlugin { private enum PrefabKind { Other, Chest, Sign } private sealed class Feeding { public bool FromTameAssist; public bool Containers; public float Range; public Regex SignRange; public int MaxRange = 64; public int LeaveAtLeast; public float TamingMultiplier = 1f; public float FedMultiplier = 1f; public string ProgressMessageType = ""; } private sealed class Species { public string Prefab; public ConfigEntry<bool> Enabled; public ConfigEntry<string> Foods; public ConfigEntry<float> TamingMinutes; public ConfigEntry<float> FedMinutes; public ConfigEntry<bool> Breeding; public ConfigEntry<float> PregnancyMinutes; public ConfigEntry<int> MaxCreatures; public int Hash; public string Name; public HashSet<int> FoodHashes = new HashSet<int>(); public ZNetView View; } private sealed class Orphan { public int Prefab; public Vector3 Pos; public int Level; public float At; public ZDOID From; public State State; } private sealed class State { public float TameLeft; public double FedUntil; public int Love; public double Pregnant; public double NextBreedCheck; public bool TameAnnounced; } [HarmonyPatch(typeof(ZDOMan), "DestroyZDO")] private static class DestroyPatch { private static void Prefix(ZDO zdo) { try { if (zdo != null && (Object)(object)_instance != (Object)null && _instance._speciesByPrefab.ContainsKey(zdo.GetPrefab())) { _instance.Orphaned(zdo); } } catch (Exception ex) { ServerTamingPlugin instance = _instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogError((object)ex); } } } } [HarmonyPatch(typeof(ZDOMan), "PrepareSave")] private static class SavePatch { private static void Prefix() { try { _instance?.WriteToZdos(); } catch (Exception ex) { ServerTamingPlugin instance = _instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogError((object)ex); } } } } public const string Guid = "Tie.ServerTaming"; public const string Version = "1.1.6"; private static readonly int KeyTameLeft = StringExtensionMethods.GetStableHashCode("ServerTaming_tameLeft"); private static readonly int KeyFedUntil = StringExtensionMethods.GetStableHashCode("ServerTaming_fedUntil"); private static readonly int KeyLove = StringExtensionMethods.GetStableHashCode("ServerTaming_love"); private static readonly int KeyPregnant = StringExtensionMethods.GetStableHashCode("ServerTaming_pregnant"); private const string TameAssistGuid = "ArgusMagnus.ServersideQoL.TameAssist"; private static ServerTamingPlugin _instance; private ConfigEntry<float> _tickSeconds; private ConfigEntry<float> _feedRadius; private ConfigEntry<bool> _requireCalm; private ConfigEntry<float> _messageRange; private ConfigEntry<bool> _progressMessages; private ConfigEntry<int> _maxTameStars; private ConfigEntry<bool> _useTameAssist; private ConfigEntry<bool> _feedWildFromContainers; private ConfigEntry<float> _containerRange; private ConfigEntry<int> _leaveAtLeast; private ConfigEntry<float> _breedCheckSeconds; private ConfigEntry<float> _loveChance; private ConfigEntry<int> _requiredLovePoints; private ConfigEntry<float> _partnerRange; private ConfigEntry<float> _populationRange; private ConfigEntry<int> _maxCreatures; private ConfigEntry<int> _maxTamedNearby; private ConfigEntry<bool> _debugLog; private readonly List<Species> _species = new List<Species>(); private readonly Dictionary<int, Species> _speciesByPrefab = new Dictionary<int, Species>(); private readonly HashSet<int> _foodPrefabs = new HashSet<int>(); private readonly Dictionary<ZDOID, State> _states = new Dictionary<ZDOID, State>(); private readonly List<Orphan> _orphans = new List<Orphan>(); private readonly List<ZDO> _sectorObjects = new List<ZDO>(); private readonly HashSet<ZDOID> _seen = new HashSet<ZDOID>(); private readonly List<ZDO> _animals = new List<ZDO>(); private readonly List<ZDO> _foods = new List<ZDO>(); private readonly HashSet<ZDOID> _eaten = new HashSet<ZDOID>(); private readonly List<ZDO> _chests = new List<ZDO>(); private readonly List<ZDO> _signs = new List<ZDO>(); private readonly Dictionary<ZDOID, float> _chestRanges = new Dictionary<ZDOID, float>(); private readonly Dictionary<int, PrefabKind> _kinds = new Dictionary<int, PrefabKind>(); private Feeding _feeding = new Feeding(); private bool _resolved; private float _timer; private double _lastTick = -1.0; private int _ticks; private void Awake() { //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Expected O, but got Unknown //IL_0347: Unknown result type (might be due to invalid IL or missing references) //IL_0352: Unknown result type (might be due to invalid IL or missing references) //IL_0357: Unknown result type (might be due to invalid IL or missing references) _instance = this; string text = Path.Combine(Paths.ConfigPath, "local.servertaming.cfg"); if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath) && File.Exists(text)) { File.Move(text, ((BaseUnityPlugin)this).Config.ConfigFilePath); ((BaseUnityPlugin)this).Config.Reload(); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Moved local.servertaming.cfg to " + Path.GetFileName(((BaseUnityPlugin)this).Config.ConfigFilePath) + ".")); } _tickSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "TickSeconds", 5f, "How often (seconds) animals near players are checked."); _feedRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "FeedRadius", 8f, "Animals eat matching food lying within this many metres. They do not walk to it, so keep them penned with the food inside."); _requireCalm = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "RequireCalm", true, "Taming and breeding pause while the animal is alerted (fleeing or fighting), like vanilla."); _messageRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "MessageRange", 30f, "Players within this many metres see taming and birth messages."); _progressMessages = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ProgressMessages", true, "Show taming progress to nearby players: at 25/50/75%, or with TameAssist's TamingProgressMessageType when TameAssist is used."); _debugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLog", false, "Log feeding, love and breeding decisions for every animal near players (verbose; for troubleshooting)."); _maxTameStars = ((BaseUnityPlugin)this).Config.Bind<int>("General", "MaxTameStars", -1, "Highest star count that can be tamed; -1 means any (including the 3+ star creatures from level mods such as ServersideQoL CreatureLevelUp). Offspring keep their parent's stars."); _useTameAssist = ((BaseUnityPlugin)this).Config.Bind<bool>("Containers", "UseTameAssistSettings", true, "When ServersideQoL TameAssist is installed, use its FeedFromContainers settings (range, chest sign range, LeaveAtLeast), its TamingTimeMultiplier and FedDurationMultiplier, and its TamingProgressMessageType. The two settings below are then ignored."); _containerRange = ((BaseUnityPlugin)this).Config.Bind<float>("Containers", "FeedFromContainersRange", 0f, "Without TameAssist: animals eat from chests within this many metres (0 = off)."); _leaveAtLeast = ((BaseUnityPlugin)this).Config.Bind<int>("Containers", "LeaveAtLeast", 1, "Without TameAssist: keep at least this many of each food in a chest."); _feedWildFromContainers = ((BaseUnityPlugin)this).Config.Bind<bool>("Containers", "FeedWildFromContainers", true, "Wild animals being tamed also eat from chests (TameAssist itself only feeds tamed animals from chests, but deer and necks can't walk to food)."); _breedCheckSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Breeding", "CheckSeconds", 30f, "How often each fed tamed animal tries to gain a love point."); _loveChance = ((BaseUnityPlugin)this).Config.Bind<float>("Breeding", "LoveChance", 0.5f, "Chance (0-1) of gaining a love point on each check when a partner is near."); _requiredLovePoints = ((BaseUnityPlugin)this).Config.Bind<int>("Breeding", "RequiredLovePoints", 4, "Love points needed to become pregnant."); _partnerRange = ((BaseUnityPlugin)this).Config.Bind<float>("Breeding", "PartnerRange", 5f, "A tamed partner of the same kind must be within this many metres."); _populationRange = ((BaseUnityPlugin)this).Config.Bind<float>("Breeding", "PopulationRange", 15f, "Radius used to count animals of the same kind for MaxCreatures."); _maxCreatures = ((BaseUnityPlugin)this).Config.Bind<int>("Breeding", "MaxCreatures", 8, "No new love points when this many animals of the same kind are within PopulationRange. Each animal's own MaxCreatures setting overrides this."); _maxTamedNearby = ((BaseUnityPlugin)this).Config.Bind<int>("Breeding", "MaxTamedNearby", 30, "No breeding when this many tamed animals of the same kind are anywhere in the area loaded around players, wherever they wandered (0 = no limit). A safety net for animals that leave the pen, where MaxCreatures only sees their small group."); AddSpecies("Deer", "Raspberry,Blueberries,Cloudberry,Carrot,Turnip,Onion,Mushroom,MushroomYellow", 25f, 5f, 10f); AddSpecies("Neck", "FishRaw", 25f, 5f, 10f); new ConsoleCommand("tamestatus", "[radius] - show server taming/breeding progress of animals near you; use through 'server tamestatus'", new ConsoleEvent(Status), false, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); Harmony val = new Harmony("Tie.ServerTaming"); val.PatchAll(typeof(SavePatch)); val.PatchAll(typeof(DestroyPatch)); } private void AddSpecies(string prefab, string foods, float taming, float fed, float pregnancy) { _species.Add(new Species { Prefab = prefab, Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>(prefab, "Enabled", true, "Make " + prefab + " tameable and breedable."), Foods = ((BaseUnityPlugin)this).Config.Bind<string>(prefab, "Foods", foods, "Comma-separated item prefab names it eats."), TamingMinutes = ((BaseUnityPlugin)this).Config.Bind<float>(prefab, "TamingMinutes", taming, "Minutes of being fed (and calm) needed to tame it."), FedMinutes = ((BaseUnityPlugin)this).Config.Bind<float>(prefab, "FedMinutes", fed, "Minutes one food item keeps it fed."), Breeding = ((BaseUnityPlugin)this).Config.Bind<bool>(prefab, "Breeding", true, "Tamed ones breed and give birth to tamed adults."), PregnancyMinutes = ((BaseUnityPlugin)this).Config.Bind<float>(prefab, "PregnancyMinutes", pregnancy, "Minutes from pregnancy to birth."), MaxCreatures = ((BaseUnityPlugin)this).Config.Bind<int>(prefab, "MaxCreatures", -1, "No new love points when this many " + prefab + " are within [Breeding] PopulationRange; -1 uses [Breeding] MaxCreatures.") }); } private void Resolve() { _resolved = true; foreach (Species item in _species) { GameObject prefab = ZNetScene.instance.GetPrefab(item.Prefab); if (!item.Enabled.Value || (Object)(object)prefab == (Object)null || (Object)(object)prefab.GetComponent<Character>() == (Object)null) { if (item.Enabled.Value) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Creature prefab '" + item.Prefab + "' not found; it is disabled.")); } continue; } item.Hash = StringExtensionMethods.GetStableHashCode(item.Prefab); item.Name = prefab.GetComponent<Character>().m_name; item.View = prefab.GetComponent<ZNetView>(); foreach (string item2 in from f in item.Foods.Value.Split(new char[1] { ',' }) select f.Trim() into f where f.Length > 0 select f) { GameObject prefab2 = ZNetScene.instance.GetPrefab(item2); if ((Object)(object)prefab2 == (Object)null || (Object)(object)prefab2.GetComponent<ItemDrop>() == (Object)null) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Food '" + item2 + "' for " + item.Prefab + " is not an item prefab; ignored.")); } else { item.FoodHashes.Add(StringExtensionMethods.GetStableHashCode(item2)); _foodPrefabs.Add(StringExtensionMethods.GetStableHashCode(item2)); } } _speciesByPrefab[item.Hash] = item; ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0}: {1} food(s), taming {2} min, breeding {3}.", item.Prefab, item.FoodHashes.Count, item.TamingMinutes.Value, item.Breeding.Value ? "on" : "off")); } } private void Update() { if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer() || ZDOMan.instance == null || (Object)(object)ZNetScene.instance == (Object)null) { _resolved = false; _states.Clear(); _orphans.Clear(); _lastTick = -1.0; return; } _timer += Time.deltaTime; if (_timer < Mathf.Max(1f, _tickSeconds.Value)) { return; } _timer = 0f; try { if (!_resolved) { Resolve(); } Tick(); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)ex); } } private void Tick() { //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d5: Unknown result type (might be due to invalid IL or missing references) double timeSeconds = ZNet.instance.GetTimeSeconds(); float dt = ((_lastTick < 0.0) ? 0f : Mathf.Clamp((float)(timeSeconds - _lastTick), 0f, Mathf.Max(1f, _tickSeconds.Value) * 3f)); _lastTick = timeSeconds; if (_speciesByPrefab.Count == 0) { return; } _feeding = ReadFeeding(); Collect(); UpdateChestRanges(); _eaten.Clear(); foreach (ZDO animal in _animals) { Species species = _speciesByPrefab[animal.GetPrefab()]; State state = GetState(animal); bool flag = animal.GetBool(ZDOVars.s_tamed, false); if (flag || CanTame(animal)) { bool flag2 = !_requireCalm.Value || !animal.GetBool(ZDOVars.s_alert, false); if (timeSeconds >= state.FedUntil) { TryEat(animal, species, state, timeSeconds, flag); } bool flag3 = timeSeconds < state.FedUntil; if (!flag) { UpdateTaming(animal, species, state, flag3, flag2, dt); } else if (species.Breeding.Value) { UpdateBreeding(animal, species, state, flag3 && flag2, timeSeconds); } } } if (++_ticks % 60 != 0) { return; } foreach (ZDOID item in _states.Keys.Where((ZDOID id) => ZDOMan.instance.GetZDO(id) == null).ToList()) { _states.Remove(item); } } private void Collect() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_009e: 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_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) _animals.Clear(); _foods.Clear(); _chests.Clear(); _signs.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)) { continue; } int prefab = sectorObject.GetPrefab(); if (_speciesByPrefab.ContainsKey(prefab)) { _animals.Add(sectorObject); } else if (_foodPrefabs.Contains(prefab) && !sectorObject.GetBool(ZDOVars.s_piece, false)) { _foods.Add(sectorObject); } else if (_feeding.Containers) { switch (Classify(prefab)) { case PrefabKind.Chest: _chests.Add(sectorObject); break; case PrefabKind.Sign: _signs.Add(sectorObject); break; } } } } } private State GetState(ZDO zdo) { //IL_0007: 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) if (!_states.TryGetValue(zdo.m_uid, out var value) && (value = Adopt(zdo)) == null) { value = new State { TameLeft = zdo.GetFloat(KeyTameLeft, -1f), FedUntil = (double)zdo.GetLong(KeyFedUntil, 0L) / 1000.0, Love = zdo.GetInt(KeyLove, 0), Pregnant = (double)zdo.GetLong(KeyPregnant, 0L) / 1000.0 }; _states[zdo.m_uid] = value; } return value; } private void Orphaned(ZDO zdo) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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) //IL_0095: 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) if (_states.TryGetValue(zdo.m_uid, out var value)) { _states.Remove(zdo.m_uid); _orphans.RemoveAll((Orphan o) => Time.time - o.At > 60f); _orphans.Add(new Orphan { Prefab = zdo.GetPrefab(), Pos = zdo.GetPosition(), Level = zdo.GetInt(ZDOVars.s_level, 1), At = Time.time, From = zdo.m_uid, State = value }); } } private State Adopt(ZDO zdo) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) if (_orphans.Count == 0) { return null; } int prefab = zdo.GetPrefab(); int level = zdo.GetInt(ZDOVars.s_level, 1); Vector3 pos = zdo.GetPosition(); Orphan orphan = _orphans.Where(delegate(Orphan o) { //IL_0030: 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) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (o.Prefab == prefab && o.Level == level && Time.time - o.At <= 60f) { Vector3 val = o.Pos - pos; return ((Vector3)(ref val)).sqrMagnitude <= 100f; } return false; }).OrderBy(delegate(Orphan o) { //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 val = o.Pos - pos; return ((Vector3)(ref val)).sqrMagnitude; }).FirstOrDefault(); if (orphan == null) { return null; } _orphans.Remove(orphan); _states[zdo.m_uid] = orphan.State; Debug($"{zdo.m_uid}: took over the state of replaced {orphan.From} (level {level})."); return orphan.State; } private string Describe(ZDO zdo) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0098: Unknown result type (might be due to invalid IL or missing references) Vector3 position = zdo.GetPosition(); return string.Format("{0} {1} ({2} star(s), {3}, owner {4}) at ({5:0}, {6:0}, {7:0})", _speciesByPrefab[zdo.GetPrefab()].Prefab, zdo.m_uid, zdo.GetInt(ZDOVars.s_level, 1) - 1, zdo.GetBool(ZDOVars.s_tamed, false) ? "tamed" : "wild", zdo.GetOwner(), position.x, position.y, position.z); } private void Debug(string text) { if (_debugLog.Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)text); } } private PrefabKind Classify(int prefab) { if (!_kinds.TryGetValue(prefab, out var value)) { GameObject prefab2 = ZNetScene.instance.GetPrefab(prefab); value = ((!((Object)(object)prefab2 == (Object)null)) ? (((Object)(object)prefab2.GetComponent<Container>() != (Object)null && (Object)(object)prefab2.GetComponent<Piece>() != (Object)null) ? PrefabKind.Chest : (((Object)(object)prefab2.GetComponent<Sign>() != (Object)null) ? PrefabKind.Sign : PrefabKind.Other)) : PrefabKind.Other); _kinds[prefab] = value; } return value; } private Feeding ReadFeeding() { Feeding feeding = new Feeding(); List<ConfigFile> list = ((!_useTameAssist.Value || !Chainloader.PluginInfos.ContainsKey("ArgusMagnus.ServersideQoL.TameAssist")) ? null : (from i in Chainloader.PluginInfos.Values where i.Metadata.GUID.StartsWith("ArgusMagnus.ServersideQoL", StringComparison.Ordinal) && (Object)(object)i.Instance != (Object)null select i.Instance.Config).ToList()); if (list != null && Get(list, "Enabled", fallback: true)) { feeding.FromTameAssist = true; feeding.Containers = Get(list, "FeedFromContainers", fallback: false); feeding.Range = Get(list, "FeedFromContainersRange", 0f); feeding.MaxRange = Get(list, "FeedFromContainersMaxRange", 64); feeding.LeaveAtLeast = Get(list, "FeedFromContainersLeaveAtLeast", 1); feeding.TamingMultiplier = Get(list, "TamingTimeMultiplier", 1f); feeding.FedMultiplier = Get(list, "FedDurationMultiplier", 1f); feeding.ProgressMessageType = Get(list, "TamingProgressMessageType", (object)"").ToString(); string text = Get(list, "FeedFromContainersRangeSignPrefix", ""); string text2 = text.Replace("\ufe0f", ""); if (text.Length > 0) { feeding.SignRange = new Regex(((text == text2) ? Regex.Escape(text) : ("(?:" + Regex.Escape(text) + "|" + Regex.Escape(text2) + ")")) + "(?<R>\\d+)"); } } else { feeding.Range = _containerRange.Value; feeding.Containers = feeding.Range > 0f; feeding.LeaveAtLeast = _leaveAtLeast.Value; } return feeding; } private static T Get<T>(List<ConfigFile> configs, string key, T fallback) { foreach (ConfigFile config in configs) { foreach (ConfigDefinition key2 in config.Keys) { if (key2.Key == key && (key2.Section == "TameAssist" || key2.Section.EndsWith(".TameAssist", StringComparison.Ordinal))) { object boxedValue = config[key2].BoxedValue; if (boxedValue is T) { return (T)boxedValue; } } } } return fallback; } private void UpdateChestRanges() { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0150: Unknown result type (might be due to invalid IL or missing references) _chestRanges.Clear(); if (!_feeding.Containers) { return; } foreach (ZDO chest in _chests) { int? num = SignRange(chest); if (num.HasValue) { int valueOrDefault = num.GetValueOrDefault(); _chestRanges[chest.m_uid] = Mathf.Min(valueOrDefault, _feeding.MaxRange); } else if (_feeding.Range > 0f) { _chestRanges[chest.m_uid] = _feeding.Range; } } foreach (ZDO sign in _signs) { int? num = SignRange(sign); if (num.HasValue) { int valueOrDefault2 = num.GetValueOrDefault(); Vector3 pos = sign.GetPosition(); ZDO val = _chests.Where(delegate(ZDO c) { //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 val2 = c.GetPosition() - pos; return ((Vector3)(ref val2)).sqrMagnitude <= 9f; }).OrderBy(delegate(ZDO c) { //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 val2 = c.GetPosition() - pos; return ((Vector3)(ref val2)).sqrMagnitude; }).FirstOrDefault(); if (val != null && !SignRange(val).HasValue) { _chestRanges[val.m_uid] = Mathf.Min(valueOrDefault2, _feeding.MaxRange); } } } } private int? SignRange(ZDO zdo) { if (_feeding.SignRange == null) { return null; } Match match = _feeding.SignRange.Match(zdo.GetString(ZDOVars.s_text, "")); if (!match.Success || !int.TryParse(match.Groups["R"].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result)) { return null; } return result; } private float TamingSeconds(Species s) { return Mathf.Max(1f, s.TamingMinutes.Value * 60f * _feeding.TamingMultiplier); } private void TryEat(ZDO animal, Species s, State st, double now, bool tamed) { string text = (TryEatFromGround(animal, s) ? "the ground" : (((tamed || _feedWildFromContainers.Value) && TryEatFromChest(animal, s)) ? "a chest" : null)); if (text != null) { st.FedUntil = now + (double)s.FedMinutes.Value * 60.0 * (double)_feeding.FedMultiplier; } if (_debugLog.Value) { Debug(Describe(animal) + " is hungry: " + ((text != null) ? ("ate from " + text + ".") : $"no food found ({_chests.Count((ZDO c) => _chestRanges.ContainsKey(c.m_uid))} feeding chest(s) loaded).")); } } private bool TryEatFromChest(ZDO animal, Species s) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: 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_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_0080: Unknown result type (might be due to invalid IL or missing references) if (!_feeding.Containers) { return false; } Vector3 pos = animal.GetPosition(); foreach (ZDO item in _chests.OrderBy(delegate(ZDO c) { //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 val2 = c.GetPosition() - pos; return ((Vector3)(ref val2)).sqrMagnitude; })) { if (_chestRanges.TryGetValue(item.m_uid, out var value)) { Vector3 val = item.GetPosition() - pos; if (((Vector3)(ref val)).sqrMagnitude <= value * value && TakeOneFood(item, s.FoodHashes, _feeding.LeaveAtLeast)) { return true; } } } return false; } private static bool TakeOneFood(ZDO chest, HashSet<int> foods, int leaveAtLeast) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown if (chest.GetBool(ZDOVars.s_inUse, false)) { return false; } byte[] byteArray = chest.GetByteArray(ZDOVars.s_items, (byte[])null); if (byteArray == null || byteArray.Length == 0) { return false; } List<(int, int, int, int)> list = new List<(int, int, int, int)>(); int num2; byte[] array; try { ZPackage val = new ZPackage(byteArray); int num = val.ReadInt(); if (num < 108) { return false; } num2 = val.ReadUShort(); for (int i = 0; i < num2; i++) { int pos = val.GetPos(); ItemData val2 = new ItemData(); int item = ItemData.Load(val, val2, (Item)num); list.Add((pos, val.GetPos(), item, val2.m_stack)); } array = val.GetArray(); } catch (Exception) { return false; } foreach (int food in foods) { List<(int, int, int, int)> list2 = (from x in list where x.Hash == food && x.Stack > 0 orderby x.Stack select x).ToList(); if (list2.Sum<(int, int, int, int)>(((int Start, int End, int Hash, int Stack) x) => x.Stack) - 1 >= Math.Max(0, leaveAtLeast)) { (int, int, int, int) tuple = list2[0]; byte b = array[tuple.Item1 + 7]; byte[] array2; if (tuple.Item4 > 1 && (b & 8) != 0) { array2 = (byte[])array.Clone(); int num3 = tuple.Item1 + 8 + (((b & 4) != 0) ? 2 : 0); ushort num4 = (ushort)(tuple.Item4 - 1); array2[num3] = (byte)(num4 & 0xFF); array2[num3 + 1] = (byte)(num4 >> 8); } else { array2 = new byte[array.Length - (tuple.Item2 - tuple.Item1)]; Buffer.BlockCopy(array, 0, array2, 0, tuple.Item1); Buffer.BlockCopy(array, tuple.Item2, array2, tuple.Item1, array.Length - tuple.Item2); ushort num5 = (ushort)(num2 - 1); array2[4] = (byte)(num5 & 0xFF); array2[5] = (byte)(num5 >> 8); } if (!chest.IsOwner()) { chest.SetOwner(ZDOMan.GetSessionID()); } chest.Set(ZDOVars.s_items, array2); return true; } } return false; } private bool TryEatFromGround(ZDO animal, Species s) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0068: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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) Vector3 position = animal.GetPosition(); float num = _feedRadius.Value * _feedRadius.Value; ZDO val = null; foreach (ZDO food in _foods) { if (!s.FoodHashes.Contains(food.GetPrefab()) || _eaten.Contains(food.m_uid)) { continue; } Vector3 val2 = food.GetPosition() - position; if (!(Mathf.Abs(val2.y) > 4f)) { float num2 = val2.x * val2.x + val2.z * val2.z; if (num2 <= num) { num = num2; val = food; } } } if (val == null) { return false; } if (!val.IsOwner()) { val.SetOwner(ZDOMan.GetSessionID()); } int num3 = val.GetInt(ZDOVars.s_stack, 1); if (num3 > 1) { val.Set(ZDOVars.s_stack, num3 - 1, false); } else { _eaten.Add(val.m_uid); ZDOMan.instance.DestroyZDO(val); } return true; } private void UpdateTaming(ZDO zdo, Species s, State st, bool fed, bool calm, float dt) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) float num = TamingSeconds(s); if (st.TameLeft < 0f || st.TameLeft > num) { st.TameLeft = num; } if (fed && calm && st.TameLeft > 0f) { int num2 = Step(st.TameLeft, num); st.TameLeft = Mathf.Max(0f, st.TameLeft - dt); int num3 = Step(st.TameLeft, num); if (_progressMessages.Value && !_feeding.FromTameAssist && num3 > num2 && num3 < 4) { Message(zdo.GetPosition(), (MessageType)1, $"{s.Name}: taming {num3 * 25}%"); } } if (_progressMessages.Value && _feeding.FromTameAssist && st.TameLeft > 0f && st.TameLeft < num) { string text = string.Format(fed ? "$hud_tameness {0:P0}" : "$hud_tameness {0:P0}, $hud_tamehungry", 1f - st.TameLeft / num); TameAssistMessage(zdo.GetPosition(), text); } if (st.TameLeft <= 0f) { Tame(zdo, s, st); } } private bool CanTame(ZDO zdo) { if (_maxTameStars.Value >= 0) { return zdo.GetInt(ZDOVars.s_level, 1) - 1 <= _maxTameStars.Value; } return true; } private static int Step(float left, float total) { return (int)((1f - left / total) * 4f); } private void Tame(ZDO zdo, Species s, State st) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) long owner = zdo.GetOwner(); if (owner == 0L || owner == ZDOMan.GetSessionID()) { zdo.Set(ZDOVars.s_tamed, true); } else { ZRoutedRpc.instance.InvokeRoutedRPC(owner, zdo.m_uid, "RPC_SetTamed", new object[1] { true }); } if (!st.TameAnnounced) { st.TameAnnounced = true; Message(zdo.GetPosition(), (MessageType)2, s.Name + " $hud_tamedone"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Tamed " + s.Prefab + " at " + Format(zdo.GetPosition()) + ".")); } } private void UpdateBreeding(ZDO zdo, Species s, State st, bool ready, double now) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) if (st.Pregnant > 0.0) { if (now - st.Pregnant >= (double)s.PregnancyMinutes.Value * 60.0) { st.Pregnant = 0.0; string text = Crowded(zdo, s, atBirth: true); if (text != null) { ((BaseUnityPlugin)this).Logger.LogInfo((object)(s.Prefab + " birth at " + Format(zdo.GetPosition()) + " skipped: " + text + ".")); } else { Birth(zdo, s); } } } else { if (!ready || now < st.NextBreedCheck) { return; } float num = Mathf.Max(1f, _breedCheckSeconds.Value); st.NextBreedCheck = now + (double)(num * Random.Range(1f, 1.5f)); if (Random.value > _loveChance.Value) { return; } string text2 = Crowded(zdo, s, atBirth: false); if (text2 != null) { Debug(Describe(zdo) + ": no love point (" + text2 + ")."); return; } Debug($"{Describe(zdo)}: love {st.Love + 1}/{Mathf.Max(1, _requiredLovePoints.Value)}."); if (++st.Love >= Mathf.Max(1, _requiredLovePoints.Value)) { st.Love = 0; st.Pregnant = now; } } } private string Crowded(ZDO zdo, Species s, bool atBirth) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: 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) Vector3 position = zdo.GetPosition(); float num = _populationRange.Value * _populationRange.Value; float num2 = _partnerRange.Value * _partnerRange.Value; int num3 = 0; int num4 = 0; bool flag = false; foreach (ZDO animal in _animals) { if (animal.GetPrefab() != s.Hash) { continue; } bool flag2 = animal.GetBool(ZDOVars.s_tamed, false); if (flag2) { num4++; } Vector3 val = animal.GetPosition() - position; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; if (sqrMagnitude <= num) { num3++; if (!atBirth && animal != zdo && _states.TryGetValue(animal.m_uid, out var value) && value.Pregnant > 0.0) { num3++; } } if (animal != zdo && sqrMagnitude <= num2 && flag2) { flag = true; } } int num5 = ((s.MaxCreatures.Value >= 0) ? s.MaxCreatures.Value : _maxCreatures.Value); if (!atBirth && !flag) { return "no tamed partner in range"; } if (num3 >= num5) { return string.Format("{0} of MaxCreatures {1} nearby{2}", num3, num5, atBirth ? "" : ", counting pregnancies"); } if (_maxTamedNearby.Value > 0 && num4 >= _maxTamedNearby.Value) { return $"{num4} tamed {s.Prefab} around players, MaxTamedNearby {_maxTamedNearby.Value}"; } return null; } private void Birth(ZDO parent, Species s) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: 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_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) //IL_007e: 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) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) Vector3 mother = parent.GetPosition(); ZDO val = _animals.Where(delegate(ZDO a) { //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 (a != parent && a.GetPrefab() == s.Hash && a.GetBool(ZDOVars.s_tamed, false)) { Vector3 val4 = a.GetPosition() - mother; return ((Vector3)(ref val4)).sqrMagnitude <= 100f; } return false; }).OrderBy(delegate(ZDO a) { //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 = a.GetPosition() - mother; return ((Vector3)(ref val4)).sqrMagnitude; }).FirstOrDefault(); Vector3 val2 = ((val == null) ? mother : Vector3.Lerp(mother, val.GetPosition(), Random.Range(0.3f, 0.7f))); val2.y += 0.5f; ZDO val3 = ZDOMan.instance.CreateNewZDO(val2, s.Hash); val3.Persistent = s.View.m_persistent; val3.Type = s.View.m_type; val3.Distant = s.View.m_distant; val3.SetPrefab(s.Hash); val3.SetRotation(Quaternion.Euler(0f, Random.Range(0f, 360f), 0f)); val3.Set(ZDOVars.s_tamed, true); int num = parent.GetInt(ZDOVars.s_level, 1); if (num > 1) { val3.Set(ZDOVars.s_level, num, false); } val3.SetOwner(0L); Message(val2, (MessageType)2, "A new " + s.Name + " was born"); ((BaseUnityPlugin)this).Logger.LogInfo((object)(s.Prefab + " born at " + Format(val2) + ".")); } private void TameAssistMessage(Vector3 pos, string text) { //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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) //IL_0054: 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_005a: 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_0077: Unknown result type (might be due to invalid IL or missing references) string progressMessageType = _feeding.ProgressMessageType; if (progressMessageType == "InWorld") { float num = _messageRange.Value * _messageRange.Value; { foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { Vector3 val = peer.GetRefPos() - pos; if (((Vector3)(ref val)).sqrMagnitude <= num) { ZPackage val2 = new ZPackage(); val2.Write(0); val2.Write(pos); val2.Write(text); val2.Write(false); ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "RPC_DamageText", new object[1] { val2 }); } } return; } } if (progressMessageType.StartsWith("TopLeft", StringComparison.Ordinal)) { Message(pos, (MessageType)1, text); } else if (progressMessageType.StartsWith("Center", StringComparison.Ordinal)) { Message(pos, (MessageType)2, text); } } private void Message(Vector3 pos, MessageType type, string text) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0067: Expected I4, but got Unknown float num = _messageRange.Value * _messageRange.Value; foreach (ZNetPeer peer in ZNet.instance.GetPeers()) { Vector3 val = peer.GetRefPos() - pos; if (((Vector3)(ref val)).sqrMagnitude <= num) { ZRoutedRpc.instance.InvokeRoutedRPC(peer.m_uid, "ShowMessage", new object[2] { (int)type, text }); } } } private void WriteToZdos() { //IL_0020: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) foreach (KeyValuePair<ZDOID, State> state in _states) { if (ZDOMan.instance.GetZDO(state.Key) != null) { ZDOExtraData.Set(state.Key, KeyTameLeft, state.Value.TameLeft); ZDOExtraData.Set(state.Key, KeyFedUntil, (long)(state.Value.FedUntil * 1000.0)); ZDOExtraData.Set(state.Key, KeyLove, state.Value.Love); ZDOExtraData.Set(state.Key, KeyPregnant, (long)(state.Value.Pregnant * 1000.0)); } } } private void Status(ConsoleEventArgs args) { //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_045e: Unknown result type (might be due to invalid IL or missing references) //IL_0496: Unknown result type (might be due to invalid IL or missing references) //IL_04a1: Unknown result type (might be due to invalid IL or missing references) Terminal context = args.Context; if ((Object)(object)ZNet.instance == (Object)null || !ZNet.instance.IsServer()) { Print(context, "tamestatus must run on the server: type 'server tamestatus' instead."); return; } float radius = 30f; if (args.Args.Length > 1 && float.TryParse(args.Args[1], NumberStyles.Float, CultureInfo.InvariantCulture, out var result) && result > 0f) { radius = result; } Vector3? center = CallerPosition(); if (!center.HasValue) { Print(context, "Could not find your position."); return; } if (!_resolved) { Resolve(); } _feeding = ReadFeeding(); Collect(); UpdateChestRanges(); double timeSeconds = ZNet.instance.GetTimeSeconds(); List<ZDO> list = _animals.Where(delegate(ZDO z) { //IL_0001: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val = z.GetPosition() - center.Value; return ((Vector3)(ref val)).sqrMagnitude <= radius * radius; }).OrderBy(delegate(ZDO z) { //IL_0001: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val = z.GetPosition() - center.Value; return ((Vector3)(ref val)).sqrMagnitude; }).ToList(); Print(context, $"{list.Count} tameable animal(s) within {radius:0} m."); foreach (ZDO item in list.Take(20)) { Species species = _speciesByPrefab[item.GetPrefab()]; State state = GetState(item); float num = Vector3.Distance(item.GetPosition(), center.Value); string text = ((timeSeconds < state.FedUntil) ? $"fed {(state.FedUntil - timeSeconds) / 60.0:0.0} min" : "hungry"); int num2 = item.GetInt(ZDOVars.s_level, 1) - 1; string text2; if (!item.GetBool(ZDOVars.s_tamed, false) && !CanTame(item)) { text2 = $"wild, {num2} star(s): above MaxTameStars, cannot be tamed"; } else if (!item.GetBool(ZDOVars.s_tamed, false)) { float num3 = TamingSeconds(species); float num4 = ((state.TameLeft < 0f) ? num3 : state.TameLeft); text2 = $"wild, taming {(1f - num4 / num3) * 100f:0}% ({num4 / 60f:0.0} min left), {text}"; } else { text2 = ((!(state.Pregnant > 0.0)) ? $"tamed, love {state.Love}/{_requiredLovePoints.Value}, {text}" : $"tamed, pregnant ({((double)species.PregnancyMinutes.Value * 60.0 - (timeSeconds - state.Pregnant)) / 60.0:0.0} min left), {text}"); } Print(context, $"{species.Prefab} {new string('*', Math.Max(0, num2))} {num:0} m: {text2}"); } Print(context, string.Format("Chest feeding: {0}{1}, global range {2:0} m, leave at least {3}, wild animals {4}.", _feeding.Containers ? "on" : "off", _feeding.FromTameAssist ? " (TameAssist settings)" : "", _feeding.Range, _feeding.LeaveAtLeast, _feedWildFromContainers.Value ? "yes" : "no")); HashSet<int> foods = new HashSet<int>(_species.SelectMany((Species x) => x.FoodHashes)); foreach (ZDO item2 in _chests.Where(delegate(ZDO c) { //IL_0001: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val = c.GetPosition() - center.Value; return ((Vector3)(ref val)).sqrMagnitude <= (radius + 64f) * (radius + 64f); }).OrderBy(delegate(ZDO c) { //IL_0001: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) Vector3 val = c.GetPosition() - center.Value; return ((Vector3)(ref val)).sqrMagnitude; }).Take(10)) { float value; string text3 = (_chestRanges.TryGetValue(item2.m_uid, out value) ? $"range {value:0} m" : "no range (no sign number, global range 0)"); Print(context, string.Format("Chest {0:0} m: {1}, {2}food: {3}", Vector3.Distance(item2.GetPosition(), center.Value), text3, item2.GetBool(ZDOVars.s_inUse, false) ? "OPEN (skipped), " : "", DescribeFood(item2, foods))); } } private static string DescribeFood(ZDO chest, HashSet<int> foods) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown byte[] byteArray = chest.GetByteArray(ZDOVars.s_items, (byte[])null); if (byteArray == null || byteArray.Length == 0) { return "empty"; } try { ZPackage val = new ZPackage(byteArray); int num = val.ReadInt(); if (num < 108) { return $"old inventory format {num}, skipped"; } int num2 = val.ReadUShort(); Dictionary<int, int> dictionary = new Dictionary<int, int>(); for (int i = 0; i < num2; i++) { ItemData val2 = new ItemData(); int num3 = ItemData.Load(val, val2, (Item)num); if (foods.Contains(num3)) { dictionary[num3] = (dictionary.TryGetValue(num3, out var value) ? value : 0) + val2.m_stack; } } return (dictionary.Count == 0) ? $"none ({num2} other item stacks)" : string.Join(", ", dictionary.Select(delegate(KeyValuePair<int, int> x) { GameObject prefab = ZNetScene.instance.GetPrefab(x.Key); return (((prefab != null) ? ((Object)prefab).name : null) ?? x.Key.ToString(CultureInfo.InvariantCulture)) + " " + x.Value; })); } catch (Exception ex) { return "unreadable (" + ex.Message + ")"; } } private static Vector3? CallerPosition() { //IL_0078: Unknown result type (might be due to invalid IL or missing references) object obj = AccessTools.TypeByName("ServerDevcommands.RedirectOutput")?.GetField("Target", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); ZRpc rpc = (ZRpc)((obj is ZRpc) ? obj : null); if (rpc == null) { return null; } ZNetPeer? obj2 = ((IEnumerable<ZNetPeer>)ZNet.instance.GetPeers()).FirstOrDefault((Func<ZNetPeer, bool>)((ZNetPeer p) => p.m_rpc == rpc)); if (obj2 == null) { return null; } return obj2.GetRefPos(); } private static void Print(Terminal output, string text) { object obj = ((object)output) ?? ((object)Console.instance); if (obj != null) { ((Terminal)obj).AddString(text); } } private static string Format(Vector3 pos) { //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) return $"({pos.x:0}, {pos.y:0}, {pos.z:0})"; } } }