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 CargoToGo v1.0.0
CargoToGo.dll
Decompiled 4 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using AzuCraftyBoxes; using AzuCraftyBoxes.IContainers; using AzuCraftyBoxes.Util; using AzuCraftyBoxes.Util.Functions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("kydldev")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CargoToGo")] [assembly: AssemblyTitle("CargoToGo")] [assembly: AssemblyVersion("1.0.0.0")] namespace CargoToGo; internal static class AzuCompat { public const string Guid = "Azumatt.AzuCraftyBoxes"; private static bool? _installed; public static bool Installed { get { if (!_installed.HasValue) { _installed = Chainloader.PluginInfos.ContainsKey("Azumatt.AzuCraftyBoxes"); } return _installed.Value; } } public static bool Active { get { if (Installed) { return CargoToGoPlugin.UseAzuCraftyBoxes.Value; } return false; } } } internal static class AzuBridge { private sealed class AzuSource : Source { private readonly object _box; public override SourceKind Kind => SourceKind.Azu; public AzuSource(object container) { _box = container; } public override int Count(string sharedName, string itemPrefab) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown try { IContainer val = (IContainer)_box; string prefabName = val.GetPrefabName(); if (string.IsNullOrWhiteSpace(prefabName)) { return 0; } if (!API.CanItemBePulled(prefabName, itemPrefab)) { return 0; } return Mathf.Max(0, LeaveOne(val.ItemCount(sharedName))); } catch (Exception ex) { Log.Debug("Counting in an AzuCraftyBoxes container failed: " + ex.GetType().Name + ": " + ex.Message); return 0; } } public override int Take(string sharedName, string itemPrefab, int amount) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown try { IContainer val = (IContainer)_box; int num = Mathf.Min(amount, Count(sharedName, itemPrefab)); if (num <= 0) { return 0; } ClaimOwnership(val); return Mathf.Clamp(val.ProcessContainerInventory(sharedName, 0, num), 0, num); } catch (Exception e) { Log.Error("Taking items from an AzuCraftyBoxes container failed", e); return 0; } } } private static bool _resolved; private static bool _lookupFailureLogged; private static Func<bool> _shouldPrevent; private static Func<int, int> _leaveOne; public static List<Source> Collect(Player p, HashSet<Inventory> alreadyCovered) { List<Source> list = new List<Source>(); try { if ((Object)(object)p == (Object)null || Prevented(p)) { return list; } List<IContainer> nearbyContainers = API.GetNearbyContainers<Player>(p, AzuCraftyBoxesPlugin.mRange.Value); if (nearbyContainers == null) { return list; } foreach (IContainer item in nearbyContainers) { if (item != null) { Inventory inventory = item.GetInventory(); if (inventory == null || !alreadyCovered.Contains(inventory)) { list.Add(new AzuSource(item)); } } } } catch (Exception e) { if (!_lookupFailureLogged) { _lookupFailureLogged = true; Log.Error("AzuCraftyBoxes lookup failed, continuing without it (logged once)", e); } } return list; } private static void Resolve() { if (_resolved) { return; } _resolved = true; try { MethodInfo methodInfo = AccessTools.Method(typeof(MiscFunctions), "ShouldPrevent", (Type[])null, (Type[])null); if (methodInfo != null) { _shouldPrevent = (Func<bool>)Delegate.CreateDelegate(typeof(Func<bool>), methodInfo); } MethodInfo methodInfo2 = AccessTools.Method(typeof(Boxes), "CheckAndDecrement", new Type[1] { typeof(int) }, (Type[])null); if (methodInfo2 != null) { _leaveOne = (Func<int, int>)Delegate.CreateDelegate(typeof(Func<int, int>), methodInfo2); } } catch (Exception ex) { Log.Warn("Could not hook AzuCraftyBoxes internals, using fallbacks: " + ex.GetType().Name + ": " + ex.Message); } Log.Info("AzuCraftyBoxes integration ready (pull gate: " + ((_shouldPrevent != null) ? "Azu ShouldPrevent" : "IsPullingAllowed fallback") + ", leave-one rule: " + ((_leaveOne != null) ? "mirrored" : "not available") + ")."); } private static bool Prevented(Player p) { Resolve(); try { if (_shouldPrevent != null) { return _shouldPrevent(); } return !PlayerPullingExtensions.IsPullingAllowed(p); } catch (Exception ex) { Log.Debug("Azu pull gate check failed, treating as 'prevented': " + ex.GetType().Name + ": " + ex.Message); return true; } } private static int LeaveOne(int count) { Resolve(); if (_leaveOne == null) { return count; } return _leaveOne(count); } private static void ClaimOwnership(IContainer c) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) if (!(c is VanillaContainer)) { return; } try { Inventory inventory = c.GetInventory(); if (inventory == null) { return; } Collider[] array = Physics.OverlapSphere(c.GetPosition(), 3f); for (int i = 0; i < array.Length; i++) { Container componentInParent = ((Component)array[i]).GetComponentInParent<Container>(); if (!((Object)(object)componentInParent == (Object)null) && componentInParent.GetInventory() == inventory) { ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.ClaimOwnership(); } return; } } Log.Debug("Could not locate the chest at " + ((object)c.GetPosition()/*cast due to .constrained prefix*/).ToString() + " to claim ownership."); } catch (Exception ex) { Log.Debug("Claiming ownership of an AzuCraftyBoxes chest failed: " + ex.GetType().Name + ": " + ex.Message); } } } internal static class CargoFactory { public const string PrefabPrefix = "CC_Cargo_"; public const string NamePrefix = "Cargo: "; private static GameObject _holder; private static int RestrictedCount; private static GameObject Holder() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if ((Object)(object)_holder == (Object)null) { _holder = new GameObject("CargoToGoPrefabs"); _holder.SetActive(false); Object.DontDestroyOnLoad((Object)(object)_holder); } return _holder; } public static void Ensure(ObjectDB db) { if ((Object)(object)db == (Object)null || db.m_items == null || db.m_items.Count == 0) { return; } HashSet<string> hashSet = new HashSet<string>(); Dictionary<string, GameObject> dictionary = new Dictionary<string, GameObject>(); GameObject val = null; GameObject val2 = null; foreach (GameObject item in db.m_items) { if (!((Object)(object)item == (Object)null)) { hashSet.Add(((Object)item).name); if (((Object)item).name == "CargoCrate") { val = item; } else if (((Object)item).name == "Stone") { val2 = item; } else if (((Object)item).name.StartsWith("CC_Cargo_")) { dictionary[((Object)item).name] = item; } } } if ((Object)(object)val == (Object)null) { val = val2; } if ((Object)(object)val == (Object)null) { Log.Error("Neither 'CargoCrate' nor 'Stone' found in ObjectDB; no cargo items were registered."); return; } if (((Object)val).name != "CargoCrate") { Log.Warn("Prefab 'CargoCrate' not found, using '" + ((Object)val).name + "' as the cargo base."); } int num = 0; RestrictedCount = 0; GameObject[] array = db.m_items.ToArray(); foreach (GameObject val3 in array) { ItemDrop val4 = (((Object)(object)val3 != (Object)null) ? val3.GetComponent<ItemDrop>() : null); PieceTable val5 = (((Object)(object)val4 != (Object)null) ? val4.m_itemData.m_shared.m_buildPieces : null); if ((Object)(object)val5 == (Object)null || val5.m_pieces == null) { continue; } foreach (GameObject piece in val5.m_pieces) { Piece val6 = (((Object)(object)piece != (Object)null) ? piece.GetComponent<Piece>() : null); if ((Object)(object)val6 == (Object)null || (Object)(object)val6.m_icon == (Object)null || val6.m_resources == null || val6.m_resources.Length == 0) { continue; } string prefabName = Utils.GetPrefabName(piece); string text = "CC_Cargo_" + prefabName; if (!hashSet.Add(text)) { if (dictionary.TryGetValue(text, out var value)) { ItemDrop component = value.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { component.m_itemData.m_shared.m_teleportable = ContentsTeleportable(val6, out var _); } } continue; } try { if (Create(db, val, text, val6)) { num++; } } catch (Exception e) { Log.Error("Failed to create cargo '" + text + "'", e); } } } if (num > 0) { MethodInfo methodInfo = AccessTools.Method(typeof(ObjectDB), "UpdateRegisters", (Type[])null, (Type[])null); if (methodInfo == null) { Log.Error("ObjectDB.UpdateRegisters not found; new cargo items may not be resolvable."); } else { methodInfo.Invoke(db, null); } Log.Info("Registered " + num + " new cargo items in ObjectDB (cloned from '" + ((Object)val).name + "'); " + RestrictedCount + " of them contain materials that can't pass through portals."); } } private static bool Create(ObjectDB db, GameObject basePrefab, string cname, Piece piece) { //IL_0180: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(basePrefab, Holder().transform); ((Object)val).name = cname; ItemDrop component = val.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { Log.Warn("Base prefab has no ItemDrop; skipped '" + cname + "'"); Object.Destroy((Object)(object)val); return false; } SharedData shared = component.m_itemData.m_shared; StringBuilder stringBuilder = new StringBuilder("Sealed materials for building this piece. They can only be used for that.\nCtrl+Alt+Right-click destroys the cargo and returns the materials.\n"); float num = 0f; Requirement[] resources = piece.m_resources; foreach (Requirement val2 in resources) { if (!((Object)(object)val2.m_resItem == (Object)null) && val2.m_amount > 0) { num += (float)val2.m_amount * val2.m_resItem.m_itemData.m_shared.m_weight; stringBuilder.Append("\n").Append(val2.m_amount).Append("x ") .Append(val2.m_resItem.m_itemData.m_shared.m_name); } } string blocker; bool flag = ContentsTeleportable(piece, out blocker); if (!flag) { stringBuilder.Append("\n\nContains materials that can't pass through portals (unless the world's portal rules allow everything)."); RestrictedCount++; Log.Debug("Cargo '" + cname + "' is portal-restricted: contains '" + blocker + "'."); } shared.m_name = "Cargo: " + piece.m_name; shared.m_description = stringBuilder.ToString(); shared.m_itemType = (ItemType)1; shared.m_icons = (Sprite[])(object)new Sprite[1] { piece.m_icon }; shared.m_variants = 0; shared.m_maxStackSize = 1; shared.m_autoStack = false; shared.m_maxQuality = 1; shared.m_weight = num * CargoToGoPlugin.WeightMultiplier.Value; shared.m_teleportable = flag; shared.m_questItem = false; shared.m_dlc = ""; shared.m_value = 0; shared.m_equipStatusEffect = null; shared.m_movementModifier = 0f; shared.m_useDurability = false; shared.m_canBeReparied = false; component.m_itemData.m_dropPrefab = val; db.m_items.Add(val); return true; } public static bool ContentsTeleportable(Piece piece, out string blocker) { blocker = null; if ((Object)(object)piece == (Object)null || piece.m_resources == null) { blocker = "(unknown contents)"; return false; } Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if (!((Object)(object)val.m_resItem == (Object)null) && val.m_amount > 0) { SharedData shared = val.m_resItem.m_itemData.m_shared; if (!shared.m_teleportable) { blocker = shared.m_name; return false; } } } return true; } public static void RefreshTeleportable(ItemData cargo) { string blocker; bool flag = ContentsTeleportable(PrefabPieceOf(cargo), out blocker); if (cargo.m_shared.m_teleportable != flag) { Log.Debug("Cargo '" + ((Object)cargo.m_dropPrefab).name + "' teleportable " + cargo.m_shared.m_teleportable + " -> " + flag + (flag ? "" : (" (contains '" + blocker + "')"))); } cargo.m_shared.m_teleportable = flag; } public static bool IsCargo(ItemData item) { if (item != null && (Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name.StartsWith("CC_Cargo_"); } return false; } public static string PieceNameOf(ItemData item) { return ((Object)item.m_dropPrefab).name.Substring("CC_Cargo_".Length); } public static GameObject GetCargoPrefab(Piece piece) { if ((Object)(object)piece == (Object)null || (Object)(object)ObjectDB.instance == (Object)null) { return null; } return ObjectDB.instance.GetItemPrefab("CC_Cargo_" + Utils.GetPrefabName(((Component)piece).gameObject)); } public static ItemData FindCargoFor(Inventory inv, Piece piece) { if (inv == null || (Object)(object)piece == (Object)null) { return null; } string text = "CC_Cargo_" + Utils.GetPrefabName(((Component)piece).gameObject); foreach (ItemData allItem in inv.GetAllItems()) { if ((Object)(object)allItem.m_dropPrefab != (Object)null && ((Object)allItem.m_dropPrefab).name == text) { return allItem; } } return null; } public static Piece PrefabPieceOf(ItemData cargo) { GameObject val = (((Object)(object)ZNetScene.instance != (Object)null) ? ZNetScene.instance.GetPrefab(PieceNameOf(cargo)) : null); if (!((Object)(object)val != (Object)null)) { return null; } return val.GetComponent<Piece>(); } } internal enum SourceKind { Inventory, Chest, Azu } internal abstract class Source { public abstract SourceKind Kind { get; } public abstract int Count(string sharedName, string itemPrefab); public abstract int Take(string sharedName, string itemPrefab, int amount); } internal sealed class InventorySource : Source { private readonly Inventory _inv; private readonly Container _cont; public override SourceKind Kind { get { if (!((Object)(object)_cont != (Object)null)) { return SourceKind.Inventory; } return SourceKind.Chest; } } public InventorySource(Inventory inv, Container cont) { _inv = inv; _cont = cont; } public override int Count(string sharedName, string itemPrefab) { return _inv.CountItems(sharedName, -1, true); } public override int Take(string sharedName, string itemPrefab, int amount) { int num = Mathf.Min(amount, _inv.CountItems(sharedName, -1, true)); if (num <= 0) { return 0; } if ((Object)(object)_cont != (Object)null) { ((Component)_cont).GetComponent<ZNetView>().ClaimOwnership(); } _inv.RemoveItem(sharedName, num, -1, true); return num; } } internal sealed class CargoPieceList : IPieceList { public string DisplayName => "Cargos"; public bool ShowTags => false; public bool CanCustomizeTags => false; public int TagCount => 0; public int TagSeparatorIndex => -1; public string GetTagDisplayName(int index) { return ""; } public int GetTagIdByIndex(int index) { return -1; } public void UpdateAvailableTags(PieceTable pieceTable) { } public void GetAvailablePiecesWithTag(int tagId, PieceTable pieceTable, IList<Piece> resultOut) { try { Player localPlayer = Player.m_localPlayer; List<string> list = CargoTab.CargoPieceNames(((Object)(object)localPlayer != (Object)null) ? ((Humanoid)localPlayer).GetInventory() : null); CargoTab.LastSignature = CargoTab.Signature(list); if (list.Count == 0 || (Object)(object)pieceTable == (Object)null || pieceTable.m_pieces == null || pieceTable.m_availablePieces == null) { return; } foreach (GameObject piece in pieceTable.m_pieces) { if (!((Object)(object)piece == (Object)null)) { Piece component = piece.GetComponent<Piece>(); if (!((Object)(object)component == (Object)null) && pieceTable.m_availablePieces.Contains(component) && list.Contains(Utils.GetPrefabName(piece))) { resultOut.Add(component); } } } Log.Debug("Cargos tab: " + resultOut.Count + " piece(s) listed for " + list.Count + " distinct cargo type(s) in the inventory."); } catch (Exception e) { Log.Error("CargoPieceList.GetAvailablePiecesWithTag failed", e); } } } internal static class CargoTab { public const string TabLabel = "Cargos"; public static string LastSignature = ""; private static readonly FieldInfo F_Lists = AccessTools.Field(typeof(BuildUi), "m_pieceLists"); private static readonly FieldInfo F_TabButtons = AccessTools.Field(typeof(BuildUi), "m_tabButtons"); private static readonly FieldInfo F_TabContainer = AccessTools.Field(typeof(BuildUi), "m_tabContainer"); private static readonly FieldInfo F_TabHandler = AccessTools.Field(typeof(BuildUi), "m_tabHandler"); private static readonly FieldInfo F_CurrentList = AccessTools.Field(typeof(BuildUi), "m_currentPieceList"); private static readonly MethodInfo M_SelectPieceList = AccessTools.Method(typeof(BuildUi), "SelectPieceList", (Type[])null, (Type[])null); private static readonly MethodInfo M_UpdatePieceButtons = AccessTools.Method(typeof(BuildUi), "UpdatePieceButtons", (Type[])null, (Type[])null); private static int _index = -1; private static BuildUi _installedOn; private static float _nextPoll; public static List<string> CargoPieceNames(Inventory inv) { List<string> list = new List<string>(); if (inv == null) { return list; } foreach (ItemData allItem in inv.GetAllItems()) { if (CargoFactory.IsCargo(allItem)) { string item = CargoFactory.PieceNameOf(allItem); if (!list.Contains(item)) { list.Add(item); } } } return list; } public static string Signature(List<string> names) { List<string> list = new List<string>(names); list.Sort(StringComparer.Ordinal); return string.Join("|", list.ToArray()); } public static void Install(BuildUi ui) { //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Expected O, but got Unknown //IL_0357: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Expected O, but got Unknown _index = -1; _installedOn = null; if (!CargoToGoPlugin.ShowCargoTab.Value) { Log.Info("Cargos tab disabled in the config."); return; } if (F_Lists == null || F_TabButtons == null || F_TabContainer == null || F_TabHandler == null || M_SelectPieceList == null || M_UpdatePieceButtons == null) { Log.Error("Cargos tab: BuildUi has changed (a field or method was not found); the tab was not added. Game version incompatible?"); return; } List<IPieceList> list = F_Lists.GetValue(ui) as List<IPieceList>; List<Button> list2 = F_TabButtons.GetValue(ui) as List<Button>; object? value = F_TabContainer.GetValue(ui); RectTransform val = (RectTransform)((value is RectTransform) ? value : null); object? value2 = F_TabHandler.GetValue(ui); TabHandler val2 = (TabHandler)((value2 is TabHandler) ? value2 : null); if (list == null || list2 == null || (Object)(object)val == (Object)null || list2.Count == 0) { Log.Error("Cargos tab: build menu structure not as expected (lists=" + (list != null) + ", buttons=" + (list2?.Count ?? (-1)) + ", container=" + ((Object)(object)val != (Object)null) + "); the tab was not added."); return; } foreach (IPieceList item in list) { if (item is CargoPieceList) { Log.Debug("Cargos tab already installed."); return; } } if (list2.Count != list.Count) { Log.Warn("Cargos tab: " + list2.Count + " tab buttons but " + list.Count + " piece lists; the tab was not added to keep indices aligned."); return; } GameObject val3 = Object.Instantiate<GameObject>(((Component)list2[list2.Count - 1]).gameObject, (Transform)(object)val); ((Object)val3).name = "CargoToGoTab"; Button component = val3.GetComponent<Button>(); if ((Object)(object)component == (Object)null) { Log.Error("Cargos tab: cloned tab has no Button; aborting."); Object.Destroy((Object)(object)val3); return; } Localize[] componentsInChildren = val3.GetComponentsInChildren<Localize>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.DestroyImmediate((Object)(object)componentsInChildren[i]); } TMP_Text[] componentsInChildren2 = val3.GetComponentsInChildren<TMP_Text>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { componentsInChildren2[i].text = "Cargos"; } Text[] componentsInChildren3 = val3.GetComponentsInChildren<Text>(true); for (int i = 0; i < componentsInChildren3.Length; i++) { componentsInChildren3[i].text = "Cargos"; } Transform val4 = val3.transform.Find("Selected"); if ((Object)(object)val4 != (Object)null) { ((Component)val4).gameObject.SetActive(false); } ((Selectable)component).interactable = true; ((UnityEventBase)component.onClick).RemoveAllListeners(); int count = list.Count; list.Add((IPieceList)(object)new CargoPieceList()); list2.Add(component); int idx = count; ((UnityEvent)component.onClick).AddListener((UnityAction)delegate { M_SelectPieceList.Invoke(ui, new object[2] { idx, false }); }); if ((Object)(object)val2 != (Object)null && val2.m_tabs != null) { Tab val5 = new Tab(); val5.m_button = component; val5.m_default = false; val5.m_page = null; val5.m_onClick = null; val2.m_tabs.Add(val5); } else { Log.Warn("Cargos tab: no TabHandler found; the tab works with the mouse but Q/E cycling and highlight may not."); } _index = count; _installedOn = ui; ReLayout(val); Log.Info("Cargos tab added to the build menu (tab index " + count + ", " + ((Transform)val).childCount + " tabs)."); } private unsafe static void ReLayout(RectTransform container) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Invalid comparison between Unknown and I4 //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0316: Unknown result type (might be due to invalid IL or missing references) //IL_031b: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0337: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) //IL_0379: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) try { List<RectTransform> list = new List<RectTransform>(); foreach (Transform item in (Transform)container) { object obj = (object)item; RectTransform val = (RectTransform)((obj is RectTransform) ? obj : null); if ((Object)(object)val != (Object)null && ((Component)val).gameObject.activeSelf) { list.Add(val); } } int count = list.Count; if (count < 2) { return; } GridLayoutGroup component = ((Component)container).GetComponent<GridLayoutGroup>(); HorizontalLayoutGroup component2 = ((Component)container).GetComponent<HorizontalLayoutGroup>(); LayoutGroup component3 = ((Component)container).GetComponent<LayoutGroup>(); string[] obj2 = new string[10] { "Tab container '", ((Object)container).name, "': rect=", null, null, null, null, null, null, null }; Rect rect = container.rect; obj2[3] = ((object)(*(Rect*)(&rect))/*cast due to .constrained prefix*/).ToString(); obj2[4] = " HLG="; obj2[5] = ((Object)(object)component2 != (Object)null).ToString(); obj2[6] = " Grid="; obj2[7] = ((Object)(object)component != (Object)null).ToString(); obj2[8] = " otherLayout="; obj2[9] = ((Object)(object)component3 != (Object)null && (Object)(object)component2 == (Object)null && (Object)(object)component == (Object)null).ToString(); Log.Debug(string.Concat(obj2)); if ((Object)(object)component != (Object)null) { rect = container.rect; float num = ((Rect)(ref rect)).width - (float)((LayoutGroup)component).padding.left - (float)((LayoutGroup)component).padding.right - component.spacing.x * (float)(count - 1); if (num > 0f) { component.cellSize = new Vector2(num / (float)count, component.cellSize.y); } if ((int)component.constraint == 1) { component.constraintCount = count; } } else if ((Object)(object)component2 != (Object)null) { if (!((HorizontalOrVerticalLayoutGroup)component2).childControlWidth) { rect = container.rect; float num2 = ((Rect)(ref rect)).width - (float)((LayoutGroup)component2).padding.left - (float)((LayoutGroup)component2).padding.right - ((HorizontalOrVerticalLayoutGroup)component2).spacing * (float)(count - 1); if (num2 > 0f) { foreach (RectTransform item2 in list) { item2.SetSizeWithCurrentAnchors((Axis)0, num2 / (float)count); } } } } else if ((Object)(object)component3 == (Object)null) { list.Sort((RectTransform a, RectTransform b) => LocalLeft(container, a).CompareTo(LocalLeft(container, b))); RectTransform val2 = list.Find((RectTransform r) => ((Object)((Component)r).gameObject).name == "CargoToGoTab"); if ((Object)(object)val2 != (Object)null) { list.Remove(val2); list.Add(val2); } RectTransform val3 = list[0]; RectTransform val4 = list[count - 2]; float num3 = LocalLeft(container, val3); float num4 = LocalLeft(container, val4); rect = val4.rect; float num5 = num4 + ((Rect)(ref rect)).width * ((Transform)val4).lossyScale.x / ((Transform)container).lossyScale.x; float num6; if (count <= 2) { num6 = 0f; } else { float num7 = LocalLeft(container, list[1]); rect = val3.rect; num6 = Mathf.Max(0f, num7 - (num3 + ((Rect)(ref rect)).width * ((Transform)val3).lossyScale.x / ((Transform)container).lossyScale.x)); } float num8 = num6; float num9 = (num5 - num3 - num8 * (float)(count - 1)) / (float)count; if (num9 <= 1f) { Log.Warn("Cargos tab: computed tab width " + num9 + " is too small; layout left unchanged."); return; } for (int num10 = 0; num10 < count; num10++) { list[num10].SetInsetAndSizeFromParentEdge((Edge)0, num3 + (float)num10 * (num9 + num8), num9); } } LayoutRebuilder.ForceRebuildLayoutImmediate(container); } catch (Exception ex) { Log.Warn("Cargos tab: re-layout failed (the tab still exists): " + ex.GetType().Name + ": " + ex.Message); } } private static float LocalLeft(RectTransform container, RectTransform rt) { //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) //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) Vector3[] array = (Vector3[])(object)new Vector3[4]; rt.GetWorldCorners(array); float x = ((Transform)container).InverseTransformPoint(array[0]).x; Rect rect = container.rect; return x - ((Rect)(ref rect)).xMin; } public static void Tick(BuildUi ui) { if (_index < 0 || (Object)(object)ui == (Object)null || (Object)(object)_installedOn != (Object)(object)ui || Time.unscaledTime < _nextPoll) { return; } _nextPoll = Time.unscaledTime + 0.2f; try { if (F_CurrentList == null || Convert.ToInt32(F_CurrentList.GetValue(ui)) != _index) { return; } Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null)) { string text = Signature(CargoPieceNames(((Humanoid)localPlayer).GetInventory())); if (!(text == LastSignature)) { Log.Debug("Cargos tab: inventory cargos changed ('" + LastSignature + "' -> '" + text + "'), rebuilding the grid."); LastSignature = text; M_UpdatePieceButtons.Invoke(ui, null); } } } catch (Exception e) { Log.Error("Cargos tab refresh failed", e); } } } [HarmonyPatch(typeof(BuildUi), "Awake")] internal static class BuildUi_Awake { private static void Postfix(BuildUi __instance) { try { CargoTab.Install(__instance); } catch (Exception e) { Log.Error("Adding the Cargos tab failed; the build menu keeps its 4 vanilla tabs", e); } } } [HarmonyPatch(typeof(BuildUi), "Update")] internal static class BuildUi_Update { private static void Postfix(BuildUi __instance) { CargoTab.Tick(__instance); } } internal static class KeyHintUi { private static KeyHints _builtFor; private static GameObject _row; private static GameObject _packHint; private static GameObject _repackHint; private static TMP_Text _packKey; private static TMP_Text _repackKey; private static bool _disabled; private static int _lastRefresh; public static void Tick(KeyHints kh) { if (_disabled || (Object)(object)kh == (Object)null) { return; } try { GameObject buildHints = kh.m_buildHints; if ((Object)(object)buildHints == (Object)null) { return; } bool flag = CargoToGoPlugin.ShowKeyHints.Value && buildHints.activeInHierarchy && !ZInput.IsGamepadActive(); if ((Object)(object)_row == (Object)null || (Object)(object)_builtFor != (Object)(object)kh) { if (!flag) { return; } if ((Object)(object)_row != (Object)null) { Object.Destroy((Object)(object)_row); } if (!Build(kh)) { _disabled = true; return; } } if (_row.activeSelf != flag) { _row.SetActive(flag); } if (flag) { _packHint.SetActive(CargoToGoPlugin.PackInWorld.Value); Position(buildHints); if (Time.frameCount - _lastRefresh > 60) { _lastRefresh = Time.frameCount; RefreshKeys(); } } } catch (Exception e) { _disabled = true; Log.Error("Key hint bar extension failed and was disabled for this session", e); } } private static bool Build(KeyHints kh) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Expected O, but got Unknown //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0282: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) GameObject buildHints = kh.m_buildHints; TMP_Text val = null; TMP_Text val2 = null; Transform val3 = FindHintRoot(buildHints.transform); if ((Object)(object)val3 != (Object)null) { List<TMP_Text> list = new List<TMP_Text>(((Component)val3).GetComponentsInChildren<TMP_Text>(false)); if (list.Count != 2) { list = new List<TMP_Text>(((Component)val3).GetComponentsInChildren<TMP_Text>(true)); } if (list.Count >= 2) { val = list[0]; val2 = list[1]; if (list[0].transform.position.x > list[1].transform.position.x + 1f) { val = list[1]; val2 = list[0]; } } } if ((Object)(object)val == (Object)null) { TMP_Text[] componentsInChildren = buildHints.GetComponentsInChildren<TMP_Text>(true); if (componentsInChildren.Length == 0) { Log.Warn("Key hint bar: no TextMeshPro text found under the build hints; hints not added."); return false; } val = (val2 = componentsInChildren[0]); } float num = EffectiveSize(val); float num2 = EffectiveSize(val2); if (num < num2 * 0.6f) { num = num2; } if (num2 < num * 0.6f) { num2 = num; } Log.Debug("Key hint font sizes: label " + num + " (property " + val.fontSize + ", autosize " + val.enableAutoSizing + "), key " + num2 + " (property " + val2.fontSize + ", autosize " + val2.enableAutoSizing + ")"); Image val4 = null; Transform val5 = val2.transform; while ((Object)(object)val5 != (Object)null && (Object)(object)val5 != (Object)(object)buildHints.transform) { Image component = ((Component)val5).GetComponent<Image>(); if ((Object)(object)component != (Object)null) { val4 = component; break; } val5 = val5.parent; } if (Log.Verbose) { DumpHierarchy(buildHints.transform, val3, val, val2, val4); } Canvas componentInParent = buildHints.GetComponentInParent<Canvas>(); Transform val6 = (((Object)(object)componentInParent != (Object)null) ? ((Component)componentInParent).transform : buildHints.transform.parent); _row = new GameObject("CargoToGoHints", new Type[1] { typeof(RectTransform) }); _row.layer = buildHints.layer; RectTransform val7 = (RectTransform)_row.transform; ((Transform)val7).SetParent(val6, false); Vector2 val8 = default(Vector2); ((Vector2)(ref val8))..ctor(0.5f, 0.5f); val7.anchorMax = val8; val7.anchorMin = val8; val7.pivot = new Vector2(0.5f, 0f); HorizontalLayoutGroup obj = _row.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 45f; ((LayoutGroup)obj).childAlignment = (TextAnchor)4; bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth; childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false); ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = childControlWidth; ContentSizeFitter obj2 = _row.AddComponent<ContentSizeFitter>(); obj2.horizontalFit = (FitMode)2; obj2.verticalFit = (FitMode)2; _packHint = AddHint("Pack", val, val2, num, num2, val4, "Pack cargo", PackKeys(), out _packKey); _repackHint = AddHint("Repack", val, val2, num, num2, val4, "Repack", RepackKeys(), out _repackKey); _builtFor = kh; Log.Info("Key hint bar: added Pack/Repack hints (font " + num + "/" + num2 + ")" + (((Object)(object)val3 != (Object)null) ? (" (style copied from '" + ((Object)val3).name + "').") : " (no template hint found, used first text style).")); return true; } private static Transform FindHintRoot(Transform root) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown List<Transform> list = new List<Transform>(); foreach (Transform item3 in root) { Transform item = item3; list.Add(item); } for (int i = 0; i < list.Count; i++) { Transform val = list[i]; if (!((Component)val).gameObject.activeInHierarchy) { continue; } if (((Component)val).GetComponentsInChildren<TMP_Text>(false).Length == 2) { return val; } foreach (Transform item4 in val) { Transform item2 = item4; list.Add(item2); } } return null; } private static GameObject AddHint(string name, TMP_Text labelStyle, TMP_Text keyStyle, float labelSize, float keySize, Image chipImg, string labelText, string keyText, out TMP_Text keyOut) { //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) GameObject val = NewObj("Hint_" + name, _row.transform); HorizontalLayoutGroup obj = val.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj).spacing = 10f; ((LayoutGroup)obj).childAlignment = (TextAnchor)4; bool childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = childControlWidth; childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false); ((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = childControlWidth; NewText("Label", val.transform, labelStyle, labelSize).text = labelText; GameObject val2 = NewObj("Chip", val.transform); if ((Object)(object)chipImg != (Object)null) { Image obj2 = val2.AddComponent<Image>(); obj2.sprite = chipImg.sprite; obj2.type = chipImg.type; ((Graphic)obj2).color = ((Graphic)chipImg).color; ((Graphic)obj2).raycastTarget = false; } HorizontalLayoutGroup obj3 = val2.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 0f; ((LayoutGroup)obj3).childAlignment = (TextAnchor)4; childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj3).childControlHeight = true); ((HorizontalOrVerticalLayoutGroup)obj3).childControlWidth = childControlWidth; childControlWidth = (((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false); ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = childControlWidth; Spacer(val2.transform, 12f); TMP_Text val3 = NewText("Key", val2.transform, keyStyle, keySize); val3.text = keyText; ((Component)val3).gameObject.AddComponent<LayoutElement>().minHeight = val3.preferredHeight + 12f; Spacer(val2.transform, 12f); keyOut = val3; return val; } private static float EffectiveSize(TMP_Text t) { try { t.ForceMeshUpdate(false, false); TMP_TextInfo textInfo = t.textInfo; if (textInfo != null && textInfo.characterCount > 0 && textInfo.characterInfo != null && textInfo.characterInfo.Length != 0 && textInfo.characterInfo[0].pointSize > 1f) { return textInfo.characterInfo[0].pointSize; } } catch (Exception ex) { Log.Debug("EffectiveSize failed: " + ex.Message); } if (!t.enableAutoSizing) { return t.fontSize; } return t.fontSizeMax; } private static GameObject NewObj(string name, Transform parent) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown GameObject val = new GameObject(name, new Type[1] { typeof(RectTransform) }) { layer = _row.layer }; val.transform.SetParent(parent, false); return val; } private static void Spacer(Transform parent, float width) { LayoutElement obj = NewObj("Spacer", parent).AddComponent<LayoutElement>(); float minWidth = (obj.preferredWidth = width); obj.minWidth = minWidth; } private static TMP_Text NewText(string name, Transform parent, TMP_Text style, float size) { //IL_0034: 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) TextMeshProUGUI obj = NewObj(name, parent).AddComponent<TextMeshProUGUI>(); ((TMP_Text)obj).font = style.font; ((TMP_Text)obj).fontSharedMaterial = style.fontSharedMaterial; ((TMP_Text)obj).enableAutoSizing = false; ((TMP_Text)obj).fontSize = size; ((TMP_Text)obj).fontStyle = style.fontStyle; ((Graphic)obj).color = ((Graphic)style).color; ((TMP_Text)obj).alignment = (TextAlignmentOptions)514; ((TMP_Text)obj).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)obj).overflowMode = (TextOverflowModes)0; ((TMP_Text)obj).richText = false; ((Graphic)obj).raycastTarget = false; return (TMP_Text)(object)obj; } private static void Position(GameObject buildHints) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) TMP_Text[] componentsInChildren = buildHints.GetComponentsInChildren<TMP_Text>(false); if (componentsInChildren.Length == 0) { return; } float num = float.MaxValue; float num2 = float.MinValue; float num3 = float.MaxValue; float num4 = float.MinValue; Vector3[] array = (Vector3[])(object)new Vector3[4]; TMP_Text[] array2 = componentsInChildren; for (int i = 0; i < array2.Length; i++) { ((RectTransform)array2[i].transform).GetWorldCorners(array); for (int j = 0; j < 4; j++) { num = Mathf.Min(num, array[j].x); num2 = Mathf.Max(num2, array[j].x); num3 = Mathf.Min(num3, array[j].y); num4 = Mathf.Max(num4, array[j].y); } } float num5 = Mathf.Max(10f, (num4 - num3) * 0.9f); _row.transform.position = new Vector3((num + num2) * 0.5f, num4 + num5, buildHints.transform.position.z); } private static string BoundKey(string action, string fallback) { try { ZInput instance = ZInput.instance; if (instance != null) { string boundKeyString = instance.GetBoundKeyString(action, true); if (!string.IsNullOrEmpty(boundKeyString)) { boundKeyString = Localization.instance.Localize(boundKeyString); if (!string.IsNullOrEmpty(boundKeyString) && !boundKeyString.StartsWith("$") && !boundKeyString.StartsWith("[")) { return boundKeyString; } } } } catch (Exception ex) { Log.Debug("BoundKey(" + action + ") failed: " + ex.Message); } return fallback; } private static string PackKeys() { return "Ctrl + Alt + " + BoundKey("Attack", "Mouse-1"); } private static string RepackKeys() { return "Alt + " + BoundKey("Remove", "Mouse-3"); } private static void RefreshKeys() { string text = PackKeys(); if (_packKey.text != text) { _packKey.text = text; } string text2 = RepackKeys(); if (_repackKey.text != text2) { _repackKey.text = text2; } } private static void DumpHierarchy(Transform root, Transform tpl, TMP_Text label, TMP_Text key, Image chip) { int lines = 0; Log.Debug("KeyHints dump: template=" + (((Object)(object)tpl != (Object)null) ? ((Object)tpl).name : "none") + " label=" + ((Object)label).name + " key=" + ((Object)key).name + " chipImage=" + (((Object)(object)chip != (Object)null) ? ((Object)chip).name : "none")); Walk(root, 0, ref lines); } private static void Walk(Transform t, int depth, ref int lines) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown if (lines++ > 150) { return; } TMP_Text component = ((Component)t).GetComponent<TMP_Text>(); List<string> list = new List<string>(); Component[] components = ((Component)t).GetComponents<Component>(); foreach (Component val in components) { if ((Object)(object)val != (Object)null) { list.Add(((object)val).GetType().Name); } } Log.Debug("KeyHints dump: " + new string('.', depth) + ((Object)t).name + " active=" + ((Component)t).gameObject.activeSelf + " [" + string.Join(",", list.ToArray()) + "]" + (((Object)(object)component != (Object)null) ? (" text='" + component.text + "'") : "")); foreach (Transform item in t) { Walk(item, depth + 1, ref lines); } } } internal static class Log { private static ManualLogSource _src; public static bool Verbose; public static void Init() { _src = Logger.CreateLogSource("CargoToGo"); } private static string Fmt(string level, string text) { return DateTime.UtcNow.ToString("yyyy-MM-dd'T'HH:mm:ss.fff'Z'") + "-CargoToGo-" + level + "-" + text; } public static void Info(string text) { if (_src != null) { _src.LogInfo((object)Fmt("INFO", text)); } } public static void Warn(string text) { if (_src != null) { _src.LogWarning((object)Fmt("WARN", text)); } } public static void Error(string text) { if (_src != null) { _src.LogError((object)Fmt("ERROR", text)); } } public static void Error(string text, Exception e) { Error(text + " | " + e.GetType().Name + ": " + e.Message + " | " + (e.StackTrace ?? "").Replace("\n", " <- ").Replace("\r", "")); } public static void Debug(string text) { if (Verbose && _src != null) { _src.LogInfo((object)Fmt("DEBUG", text)); } } } internal static class Packer { public const string BuiltFromCargoKey = "CC_FromCargo"; private static readonly MethodInfo CheckAccess = AccessTools.Method(typeof(Container), "CheckAccess", (Type[])null, (Type[])null); private static int _cacheFrame = -1; private static List<Container> _cache = new List<Container>(); private static float _lastPack; private static int _sourcesFrame = -1; private static List<Source> _sourcesCache = new List<Source>(); public static bool Alt { get { if (!ZInput.GetKey((KeyCode)308, false)) { return ZInput.GetKey((KeyCode)307, false); } return true; } } public static bool Ctrl { get { if (!ZInput.GetKey((KeyCode)306, false)) { return ZInput.GetKey((KeyCode)305, false); } return true; } } public static bool PackChord { get { if (Alt) { return Ctrl; } return false; } } public static void Say(Player p, string text) { ((Character)p).Message((MessageType)2, text, 0, (Sprite)null, false); } public static string PName(Player p) { if (!((Object)(object)p != (Object)null)) { return "?"; } return p.GetPlayerName(); } public static string PrefabOf(ItemDrop r) { return Utils.GetPrefabName(((Component)r).gameObject); } public static List<Container> NearbyContainers(Player p) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (_cacheFrame == Time.frameCount) { return _cache; } _cacheFrame = Time.frameCount; _cache = new List<Container>(); if (!CargoToGoPlugin.PullFromContainers.Value) { return _cache; } float value = CargoToGoPlugin.ContainerRange.Value; if (value <= 0f) { return _cache; } HashSet<Container> hashSet = new HashSet<Container>(); Collider[] array = Physics.OverlapSphere(((Component)p).transform.position, value); for (int i = 0; i < array.Length; i++) { Container componentInParent = ((Component)array[i]).GetComponentInParent<Container>(); if (!((Object)(object)componentInParent == (Object)null) && hashSet.Add(componentInParent) && !((Object)(object)((Component)componentInParent).GetComponent<TombStone>() != (Object)null)) { ZNetView component = ((Component)componentInParent).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && componentInParent.GetInventory() != null && !componentInParent.IsInUse() && (!(CheckAccess != null) || (bool)CheckAccess.Invoke(componentInParent, new object[1] { p.GetPlayerID() }))) { _cache.Add(componentInParent); } } } return _cache; } private static List<Source> Sources(Player p) { if (_sourcesFrame == Time.frameCount) { return _sourcesCache; } _sourcesFrame = Time.frameCount; List<Source> list = new List<Source>(); HashSet<Inventory> hashSet = new HashSet<Inventory>(); foreach (Container item2 in NearbyContainers(p)) { Inventory inventory = item2.GetInventory(); hashSet.Add(inventory); list.Add(new InventorySource(inventory, item2)); } if (CargoToGoPlugin.PullFromContainers.Value && AzuCompat.Active) { list.AddRange(AzuBridge.Collect(p, hashSet)); } List<Source> list2 = new List<Source>(); InventorySource item = new InventorySource(((Humanoid)p).GetInventory(), null); if (!CargoToGoPlugin.ContainersFirst.Value) { list2.Add(item); } list2.AddRange(list); if (CargoToGoPlugin.ContainersFirst.Value) { list2.Add(item); } _sourcesCache = list2; return list2; } public static bool FreeKeyActive(Piece piece) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) ZoneSystem instance = ZoneSystem.instance; if ((Object)(object)instance != (Object)null && (Object)(object)piece != (Object)null) { return instance.GetGlobalKey(piece.FreeBuildKey()); } return false; } public static bool BuildIsFree(Player p, Piece piece) { if (!((Object)(object)p != (Object)null) || !p.NoCostCheat()) { return FreeKeyActive(piece); } return true; } public static bool CanPack(Player p, Piece piece) { if ((Object)(object)piece != (Object)null && piece.m_resources != null && piece.m_resources.Length != 0 && BuildIsFree(p, piece)) { return true; } string missing; return CheckResources(p, piece, Sources(p), out missing); } private static bool CheckResources(Player p, Piece piece, List<Source> sources, out string missing) { missing = null; if ((Object)(object)piece == (Object)null || piece.m_resources == null || piece.m_resources.Length == 0) { missing = "nothing to pack"; return false; } Requirement[] resources = piece.m_resources; foreach (Requirement val in resources) { if ((Object)(object)val.m_resItem == (Object)null || val.m_amount <= 0) { continue; } string name = val.m_resItem.m_itemData.m_shared.m_name; string itemPrefab = PrefabOf(val.m_resItem); int num = 0; foreach (Source source in sources) { num += source.Count(name, itemPrefab); if (num >= val.m_amount) { break; } } if (num < val.m_amount) { missing = name; return false; } } return true; } public static bool TryPack(Player p, Piece piece) { try { if ((Object)(object)p == (Object)null || (Object)(object)piece == (Object)null) { return false; } if (Time.time - _lastPack < 0.35f) { return false; } _lastPack = Time.time; string prefabName = Utils.GetPrefabName(((Component)piece).gameObject); GameObject cargoPrefab = CargoFactory.GetCargoPrefab(piece); if ((Object)(object)cargoPrefab == (Object)null) { Say(p, "This piece can't be packed into a cargo."); Log.Warn("Pack refused for '" + prefabName + "' by " + PName(p) + ": no cargo prefab registered for this piece."); return false; } Inventory inventory = ((Humanoid)p).GetInventory(); if (!inventory.HaveEmptySlot()) { Say(p, "No free inventory slot for a cargo."); Log.Info("Pack refused for '" + prefabName + "' by " + PName(p) + ": inventory has no free slot."); return false; } List<Source> list = Sources(p); bool flag = FreeKeyActive(piece); bool flag2 = flag || p.NoCostCheat(); string missing = null; if (!flag2 && !CheckResources(p, piece, list, out missing)) { Say(p, "Missing materials: " + Localization.instance.Localize(missing)); Log.Info("Pack refused for '" + prefabName + "' by " + PName(p) + ": missing material " + missing + "."); return false; } ItemData val = cargoPrefab.GetComponent<ItemDrop>().m_itemData.Clone(); val.m_dropPrefab = cargoPrefab; val.m_stack = 1; val.m_quality = 1; if (!inventory.AddItem(val)) { Say(p, "No free inventory slot for a cargo."); Log.Warn("Pack failed for '" + prefabName + "' by " + PName(p) + ": AddItem(cargo) returned false although a free slot was reported."); return false; } StringBuilder stringBuilder = new StringBuilder(); Requirement[] resources = piece.m_resources; foreach (Requirement val2 in resources) { if ((Object)(object)val2.m_resItem == (Object)null || val2.m_amount <= 0) { continue; } string name = val2.m_resItem.m_itemData.m_shared.m_name; if (flag) { stringBuilder.Append(PrefabOf(val2.m_resItem)).Append(" x").Append(val2.m_amount) .Append(" (free-build world key, nothing consumed); "); continue; } int num = val2.m_amount; string itemPrefab = PrefabOf(val2.m_resItem); int num2 = 0; int num3 = 0; int num4 = 0; foreach (Source item in list) { if (num <= 0) { break; } int num5 = item.Take(name, itemPrefab, num); if (num5 > 0) { if (item.Kind == SourceKind.Chest) { num2 += num5; } else if (item.Kind == SourceKind.Azu) { num3 += num5; } else { num4 += num5; } num -= num5; } } if (num > 0 && !flag2) { Log.Error("Pack of '" + prefabName + "': " + num + " of " + PrefabOf(val2.m_resItem) + " could not be removed after the availability check passed."); } stringBuilder.Append(PrefabOf(val2.m_resItem)).Append(" x").Append(val2.m_amount) .Append(" (chests ") .Append(num2) .Append(", azu ") .Append(num3) .Append(", inventory ") .Append(num4) .Append((num > 0) ? (", free (nocost) " + num) : "") .Append("); "); } if (CargoToGoPlugin.PackEffects.Value) { PlayPackEffects(p, piece); } Say(p, "Packed: " + Localization.instance.Localize(piece.m_name)); Log.Info("Cargo created for '" + prefabName + "' by " + PName(p) + " -> " + stringBuilder.ToString().TrimEnd(Array.Empty<char>())); return true; } catch (Exception e) { Log.Error("TryPack threw for player " + PName(p), e); return false; } } private unsafe static void PlayPackEffects(Player p, Piece piece) { //IL_0006: 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_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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0092: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) try { Vector3 val = ((Component)p).transform.position + ((Component)p).transform.forward * 2f; Quaternion rotation = ((Component)p).transform.rotation; GameObject value = Traverse.Create((object)p).Field("m_placementGhost").GetValue<GameObject>(); if ((Object)(object)value != (Object)null && value.activeInHierarchy) { val = value.transform.position; rotation = value.transform.rotation; } int num = 0; if (piece.m_placeEffect != null) { piece.m_placeEffect.Create(val, rotation, (Transform)null, 1f, -1, default(ZDOID)); num++; } WearNTear component = ((Component)piece).GetComponent<WearNTear>(); if ((Object)(object)component != (Object)null && component.m_destroyedEffect != null) { component.m_destroyedEffect.Create(val, rotation, (Transform)null, 1f, -1, default(ZDOID)); num++; } string text = num.ToString(); Vector3 val2 = val; Log.Debug("Played " + text + " pack effect lists at " + ((object)(*(Vector3*)(&val2))/*cast due to .constrained prefix*/).ToString()); } catch (Exception ex) { Log.Warn("Pack effects failed (cargo was still created): " + ex.GetType().Name + ": " + ex.Message); } } public static bool Unpack(Player p, ItemData cargo) { //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_0218: Unknown result type (might be due to invalid IL or missing references) try { Piece val = CargoFactory.PrefabPieceOf(cargo); string text = CargoFactory.PieceNameOf(cargo); if ((Object)(object)val == (Object)null || val.m_resources == null) { Say(p, "Can't read this cargo's contents; not destroyed."); Log.Error("Unpack aborted by " + PName(p) + ": piece prefab '" + text + "' not found, cargo kept."); return false; } Inventory inventory = ((Humanoid)p).GetInventory(); if (!inventory.RemoveItem(cargo)) { Log.Warn("Unpack aborted by " + PName(p) + ": cargo for '" + text + "' could not be removed from the inventory."); return false; } if (FreeKeyActive(val)) { Say(p, "Cargo unpacked: no materials returned (free build)."); Log.Info("Cargo destroyed for '" + text + "' by " + PName(p) + " -> no materials returned (free-build world key is active)."); return true; } Vector3 val2 = ((Component)p).transform.position + ((Component)p).transform.forward * 1.5f + Vector3.up; StringBuilder stringBuilder = new StringBuilder(); bool flag = false; Requirement[] resources = val.m_resources; foreach (Requirement val3 in resources) { if ((Object)(object)val3.m_resItem == (Object)null || val3.m_amount <= 0) { continue; } int num = Mathf.Max(1, val3.m_resItem.m_itemData.m_shared.m_maxStackSize); int num2 = val3.m_amount; int num3 = 0; int num4 = 0; while (num2 > 0) { int num5 = Mathf.Min(num2, num); ItemData val4 = val3.m_resItem.m_itemData.Clone(); val4.m_dropPrefab = ((Component)val3.m_resItem).gameObject; val4.m_stack = num5; val4.m_quality = 1; val4.m_worldLevel = Game.m_worldLevel; if (inventory.CanAddItem(val4, num5) && inventory.AddItem(val4)) { num3 += num5; } else { ItemDrop.DropItem(val4, num5, val2, Quaternion.identity); num4 += num5; } num2 -= num5; } if (num4 > 0) { flag = true; } stringBuilder.Append(PrefabOf(val3.m_resItem)).Append(" x").Append(val3.m_amount) .Append(" (to inventory ") .Append(num3) .Append(", dropped ") .Append(num4) .Append("); "); } Say(p, flag ? "Cargo unpacked (some materials dropped: inventory full)." : "Cargo unpacked: materials returned."); Log.Info("Cargo destroyed for '" + text + "' by " + PName(p) + " -> materials returned: " + stringBuilder.ToString().TrimEnd(Array.Empty<char>())); return true; } catch (Exception e) { Log.Error("Unpack threw for player " + PName(p), e); return false; } } public static bool IsBuiltFromCargo(Piece piece) { ZNetView val = (((Object)(object)piece != (Object)null) ? ((Component)piece).GetComponent<ZNetView>() : null); if ((Object)(object)val != (Object)null && val.IsValid()) { return val.GetZDO().GetBool("CC_FromCargo", false); } return false; } } [HarmonyPatch(typeof(ObjectDB), "Awake")] [HarmonyPriority(0)] internal static class ObjectDB_Awake { private static void Postfix(ObjectDB __instance) { try { CargoFactory.Ensure(__instance); } catch (Exception e) { Log.Error("ObjectDB.Awake hook failed", e); } } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] [HarmonyPriority(0)] internal static class ObjectDB_Copy { private static void Postfix(ObjectDB __instance) { try { CargoFactory.Ensure(__instance); } catch (Exception e) { Log.Error("ObjectDB.CopyOtherDB hook failed", e); } } } [HarmonyPatch(typeof(ZNetScene), "Awake")] [HarmonyPriority(0)] internal static class ZNetScene_Awake { private static void Postfix() { try { CargoFactory.Ensure(ObjectDB.instance); } catch (Exception e) { Log.Error("ZNetScene.Awake hook failed", e); } } } internal static class PlaceState { public static Piece Piece; public static ItemData Cargo; public static void Clear() { Piece = null; Cargo = null; } } [HarmonyPatch(typeof(Player), "TryPlacePiece")] internal static class Player_TryPlacePiece { private static bool Prefix(Player __instance, Piece piece, ref bool __result) { try { PlaceState.Clear(); if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || (Object)(object)piece == (Object)null) { return true; } if (CargoToGoPlugin.PackInWorld.Value && Packer.PackChord) { Packer.TryPack(__instance, piece); __result = false; return false; } if (__instance.NoCostCheat()) { return true; } ItemData val = CargoFactory.FindCargoFor(((Humanoid)__instance).GetInventory(), piece); if (val != null) { PlaceState.Piece = piece; PlaceState.Cargo = val; Log.Debug("Placing '" + Utils.GetPrefabName(((Component)piece).gameObject) + "' with a cargo."); } } catch (Exception e) { Log.Error("TryPlacePiece hook failed", e); } return true; } } [HarmonyPatch(typeof(Player), "UpdatePlacement")] internal static class Player_UpdatePlacement { private static void Postfix() { PlaceState.Clear(); } } [HarmonyPatch(typeof(Player), "ConsumeResources")] internal static class Player_ConsumeResources { private static bool Prefix(Player __instance, Requirement[] requirements) { try { if (PlaceState.Cargo == null || (Object)(object)PlaceState.Piece == (Object)null) { return true; } if (requirements != PlaceState.Piece.m_resources) { return true; } ItemData cargo = PlaceState.Cargo; PlaceState.Cargo = null; bool flag = ((Humanoid)__instance).GetInventory().RemoveItem(cargo); if (flag) { Log.Info("Cargo used: '" + Utils.GetPrefabName(((Component)PlaceState.Piece).gameObject) + "' built from a cargo by " + Packer.PName(__instance) + "."); } else { Log.Warn("Cargo for '" + Utils.GetPrefabName(((Component)PlaceState.Piece).gameObject) + "' could not be removed from the inventory; falling back to normal material use."); } return !flag; } catch (Exception e) { Log.Error("ConsumeResources hook failed", e); return true; } } } [HarmonyPatch(typeof(Piece), "SetCreator")] internal static class Piece_SetCreator { private static void Postfix(Piece __instance) { try { if (PlaceState.Cargo != null && !((Object)(object)PlaceState.Piece == (Object)null) && !(Utils.GetPrefabName(((Component)__instance).gameObject) != Utils.GetPrefabName(((Component)PlaceState.Piece).gameObject))) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { component.GetZDO().Set("CC_FromCargo", true); Log.Debug("Tagged placed '" + ((Object)__instance).name + "' as built from cargo."); } } } catch (Exception e) { Log.Error("SetCreator hook failed", e); } } } [HarmonyPatch(typeof(Player), "HaveRequirements", new Type[] { typeof(Piece), typeof(RequirementMode) })] internal static class Player_HaveRequirements { private static void Postfix(Player __instance, Piece piece, RequirementMode mode, ref bool __result) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0083: Unknown result type (might be due to invalid IL or missing references) try { if (!__result && (int)mode != 1 && !((Object)(object)piece == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { bool flag = CargoFactory.FindCargoFor(((Humanoid)__instance).GetInventory(), piece) != null; if (!flag && CargoToGoPlugin.PackInWorld.Value && Packer.PackChord && (Object)(object)piece == (Object)(object)__instance.GetSelectedPiece()) { flag = Packer.CanPack(__instance, piece); } if (flag && (!((Object)(object)piece.m_craftingStation != (Object)null) || Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, ((Component)__instance).transform.position))) && (string.IsNullOrEmpty(piece.m_dlc) || DLCMan.instance.IsDLCInstalled(piece.m_dlc))) { __result = true; } } } catch (Exception e) { Log.Error("HaveRequirements hook failed", e); } } } [HarmonyPatch(typeof(Hud), "OnLeftClickPiece")] internal static class Hud_OnLeftClickPiece { private static void Postfix() { try { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && Packer.PackChord) { Piece selectedPiece = localPlayer.GetSelectedPiece(); if ((Object)(object)selectedPiece != (Object)null) { Packer.TryPack(localPlayer, selectedPiece); } } } catch (Exception e) { Log.Error("Hud.OnLeftClickPiece hook failed", e); } } } [HarmonyPatch(typeof(Player), "RemovePiece")] internal static class Player_RemovePiece { public static Piece Pending; public static float PendingTime; private static bool Prefix(Player __instance) { Pending = null; try { if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !Packer.Alt) { return true; } Piece hoveringPiece = __instance.GetHoveringPiece(); if ((Object)(object)hoveringPiece == (Object)null) { return true; } if (!Packer.IsBuiltFromCargo(hoveringPiece) && !CargoToGoPlugin.AltDestroyAnyPiece.Value) { return true; } if ((Object)(object)CargoFactory.GetCargoPrefab(hoveringPiece) == (Object)null) { Log.Warn("ALT-destroy of '" + Utils.GetPrefabName(((Component)hoveringPiece).gameObject) + "': no cargo prefab exists, using normal destroy."); return true; } if (!((Humanoid)__instance).GetInventory().HaveEmptySlot()) { ((Character)__instance).Message((MessageType)2, "No free inventory slot for a cargo.", 0, (Sprite)null, false); Log.Info("ALT-destroy of '" + Utils.GetPrefabName(((Component)hoveringPiece).gameObject) + "' blocked for " + Packer.PName(__instance) + ": no free inventory slot."); return false; } ZNetView component = ((Component)hoveringPiece).GetComponent<ZNetView>(); if ((Object)(object)component == (Object)null || !component.IsValid()) { return true; } component.ClaimOwnership(); Pending = hoveringPiece; PendingTime = Time.time; } catch (Exception e) { Log.Error("RemovePiece hook failed", e); Pending = null; } return true; } private static void Postfix(bool __result) { if (!__result) { Pending = null; } } } [HarmonyPatch(typeof(Piece), "DropResources")] internal static class Piece_DropResources { private static bool Prefix(Piece __instance) { try { Piece pending = Player_RemovePiece.Pending; if ((Object)(object)pending == (Object)null || pending != __instance) { return true; } Player_RemovePiece.Pending = null; string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject); if (Packer.FreeKeyActive(__instance)) { Log.Debug("Repack of '" + prefabName + "' skipped: free-build world key is active, vanilla drops nothing."); return true; } if (Time.time - Player_RemovePiece.PendingTime > 1.5f) { Log.Warn("Repack of '" + prefabName + "' timed out (removal took >1.5s); normal drops used."); return true; } Player localPlayer = Player.m_localPlayer; GameObject cargoPrefab = CargoFactory.GetCargoPrefab(__instance); if ((Object)(object)localPlayer == (Object)null || (Object)(object)cargoPrefab == (Object)null) { return true; } ItemData val = cargoPrefab.GetComponent<ItemDrop>().m_itemData.Clone(); val.m_dropPrefab = cargoPrefab; val.m_stack = 1; val.m_quality = 1; if (!((Humanoid)localPlayer).GetInventory().AddItem(val)) { Log.Warn("Repack of '" + prefabName + "' by " + Packer.PName(localPlayer) + ": AddItem failed, normal material drops used."); return true; } ((Character)localPlayer).Message((MessageType)2, "Repacked: " + Localization.instance.Localize(__instance.m_name), 0, (Sprite)null, false); Log.Info("Cargo repacked from piece '" + prefabName + "' by " + Packer.PName(localPlayer) + " (normal drops skipped)."); return false; } catch (Exception e) { Log.Error("Piece.DropResources hook failed", e); return true; } } } internal static class Rules { public static bool Blocked(Inventory target, ItemData item) { if (!CargoFactory.IsCargo(item)) { return false; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer != (Object)null) { return target != ((Humanoid)localPlayer).GetInventory(); } return false; } public static void Warn(string text) { if ((Object)(object)Player.m_localPlayer != (Object)null) { ((Character)Player.m_localPlayer).Message((MessageType)2, text, 0, (Sprite)null, false); } Log.Debug("Blocked action: " + text); } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })] internal static class Inv_Add1 { private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { if (!Rules.Blocked(__instance, item)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(Vector2i) })] internal static class Inv_Add2 { private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { if (!Rules.Blocked(__instance, item)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(int), typeof(int), typeof(int), typeof(bool) })] internal static class Inv_Add3 { private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { if (!Rules.Blocked(__instance, item)) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData) })] internal static class Inv_Move1 { private static bool Prefix(Inventory __instance, ItemData item) { if (!Rules.Blocked(__instance, item)) { return true; } Rules.Warn("Cargo can't leave your inventory."); return false; } } [HarmonyPatch(typeof(Inventory), "MoveItemToThis", new Type[] { typeof(Inventory), typeof(ItemData), typeof(int), typeof(int), typeof(int) })] internal static class Inv_Move2 { private static bool Prefix(Inventory __instance, ItemData item, ref bool __result) { if (!Rules.Blocked(__instance, item)) { return true; } Rules.Warn("Cargo can't leave your inventory."); __result = false; return false; } } [HarmonyPatch(typeof(InventoryGrid), "DropItem")] internal static class Grid_Drop { private static bool Prefix(InventoryGrid __instance, ItemData item, ref bool __result) { if (!Rules.Blocked(__instance.GetInventory(), item)) { return true; } Rules.Warn("Cargo can't leave your inventory."); __result = false; return false; } } [HarmonyPatch(typeof(Humanoid), "DropItem")] internal static class Hum_Drop { private static bool Prefix(ItemData item, ref bool __result) { if (!CargoFactory.IsCargo(item)) { return true; } Rules.Warn("Cargo can't be dropped. Ctrl+Alt+Right-click unpacks it."); __result = false; return false; } } [HarmonyPatch(typeof(Humanoid), "UseItem")] internal static class Hum_Use { private static bool Prefix(ItemData item) { if (!CargoFactory.IsCargo(item)) { return true; } Rules.Warn("Cargo contents are only usable for building."); return false; } } [HarmonyPatch(typeof(InventoryGui), "OnRightClickItem")] internal static class Gui_RightClick { private static bool Prefix(InventoryGrid grid, ItemData item) { try { if (!CargoFactory.IsCargo(item) || !Packer.Ctrl || !Packer.Alt) { return true; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || grid.GetInventory() != ((Humanoid)localPlayer).GetInventory()) { return false; } Packer.Unpack(localPlayer, item); return false; } catch (Exception e) { Log.Error("OnRightClickItem hook failed", e); return true; } } } [HarmonyPatch(typeof(Inventory), "IsTeleportable")] internal static class Inv_IsTeleportable { private static void Prefix(Inventory __instance) { try { foreach (ItemData allItem in __instance.GetAllItems()) { if (CargoFactory.IsCargo(allItem)) { CargoFactory.RefreshTeleportable(allItem); } } } catch (Exception e) { Log.Error("Inventory.IsTeleportable hook failed", e); } } } [HarmonyPatch(typeof(KeyHints), "UpdateHints")] internal static class KeyHints_UpdateHints { private static void Postfix(KeyHints __instance) { KeyHintUi.Tick(__instance); } } [BepInPlugin("com.kydldev.CargoToGo", "CargoToGo", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class CargoToGoPlugin : BaseUnityPlugin { public const string GUID = "com.kydldev.CargoToGo"; public const string PluginName = "CargoToGo"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry<float> ContainerRange; internal static ConfigEntry<bool> PullFromContainers; internal static ConfigEntry<bool> UseAzuCraftyBoxes; internal static ConfigEntry<bool> ContainersFirst; internal static ConfigEntry<bool> PackInWorld; internal static ConfigEntry<bool> AltDestroyAnyPiece; internal static ConfigEntry<bool> PackEffects; internal static ConfigEntry<bool> ShowKeyHints; internal static ConfigEntry<bool> ShowCargoTab; internal static ConfigEntry<bool> VerboseLogging; internal static ConfigEntry<float> WeightMultiplier; private void Awake() { //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02de: Unknown result type (might be due to invalid IL or missing references) Log.Init(); ContainerRange = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ContainerRange", 20f, "Radius (m) around the player to search for chests when packing a cargo. 0 turns CargoToGo's own search off (combine with UseAzuCraftyBoxes to rely only on AzuCraftyBoxes' range)."); PullFromContainers = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PullFromContainers", true, "Allow packing materials from nearby chests."); UseAzuCraftyBoxes = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "UseAzuCraftyBoxes", true, "If AzuCraftyBoxes is installed, also pack from the containers it reaches: its own Container Range, chest toggles, item include/exclude rules, 'leave one', drawers and bags. Works even when ContainerRange is 0. Needs PullFromContainers."); ContainersFirst = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ContainersFirst", true, "Take materials from chests before the player's inventory."); PackInWorld = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PackInWorld", true, "Ctrl+Alt + left click with a piece selected (in the world) packs a cargo instead of placing the piece."); AltDestroyAnyPiece = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AltDestroyAnyPiece", false, "ALT + destroy returns a cargo even for pieces that were not built from a cargo."); PackEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PackEffects", true, "Play build dust / sound / the piece's break effect when a cargo is packed."); ShowKeyHints = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowKeyHints", true, "Show the Pack cargo / Repack shortcuts in the build-mode key hint bar (keyboard only)."); ShowCargoTab = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ShowCargoTab", true, "Add a 5th \"Cargos\" tab to the build menu that lists the pieces you currently hold a cargo for. Needs a game restart."); VerboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "VerboseLogging", false, "Also write DEBUG lines (blocked actions, tagging, ...) to the BepInEx log."); WeightMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("General", "WeightMultiplier", 1f, "Cargo weight = contents weight x this. Needs a game restart."); Log.Verbose = VerboseLogging.Value; Log.Info("CargoToGo 1.0.0 starting. ContainerRange=" + ContainerRange.Value + " PullFromContainers=" + PullFromContainers.Value + " UseAzuCraftyBoxes=" + UseAzuCraftyBoxes.Value + " (AzuCraftyBoxes installed: " + AzuCompat.Installed + ") ContainersFirst=" + ContainersFirst.Value + " PackInWorld=" + PackInWorld.Value + " PackEffects=" + PackEffects.Value + " ShowKeyHints=" + ShowKeyHints.Value + " ShowCargoTab=" + ShowCargoTab.Value + " AltDestroyAnyPiece=" + AltDestroyAnyPiece.Value + " WeightMultiplier=" + WeightMultiplier.Value); try { Harmony val = new Harmony("com.kydldev.CargoToGo"); val.PatchAll(); int num = 0; foreach (MethodBase patchedMethod in val.GetPatchedMethods()) { _ = patchedMethod; num++; } Log.Info("Harmony patched " + num + " methods."); } catch (Exception e) { Log.Error("Harmony patching failed, the mod will not work", e); } } }