diff --git a/Utilities/ItemBaseUtil.cs b/Utilities/ItemBaseUtil.cs index 4b6f2bb..e6797d7 100644 --- a/Utilities/ItemBaseUtil.cs +++ b/Utilities/ItemBaseUtil.cs @@ -33,7 +33,17 @@ public static Boolean CompareDeep(this ItemBase original, ItemBase comparer) /// True if ItemID and Type of both Items match, otherwise false public static bool Compare(this ItemBase original, ItemBase comparer) { - return original.mnItemID == comparer.mnItemID && original.mType == comparer.mType; + if (original == null || comparer == null) + return false; + if (original.mType == comparer.mType) + { + if (original.mType == ItemType.ItemCubeStack && comparer.mType == ItemType.ItemCubeStack) + return (original as ItemCubeStack).CompareCubes(comparer as ItemCubeStack); + else + return original.mnItemID == comparer.mnItemID && original.mType == comparer.mType; + } + else + return false; } /// @@ -43,10 +53,10 @@ public static bool Compare(this ItemBase original, ItemBase comparer) /// Original Item /// Item to Compare Against /// True if ItemID, Type, CubeType, CubeValue of both Items match, otherwise false - public static bool Compare(this ItemCubeStack original, ItemCubeStack comparer) + public static bool CompareCubes(this ItemCubeStack original, ItemCubeStack comparer) { // We'll ignore the original stacks for now. May revisit in the future - return original != null && comparer != null && original.Compare(comparer.As()) && + return original != null && comparer != null && original.mCubeType == comparer.mCubeType && original.mCubeValue == comparer.mCubeValue; // && original.mnAmount == comparer.mnAmount; } @@ -183,14 +193,15 @@ public static void DecrementStack(this ItemBase item, Int32 amount = 1) /// /// The Item Stack /// The amount of Items - public static void SetAmount(this ItemBase item, Int32 amount) + public static ItemBase SetAmount(this ItemBase item, Int32 amount) { if (!item.IsStack()) - return; + return item; if (item.mType == ItemType.ItemCubeStack) item.As().mnAmount = amount; if (item.mType == ItemType.ItemStack) item.As().mnAmount = amount; + return item; } /// diff --git a/Utilities/MachineInventory.cs b/Utilities/MachineInventory.cs new file mode 100644 index 0000000..1507cd8 --- /dev/null +++ b/Utilities/MachineInventory.cs @@ -0,0 +1,415 @@ +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +namespace FortressCraft.Community.Utilities +{ + /// + /// Generic machine inventory class with list inventory support + /// + /// Origianl code by steveman0 + public class MachineInventory + { + /// + /// For associating the machine owner of the inventory + /// + public MachineEntity Machine; + + /// + /// For associating the mob owner of the inventory + /// + public MobEntity Mob; + + /// + /// The total item capacity of the storage + /// + public int StorageCapacity; + + /// + /// The list of items in the inventory + /// + public List Inventory; + + /// + /// Generic machine inventory class with list inventory support + /// + /// For associating the owner machine + /// The storage capacity of the inventory + public MachineInventory(MachineEntity machineentity, int storagecapacity) + { + this.Machine = machineentity; + this.StorageCapacity = storagecapacity; + this.Inventory = new List(); + } + + /// + /// Generic machine inventory class with list inventory support + /// + /// For associating the owner mob + /// The storage capacity of the inventory + public MachineInventory(MobEntity mobentity, int storagecapacity) + { + this.Mob = mobentity; + this.StorageCapacity = storagecapacity; + this.Inventory = new List(); + } + + /// + /// Add a single item type to the inventory + /// + /// The item to add + /// Amount of items added if given a stack + /// Returns the remainder that doesn't fit or null if successful + public ItemBase AddItem(ItemBase item, int amount = 1) + { + return ItemBaseUtil.AddListItem(item, ref this.Inventory, true, this.StorageCapacity); + } + + /// + /// Add items from a source inventory or item list + /// + /// The source inventory or list of items + /// The number of items to transfer + public void AddItem(ref List items, int amount = 1) + { + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, amount, this.StorageCapacity, false); + } + + /// + /// Transfers items to machine inventory if they are on the provided whitelist + /// + /// Source inventory or list of items + /// List of items types allowed in the transfer + /// Number of items to add + public void AddWhiteList(ref List items, IEnumerable whitelist, int amount = 1) + { + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, amount, this.StorageCapacity, false, whitelist, true); + } + + /// + /// Transfers items to machine inventory if they are on the provided whitelist + /// + /// Source inventory or list of items + /// Item type allowed in the transfer + /// Number of items to add + public void AddWhiteList(ref List items, ItemBase whitelist, int amount = 1) + { + ItemBase[] WhiteList = new[] { whitelist }; + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, amount, this.StorageCapacity, false, WhiteList, true); + } + + /// + /// Transfers items to machine inventory if they are not on the provided blacklist + /// + /// Source inventory or list of items + /// List of items forbidden from transfer + /// Number of items to add + public void AddBlackList(ref List items, IEnumerable blacklist, int amount = 1) + { + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, amount, this.StorageCapacity, false, blacklist, false); + } + + + + /// + /// Transfers items to machine inventory if they are not on the provided blacklist + /// + /// Source inventory or list of items + /// Item forbidden from transfer + /// Number of items to add + public void AddBlackList(ref List items, ItemBase blacklist, int amount = 1) + { + ItemBase[] BlackList = new[] { blacklist }; + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, amount, this.StorageCapacity, false, BlackList, false); + } + + /// + /// Fills the inventory to capacity with source items + /// + /// Source items to fill the inventory + public void Fill(ref List items) + { + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, this.SpareCapacity(), this.StorageCapacity); + } + + /// + /// Fills the inventory to capacity with source items + /// + /// Source items to fill the inventory + /// Item type allowed in the transfer + public void FillWhiteList(ref List items, IEnumerable whitelist) + { + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, this.SpareCapacity(), this.StorageCapacity, false, whitelist, true); + } + + /// + /// Fills the inventory to capacity with source items + /// + /// Source items to fill the inventory + /// Item type allowed in the transfer + public void FillWhiteList(ref List items, ItemBase whitelist) + { + ItemBase[] WhiteList = new[] { whitelist }; + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, this.SpareCapacity(), this.StorageCapacity, false, WhiteList, true); + } + + /// + /// Fills the inventory to capacity with source items + /// + /// Source items to fill the inventory + /// Item forbidden from transfer + public void FillBlackList(ref List items, IEnumerable blacklist) + { + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, this.SpareCapacity(), this.StorageCapacity, false, blacklist, false); + } + + /// + /// Fills the inventory to capacity with source items + /// + /// Source items to fill the inventory + /// Item forbidden from transfer + public void FillBlackList(ref List items, ItemBase blacklist) + { + ItemBase[] BlackList = new[] { blacklist }; + ItemBaseUtil.MoveItems(ref items, ref this.Inventory, this.SpareCapacity(), this.StorageCapacity, false, BlackList, false); + } + + /// + /// Empty the inventory of items + /// + /// Target inventory or list + /// Maximum number of items to take + public void Empty(ref List items, int amount) + { + ItemBaseUtil.MoveItems(ref this.Inventory, ref items, amount); + } + + /// + /// Return item from inventory by example (obeys stack size) + /// + /// Example item to find in inventory + /// Returns the item or null if unavailable or insufficient stack size + public ItemBase RemoveItem(ItemBase item) + { + return ItemBaseUtil.RemoveListItem(item, ref this.Inventory, false); + } + + /// + /// Return item from inventory by example including partial item stack + /// + /// Example item to find in inventory + /// Returns the item or partial stack (null if item not found) + public ItemBase RemovePartialStack(ItemBase item) + { + return ItemBaseUtil.RemoveListItem(item, ref this.Inventory, true); + } + + /// + /// Remove any single item type from the inventory + /// + /// Amount to remove (for stacks) + /// The ItemBase removed from inventory + public ItemBase RemoveAnySingle(int amount = 1) + { + List output = new List(); + ItemBaseUtil.MoveItems(ref this.Inventory, ref output, amount, amount, true); + if (output.Count == 0) + return null; + return output[0]; + } + + /// + /// Remove items from inventory if items are on the whitelist + /// + /// The target inventory or list to store the items + /// The list of items allowed to transfer + /// Storage capacity of target inventory + /// Amount of items to move in this transfer + public void RemoveWhiteList(ref List items, IEnumerable whitelist, int storagecapacity = int.MaxValue, int amount = 1) + { + ItemBaseUtil.MoveItems(ref this.Inventory, ref items, amount, storagecapacity, false, whitelist, true); + } + + /// + /// Remove items from inventory if items are on the whitelist + /// + /// The target inventory or list to store the items + /// Item allowed to transfer + /// Storage capacity of target inventory + /// Amount of items to move in this transfer + public void RemoveWhiteList(ref List items, ItemBase whitelist, int storagecapacity = int.MaxValue, int amount = 1) + { + ItemBase[] WhiteList = new [] { whitelist }; + ItemBaseUtil.MoveItems(ref this.Inventory, ref items, amount, storagecapacity, false, WhiteList, true); + } + + /// + /// Remove items from inventory if items are not on the blacklist + /// + /// The target inventory or list to store the items + /// The list of items forbidden from transfer + /// Storage capacity of target inventory + /// Amount of items to move in this transfer + public void RemoveBlackList(ref List items, IEnumerable blacklist, int storagecapacity = int.MaxValue, int amount = 1) + { + ItemBaseUtil.MoveItems(ref this.Inventory, ref items, amount, storagecapacity, false, blacklist, false); + } + + /// + /// Remove items from inventory if items are not on the blacklist + /// + /// The target inventory or list to store the items + /// Item forbidden from transfer + /// Storage capacity of target inventory + /// Amount of items to move in this transfer + public void RemoveBlackList(ref List items, ItemBase blacklist, int storagecapacity = int.MaxValue, int amount = 1) + { + ItemBase[] BlackList = new[] { blacklist }; + ItemBaseUtil.MoveItems(ref this.Inventory, ref items, amount, storagecapacity, false, BlackList, false); + } + + /// + /// Returns the spare capacity of the inventory + /// + /// The spare capacity of the inventory + public int SpareCapacity() + { + return this.StorageCapacity - this.Inventory.GetItemCount(); + } + + /// + /// Returns the current number of items in the inventory + /// + /// Current number of items in inventory + public int ItemCount() + { + return this.Inventory.GetItemCount(); + } + + /// + /// Helper logic for checking if the inventory has space + /// + /// + public bool HasSpareCapcity() + { + return this.SpareCapacity() > 0; + } + + /// + /// Helper logic for checking if the inventory is empty + /// + /// + public bool IsEmpty() + { + return this.ItemCount() == 0; + } + + /// + /// Helper logic for checking if the inventory is full + /// + /// + public bool IsFull() + { + return this.ItemCount() >= this.StorageCapacity; + } + + /// + /// Item drop code for emptying the inventory on the ground on machine delete + /// + public void DropOnDelete() + { + if (this.Machine == null) + { + Debug.LogWarning("Tried to drop machine inventory when not associated with a machine!"); + return; + } + if (!WorldScript.mbIsServer) + return; + System.Random random = new System.Random(); + for (int index = 0; index < this.Inventory.Count; ++index) + { + if (this.Inventory[index] != null) + { + Vector3 velocity = new Vector3((float)random.NextDouble() - 0.5f, (float)random.NextDouble() - 0.5f, (float)random.NextDouble() - 0.5f); + ItemManager.instance.DropItem(this.Inventory[index], this.Machine.mnX, this.Machine.mnY, this.Machine.mnZ, velocity); + } + } + this.Inventory = null; + } + + /// + /// Item drop code for emptying the inventory on the ground on mob delete + /// + public void DropOnMobDelete() + { + if (this.Mob == null) + { + Debug.LogWarning("Tried to drop mob inventory when not associated with a mob!"); + return; + } + if (!WorldScript.mbIsServer) + return; + System.Random random = new System.Random(); + for (int index = 0; index < this.Inventory.Count; ++index) + { + if (this.Inventory[index] != null) + { + Vector3 velocity = new Vector3((float)random.NextDouble() - 0.5f, (float)random.NextDouble() - 0.5f, (float)random.NextDouble() - 0.5f); + ItemManager.instance.DropItem(this.Inventory[index], this.Mob.mnX, this.Mob.mnY, this.Mob.mnZ, velocity); + } + } + this.Inventory = null; + } + + /// + /// Generic serialization function for writing the inventory to disk + /// + /// + public void WriteInventory(BinaryWriter writer) + { + if (this.Inventory == null) + { + Debug.LogWarning("Trying to write Machine Inventory but inventory is null?"); + return; + } + int listcount = this.Inventory.Count; + int version = 0; + + writer.Write(version); + writer.Write(listcount); + for (int index = 0; index < listcount; ++index) + { + ItemFile.SerialiseItem(this.Inventory[index], writer); + } + } + + /// + /// Generic serialization function for reading the inventory from disk + /// + /// + public void ReadInventory(BinaryReader reader) + { + int listcount; + int version = reader.ReadInt32(); + this.Inventory = new List(); + + switch (version) + { + case 0: + listcount = reader.ReadInt32(); + for (int index = 0; index < listcount; ++index) + { + ItemBase item = ItemFile.DeserialiseItem(reader); + if (item != null) + this.Inventory.Add(item); + else + Debug.LogError("Machine inventory tried to read in a null item! Corrupt save?"); + } + break; + default: + Debug.LogError("Attempted to read Machine inventory version that does not exist!"); + break; + } + } + } +} diff --git a/Utilities/UIExample/FreightCartWindow.cs b/Utilities/UIExample/FreightCartWindow.cs new file mode 100644 index 0000000..8237cf5 --- /dev/null +++ b/Utilities/UIExample/FreightCartWindow.cs @@ -0,0 +1,268 @@ +using UnityEngine; +using System.Collections.Generic; +using FortressCraft.Community.Utilities; + +public class FreightCartWindow : BaseMachineWindow +{ + public const string InterfaceName = "FreightCartStation"; + + private bool dirty; + private bool ChooseLowStock = false; + + public override void SpawnWindow(SegmentEntity targetEntity) + { + FreightCartStation station = targetEntity as FreightCartStation; + Debug.Log("Before close?"); + //Catch for when the window is called on an inappropriate machine + if (station == null) + { + GenericMachinePanelScript.instance.Hide(); + UIManager.RemoveUIRules("Machine"); + return; + } + //station.UIdelay = 0; + //station.UILock = true; + UIUtil.UIdelay = 0; + UIUtil.UILock = true; + Debug.Log("After close?"); + + this.manager.SetTitle("Freight Cart Station - Register Freight"); + + this.manager.AddButton("switchlowstock", "Edit Low Stock", 25, 0); + this.manager.AddButton("switchhighstock", "Edit High Stock", 175, 0); + + int spacing = 175; + int count = 0; + int offset = 50; + if (station.massStorageCrate != null) + count = FreightCartManager.instance.GetFreightEntries(station.massStorageCrate).Count; + for (int n = 0; n < count + 1; n++) + { + int suffix = n; + if (n == count) + suffix = -1; + this.manager.AddIcon("registry" + suffix, "empty", Color.white, 0, offset + (spacing * n)); + this.manager.AddBigLabel("registrytitle" + n, "Add New Freight", Color.white, 60, offset + (spacing * n)); + if (suffix != -1) + { + this.manager.AddLabel(GenericMachineManager.LabelType.OneLineHalfWidth, "lowstocktitle" + n, "Low Stock Limit", this.ChooseLowStock == true ? Color.white : Color.gray, false, 0, offset + (spacing * n + 40)); + this.manager.AddLabel(GenericMachineManager.LabelType.OneLineHalfWidth, "highstocktitle" + n, "High Stock Limit", this.ChooseLowStock == false ? Color.white : Color.gray, false, 150, offset + (spacing * n + 40)); + this.manager.AddLabel(GenericMachineManager.LabelType.OneLineHalfWidth, "lowstock" + n, "Low Stock Limit", this.ChooseLowStock == true ? Color.white : Color.gray, false, 0, offset + (spacing * n + 60)); + this.manager.AddLabel(GenericMachineManager.LabelType.OneLineHalfWidth, "highstock" + n, "High Stock Limit", this.ChooseLowStock == false ? Color.white : Color.gray, false, 150, offset + (spacing * n + 60)); + this.manager.AddButton("decreasestock" + n, "Decrease Stock", 25, offset + (spacing * n + 100)); + this.manager.AddButton("increasestock" + n, "Increase Stock", 175, offset + (spacing * n + 100)); + } + } + this.dirty = true; + } + + public override void UpdateMachine(SegmentEntity targetEntity) + { + FreightCartStation station = targetEntity as FreightCartStation; + //Catch for when the window is called on an inappropriate machine + if (station == null) + { + GenericMachinePanelScript.instance.Hide(); + UIManager.RemoveUIRules("Machine"); + return; + } + //station.UIdelay = 0; + UIUtil.UIdelay = 0; + List registries = new List(); + if (station.massStorageCrate != null) + registries = FreightCartManager.instance.GetFreightEntries(station.massStorageCrate); + else + return; + + for (int index = 0; index < registries.Count; index++) + { + ItemBase item = registries[index].FreightItem; + int lowstock = registries[index].LowStock; + int highstock = registries[index].HighStock; + + string itemname = ItemManager.GetItemName(item); + string iconname = ItemManager.GetItemIcon(item); + + this.manager.UpdateIcon("registry" + index, iconname, Color.white); + this.manager.UpdateLabel("registrytitle" + index, itemname, Color.white); + this.manager.UpdateLabel("lowstock" + index, registries[index].LowStock.ToString(), this.ChooseLowStock == true ? Color.white : Color.gray); + this.manager.UpdateLabel("highstock" + index, registries[index].HighStock.ToString(), this.ChooseLowStock == false ? Color.white : Color.gray); + this.manager.UpdateLabel("lowstocktitle" + index, "Low Stock Limit", this.ChooseLowStock == true ? Color.white : Color.gray); + this.manager.UpdateLabel("highstocktitle" + index, "High Stock Limit", this.ChooseLowStock == false ? Color.white : Color.gray); + } + if (this.dirty == true) + { + this.UpdateState(station); + this.dirty = false; + } + } + + private void UpdateState(FreightCartStation machine) + { + return; + } + + public override bool ButtonClicked(string name, SegmentEntity targetEntity) + { + FreightCartStation station = targetEntity as FreightCartStation; + + if (name.Contains("registry")) // drag drop to a slot + { + int slotNum = -1; + int.TryParse(name.Replace("registry", ""), out slotNum); //Get slot name as number + List registries = FreightCartManager.instance.GetFreightEntries(station.massStorageCrate); + + if (slotNum > -1) // valid slot + { + //clear registry + FreightCartManager.instance.RemoveRegistry(station.massStorageCrate, registries[slotNum].FreightItem); + this.manager.RedrawWindow(); + } + + return true; + } + else if (name.Contains("switchlowstock")) + { + this.ChooseLowStock = true; + this.manager.RedrawWindow(); + } + else if (name.Contains("switchhighstock")) + { + this.ChooseLowStock = false; + this.manager.RedrawWindow(); + } + else if (name.Contains("decreasestock")) + { + int slotNum = -1; + int.TryParse(name.Replace("decreasestock", ""), out slotNum); //Get slot name as number + List registries = FreightCartManager.instance.GetFreightEntries(station.massStorageCrate); + + if (slotNum > -1) // valid slot + { + int amount = 100; + if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) + amount = 10; + if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) + amount = 1; + if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)) + amount = 1000; + + int stock; + if (this.ChooseLowStock) + { + stock = registries[slotNum].LowStock - amount; + if (stock < 0) + stock = 0; + FreightCartManager.instance.UpdateRegistry(station.massStorageCrate, registries[slotNum].FreightItem, stock, registries[slotNum].HighStock); + this.manager.UpdateLabel("lowstock" + slotNum, stock.ToString(), Color.white); + } + else + { + stock = registries[slotNum].HighStock - amount; + if (stock < 0) + stock = 0; + FreightCartManager.instance.UpdateRegistry(station.massStorageCrate, registries[slotNum].FreightItem, registries[slotNum].LowStock, stock); + this.manager.UpdateLabel("highstock" + slotNum, stock.ToString(), Color.white); + } + } + } + else if (name.Contains("increasestock")) + { + int slotNum = -1; + int.TryParse(name.Replace("increasestock", ""), out slotNum); //Get slot name as number + List registries = FreightCartManager.instance.GetFreightEntries(station.massStorageCrate); + + if (slotNum > -1) // valid slot + { + int amount = 100; + if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift)) + amount = 10; + if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) + amount = 1; + if (Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt)) + amount = 1000; + + int stock; + if (this.ChooseLowStock) + { + stock = registries[slotNum].LowStock + amount; + FreightCartManager.instance.UpdateRegistry(station.massStorageCrate, registries[slotNum].FreightItem, stock, registries[slotNum].HighStock); + this.manager.UpdateLabel("lowstock" + slotNum, stock.ToString(), Color.white); + } + else + { + stock = registries[slotNum].HighStock + amount; + FreightCartManager.instance.UpdateRegistry(station.massStorageCrate, registries[slotNum].FreightItem, registries[slotNum].LowStock, stock); + this.manager.UpdateLabel("highstock" + slotNum, stock.ToString(), Color.white); + } + } + } + + return false; + } + + public override ItemBase GetDragItem(string name, SegmentEntity targetEntity) + { + FreightCartStation machine = targetEntity as FreightCartStation; + + return null; + } + + public override bool RemoveItem(string name, ItemBase originalItem, ItemBase swapitem, SegmentEntity targetEntity) + { + FreightCartStation machine = targetEntity as FreightCartStation; + + return false; + } + + public override void HandleItemDrag(string name, ItemBase draggedItem, DragAndDropManager.DragRemoveItem dragDelegate, SegmentEntity targetEntity) + { + FreightCartStation station = targetEntity as FreightCartStation; + if (station.massStorageCrate == null) + return; + + if (name.Contains("registry")) // drag drop to a slot + { + int slotNum = -1; + int.TryParse(name.Replace("registry", ""), out slotNum); //Get slot name as number + + if (slotNum == -1) // valid slot + { + if (this.manager.mWindowLookup[name + "_icon"].GetComponent().spriteName == "empty") + { + FreightCartManager.instance.AddRegistry(station.massStorageCrate, draggedItem, 0, 0); + this.manager.RedrawWindow(); + } + //machine.filterCubeId[slotNum] = cubeId; + //machine.filterCubeValue[slotNum] = cubeValue; + //machine.filterItem[slotNum] = draggedItem.mnItemID; + //UnityEngine.Debug.LogError("SET: " + cubeId + " : " + cubeValue + " : " + draggedItem.mnItemID + " : " + draggedItem.mType); + + //UnityEngine.Debug.LogError("item set"); + } + } + + return; + } + + public static NetworkInterfaceResponse HandleNetworkCommand(Player player, NetworkInterfaceCommand nic) + { + FreightCartStation station = nic.target as FreightCartStation; + + string command = nic.command; + if (command != null) + { + if (command == "test") + { + // do whatever + } + } + + return new NetworkInterfaceResponse + { + entity = station, + inventory = player.mInventory + }; + } +} + diff --git a/Utilities/UIUtil.cs b/Utilities/UIUtil.cs new file mode 100644 index 0000000..30f345a --- /dev/null +++ b/Utilities/UIUtil.cs @@ -0,0 +1,233 @@ +using System; +using System.Reflection; +using UnityEngine; + +namespace FortressCraft.Community.Utilities +{ + /// + /// Simple cross-mod compatible UI support. Original code by BinaryAlgorithm, updated by steveman0 + /// + public class UIUtil + { + /// + /// Timer to delay dissociation of UI panel to overcome race condition + /// + public static int UIdelay; + /// + /// Lock to prevent running the dissociation when it isn't needed + /// + public static bool UILock; + + /// + /// Associates the machine so that it, and only it, can handle releasing the UI + /// + public static SegmentEntity TargetMachine; + + /// + /// Vector for recording default window position for scaled UI + /// + private static Vector3 StartPos; + + /// + /// Used to prevent rescaling the UI after it's already been done + /// + private static bool firstopen; + + /// + /// Call this in GetPopupText to handle your UI Window + /// + /// Pass the current machine + /// The mod window inherited from BaseMachineWindow + /// + public static bool HandleThisMachineWindow(SegmentEntity theMachine, BaseMachineWindow theWindow) + { + try + { + //GenericMachineManager manager = GenericMachinePanelScript.instance.manager; // not yet + GenericMachineManager manager = typeof(GenericMachinePanelScript).GetField("manager", BindingFlags.NonPublic | + BindingFlags.Instance).GetValue(GenericMachinePanelScript.instance) as GenericMachineManager; + + // this will replace with the current machine's window, which is OK as long as each Mod uses this technique + manager.windows[eSegmentEntity.Mod] = theWindow; + UIUtil.TargetMachine = theMachine; + theWindow.manager = manager; + UIUtil.UIdelay = 0; + UIUtil.UILock = true; + } + catch (Exception ex) + { + //this.error = "Window Registration failed : " + ex.Message; + UnityEngine.Debug.LogError("Window Registration failed : " + ex.Message + " : " + ex.StackTrace); + } + GenericMachinePanelScript panel = GenericMachinePanelScript.instance; + + try + { + // player looking at this machine + if (WorldScript.instance.localPlayerInstance.mPlayerBlockPicker.selectedEntity == theMachine) + { + if (panel.Background_Panel.activeSelf == true) // window is open + { + panel.gameObject.SetActive(true); // undoes the default handler hiding the window + } + + // player interacts with machine + if (Input.GetButtonDown("Interact")) // "E" by default + { + // UIManager.UpdateGenericMachineWindow() -> GenericMachinePanelScript.TryShow() + // default handler will try and fail as intended because our window is not in its dictionary, this is fine + // similarly, the Hide() should not occur because the selectedEntity is this machine (panel.targetEntity) + //Debug.Log("Interacted"); + if (panel.Background_Panel.activeSelf == true) // window is not already opened + { + // Do nothing + } + else // window IS already opened, we pressed to interact again (meaning to close it) + { + Hide(panel); // hide window, since we are not focused on this machine anymore + DragAndDropManager.instance.CancelDrag(); + DragAndDropManager.instance.DisableDragBackground(); + } + } + else if (Input.GetKeyDown(KeyCode.Escape)) // escape should close window also + { + if (panel.isActiveAndEnabled) + UIManager.instance.UnpauseGame(); + Hide(panel); // hide window + DragAndDropManager.instance.CancelDrag(); + DragAndDropManager.instance.DisableDragBackground(); + } + } + else // we are not the selected machine, or no machine is selected; but not due to user input (probably) + { + if (panel.targetEntity == theMachine) // this machine WAS focused with window open a moment ago, so it should handle closing its own window + { + Hide(panel); // hide window, since we are not focused on this machine anymore + DragAndDropManager.instance.CancelDrag(); + DragAndDropManager.instance.DisableDragBackground(); + } + } + } + catch (Exception ex) + { + return false; + } + + return (panel.targetEntity == theMachine); // true if machine window is currently open, false otherwise (such as if Hide() called) + } + + /// + /// Internal sub function for hiding the panel + /// + /// The working panel + public static void Hide(GenericMachinePanelScript panel) + { + UIManager.RemoveUIRules("Machine"); + panel.currentWindow.OnClose(panel.targetEntity); + panel.Scroll_Bar.GetComponent().scrollValue = 0f; + panel.targetEntity = null; + panel.currentWindow = null; + + GenericMachineManager manager = typeof(GenericMachinePanelScript).GetField("manager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(panel) as GenericMachineManager; + manager.ClearWindow(); + + panel.gameObject.SetActive(false); + panel.Background_Panel.SetActive(false); + } + + /// + /// Insert in machine UnityUpdate to disconnect the UI when finished. + /// + public static void DisconnectUI(SegmentEntity theCaller) + { + if (UIdelay > 5 && UILock && UIUtil.TargetMachine != null && UIUtil.TargetMachine == theCaller) + { + GenericMachinePanelScript panel = GenericMachinePanelScript.instance; + panel.gameObject.SetActive(false); + panel.Background_Panel.SetActive(false); + panel.currentWindow = null; + panel.targetEntity = null; + UIManager.RemoveUIRules("Machine"); + DragAndDropManager.instance.CancelDrag(); + DragAndDropManager.instance.DisableDragBackground(); + GenericMachineManager manager2 = typeof(GenericMachinePanelScript).GetField("manager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(GenericMachinePanelScript.instance) as GenericMachineManager; + manager2.windows.Remove(eSegmentEntity.Mod); + if (manager2.windows.ContainsKey(eSegmentEntity.Mod)) + { + Debug.LogWarning("DisconnectUI was not able to remove the window entry!"); + return; + } + UIUtil.TargetMachine = null; + UILock = false; + } + else if (UIUtil.TargetMachine != null && UIUtil.TargetMachine == theCaller) + UIdelay++; + } + + /// + /// An emergency escape function when looking at the wrong machine (no longer necessary!) + /// + public static void EscapeUI() + { + GenericMachinePanelScript panel = GenericMachinePanelScript.instance; + panel.gameObject.SetActive(false); + panel.Background_Panel.SetActive(false); + panel.currentWindow = null; + panel.targetEntity = null; + GenericMachineManager manager2 = typeof(GenericMachinePanelScript).GetField("manager", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(GenericMachinePanelScript.instance) as GenericMachineManager; + manager2.windows.Remove(eSegmentEntity.Mod); + UIManager.RemoveUIRules("Machine"); + DragAndDropManager.instance.CancelDrag(); + DragAndDropManager.instance.DisableDragBackground(); + } + + + /// + /// Helper class for scaling UI window elements + /// + /// Multiplying factor for the window width + /// Allows manual overriding of the window content offset if required + public static void ScaleUIWindow(float scalingfactorx, float xoffsetoverride = 0) + { + if (!firstopen) + { + float xoffset = 0; + if (scalingfactorx > 0) + xoffset = -140 * scalingfactorx; + if (xoffsetoverride != 0) + xoffset = xoffsetoverride; + StartPos = GenericMachinePanelScript.instance.gameObject.transform.localPosition; + GenericMachinePanelScript.instance.gameObject.transform.localScale = new Vector3(scalingfactorx, 1.0f, 1.0f); + GenericMachinePanelScript.instance.gameObject.transform.localPosition = StartPos + new Vector3(xoffset, 0f, 0f); + GenericMachinePanelScript.instance.Background_Panel.transform.localScale = new Vector3(scalingfactorx, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Label_Holder.transform.localScale = new Vector3(1f / scalingfactorx, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Icon_Holder.transform.localScale = new Vector3(1f / scalingfactorx, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Content_Holder.transform.localScale = new Vector3(1f / scalingfactorx, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Content_Icon_Holder.transform.localScale = new Vector3(1f / scalingfactorx, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Scroll_Bar.transform.localScale = new Vector3(1f / scalingfactorx, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Source_Holder.transform.localScale = new Vector3(1f / scalingfactorx, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Generic_Machine_Title_Label.transform.localScale = new Vector3(1f / scalingfactorx, 1.0f, 1.0f); + + firstopen = true; + } + } + + /// + /// Used in UI window OnClose method to restore default window settings + /// + public static void RestoreUIScale() + { + GenericMachinePanelScript.instance.gameObject.transform.localPosition = StartPos; + GenericMachinePanelScript.instance.gameObject.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Background_Panel.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Label_Holder.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Icon_Holder.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Content_Holder.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Content_Icon_Holder.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Scroll_Bar.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Source_Holder.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + GenericMachinePanelScript.instance.Generic_Machine_Title_Label.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); + firstopen = false; + } + } +} diff --git a/bin/FCECommunityTools.XML b/bin/FCECommunityTools.XML new file mode 100644 index 0000000..076b80b --- /dev/null +++ b/bin/FCECommunityTools.XML @@ -0,0 +1,671 @@ + + + + FCECommunityTools + + + + + A community interface to allow cross-mod communication for item storage + + + + + Checks to see if a Storage Medium has any items + + True if the storage medium has any item, false otherwise + + + + Checks to see if a Storage Medium has the specified item + + Checks for Ore/Item/Cube + + The Item to Check For + True if the storage medium has the specified item, false otherwise + + + + Checks to see if a Storage Medium has the specified item + + Checks for Ore/Item/Cube + + The Item to Check For + Stores the amount of the items available + True if the storage medium has the specified item, false otherwise + + + + Checks to see if a Storage Medium has amount capcity free + + The amount of capcity to check for + True if the storage medium has amount capacity free, otherwise false + + + + Get the free capcity of the entity + + The free capcity of the entity + + + + Attempts to give the Item to a Storage Medium + + The Item to give to a Storage Medium + True if the Storage Medium accepted the item, otherwise false + + + + Attempts to take an Item from a Storage Medium + + The Item to Retrieve + An ItemBase if the requested Item was found, otherwise null + + + + Attempts to take any item from a Storage Medium + + An ItemBase if there's something to return, or null if empty + + + + Extension Methods and Helpers for the ItemBase Class + + + Extension Methods and Helpers for the ItemBase Class + + + + + Gets the amount of items and cubes in any type of Enumerable ItemBase + + The list of items to get the total count from + The amount of Items and Cubes + + + + Gets the amount of items in any type of Enumerable ItemBase + + The list of items to get the total count from + The unique id of the item to count + The amount of Items + + + + Gets the amount of cubes in any type of Enumerable ItemBase + + + + + The amount of Cubes + + + + Gets the amount of cubes OR items from any Enumerable ItemBase, based off of an ItemBase + + The list of items to get the total count from + The ItemBase which to restrain the Count to + The amount of Cubes or Items + + + + Adds an ItemBase to a list, consolidating stacks - obeys list storage capacity by returning excess items + + The item to add to the list + The list to transfer it to + If true returns partial stack when insufficient stack size found + The list's storage capacity + The remaining items that do not fit in the list + + + + Deduct an item from an item list by example + + The example item to attempt to remove from the list + The list to take the item from + If true returns partial stack when insufficient stack size found + The ItemBase object or null if unavailable + + + + Moves specified amount of any items from one list to another obeying target storage capacity. + + Source list of items + Target list of items + Quantity of items to move + Storage capacity of target item list + Moves only the first item found + A list of items to server as a whitelist or blacklist for transferring + True if whitelist otherwise treat as a blacklist + + + + Moves specified amount of any items from one list to another obeying target storage capacity. + + Source item to move + Target list of items + Quantity of items to move (for stacks) + Storage capacity of target item list + Moves only the first item found + A list of items to server as a whitelist or blacklist for transferring + True if whitelist otherwise treat as a blacklist + + + + Compares all possible + + The original ItemBase + The ItemBase to Compare Against + True if all major properties match + + + + Compare the ItemID and Type values of ItemBase + + Original Item + Item to Compare Against + True if ItemID and Type of both Items match, otherwise false + + + + Compares the ItemID, Type, CubeType, and CubeValue values of ItemCubeStack + Does not compare the Amounts + + Original Item + Item to Compare Against + True if ItemID, Type, CubeType, CubeValue of both Items match, otherwise false + + + + Compares the ItemID, Type, CurrentDurability, and MaxDurability values of ItemDurability + + Original Item + Item to Compare Against + True if ItemID, Type, CurrentDurability, and MaxDurability of both Items match, otherwise false + + + + Compares the ItemID and Type values of ItemStack + + Original Item + Item to Compare Against + True if ItemID and Type of both Items match, otherwise false + + + + Compares ItemID and Type values of ItemSingle + + Original Item + Item to Compare Against + True if ItemID and Type of both Items match, otherwise false + + + + Compares ItemID, Type, and ChargeLevel of ItemCharge + + Original Item + Item to Compare Against + True if ItemID, Type and ChargeLevel of both Items match, otherwise false + + + + Compares ItemID, Type, LocationX, LocationY, LocationZ, LookVectorX, LookVectorY amd LookVectoryZ of ItemLocation + + Original Item + Item to Compare Against + + True if ItemID, Type, LocationX, LocationY, LocationZ, LookVectorX, LookVectorY amd LookVectoryZ of both Items + match, otherwise false + + + + + Is the Item original Stack Type + + The Item + True if Item is original Stack, otherwise False + + + + Compares two Items to check if they are both stacks and identical + + The original Item + The item to compare against + True if both Items are stacks and the same + + + + Increases the Stack Size by the specified amount + + The Item Stack + The amount to increment by (Default: 1) + + + + Decrement the Stack Size by the specified amount + + The Item Stack + The amount to increment by (Default: 1) + + + + Set the amount of items in original Item Stack + + The Item Stack + The amount of Items + + + + Creates original new instance of the ItemBase type + + The original to create original new instance of + The new original, or null if unknown type + + + + Gets the amount of items in an ItemBase, while being Stack friendly + + The original + The amount of items + + + + Convert a ItemBase into a class that inherits ItemBase + + Class that Inherits ItemBase + The entity to convert + The entity as + + + + A Float Equals method with tolerance. + Based off of: https://msdn.microsoft.com/en-us/library/ya2zha7s.aspx + + + + + Checks the N/E/S/W/Up/Down directions of the Center block for any SegmentEntitys of T; + Will report whether there was a failure because a segment wasn't loaded. + + The SegmentEntity class to search for. + The MachineEntity to Search Around + Whether or not a Null Segment was Encountered + + + + + Extension Methods and Helpers for the GameObject class + + + + + Stores all of the GameObjects from the Games Resources into a cached object + + + + + Gets a GameObject from the Resources + Originally created by binaryalgorithm & steveman0 + + The Name of the GameObject to retrieve + The named GameObject, or null + + + + Generic machine inventory class with list inventory support + + Origianl code by steveman0 + + + + For associating the machine owner of the inventory + + + + + For associating the mob owner of the inventory + + + + + The total item capacity of the storage + + + + + The list of items in the inventory + + + + + Generic machine inventory class with list inventory support + + For associating the owner machine + The storage capacity of the inventory + + + + Generic machine inventory class with list inventory support + + For associating the owner mob + The storage capacity of the inventory + + + + Add a single item type to the inventory + + The item to add + Amount of items added if given a stack + Returns the remainder that doesn't fit or null if successful + + + + Add items from a source inventory or item list + + The source inventory or list of items + The number of items to transfer + + + + Transfers items to machine inventory if they are on the provided whitelist + + Source inventory or list of items + List of items types allowed in the transfer + Number of items to add + + + + Transfers items to machine inventory if they are on the provided whitelist + + Source inventory or list of items + Item type allowed in the transfer + Number of items to add + + + + Transfers items to machine inventory if they are not on the provided blacklist + + Source inventory or list of items + List of items forbidden from transfer + Number of items to add + + + + Transfers items to machine inventory if they are not on the provided blacklist + + Source inventory or list of items + Item forbidden from transfer + Number of items to add + + + + Fills the inventory to capacity with source items + + Source items to fill the inventory + + + + Fills the inventory to capacity with source items + + Source items to fill the inventory + Item type allowed in the transfer + + + + Fills the inventory to capacity with source items + + Source items to fill the inventory + Item type allowed in the transfer + + + + Fills the inventory to capacity with source items + + Source items to fill the inventory + Item forbidden from transfer + + + + Fills the inventory to capacity with source items + + Source items to fill the inventory + Item forbidden from transfer + + + + Empty the inventory of items + + Target inventory or list + Maximum number of items to take + + + + Return item from inventory by example (obeys stack size) + + Example item to find in inventory + Returns the item or null if unavailable or insufficient stack size + + + + Return item from inventory by example including partial item stack + + Example item to find in inventory + Returns the item or partial stack (null if item not found) + + + + Remove any single item type from the inventory + + Amount to remove (for stacks) + The ItemBase removed from inventory + + + + Remove items from inventory if items are on the whitelist + + The target inventory or list to store the items + The list of items allowed to transfer + Storage capacity of target inventory + Amount of items to move in this transfer + + + + Remove items from inventory if items are on the whitelist + + The target inventory or list to store the items + Item allowed to transfer + Storage capacity of target inventory + Amount of items to move in this transfer + + + + Remove items from inventory if items are not on the blacklist + + The target inventory or list to store the items + The list of items forbidden from transfer + Storage capacity of target inventory + Amount of items to move in this transfer + + + + Remove items from inventory if items are not on the blacklist + + The target inventory or list to store the items + Item forbidden from transfer + Storage capacity of target inventory + Amount of items to move in this transfer + + + + Returns the spare capacity of the inventory + + The spare capacity of the inventory + + + + Returns the current number of items in the inventory + + Current number of items in inventory + + + + Helper logic for checking if the inventory has space + + + + + + Helper logic for checking if the inventory is empty + + + + + + Helper logic for checking if the inventory is full + + + + + + Item drop code for emptying the inventory on the ground on machine delete + + + + + Item drop code for emptying the inventory on the ground on mob delete + + + + + Generic serialization function for writing the inventory to disk + + + + + + Generic serialization function for reading the inventory from disk + + + + + + Extension Methods and Helpers for the SegmentEntity class + + + + + Convert a SegmentEntity into a class that inherit SegmentEntity + + Class that Inherits SegmentEntity + The entity to convert + The entity as TSegmentEntity + + + + Simple cross-mod compatible UI support. Original code by BinaryAlgorithm, updated by steveman0 + + + + + Timer to delay dissociation of UI panel to overcome race condition + + + + + Lock to prevent running the dissociation when it isn't needed + + + + + Associates the machine so that it, and only it, can handle releasing the UI + + + + + Vector for recording default window position for scaled UI + + + + + Used to prevent rescaling the UI after it's already been done + + + + + Call this in GetPopupText to handle your UI Window + + Pass the current machine + The mod window inherited from BaseMachineWindow + + + + + Internal sub function for hiding the panel + + The working panel + + + + Insert in machine UnityUpdate to disconnect the UI when finished. + + + + + An emergency escape function when looking at the wrong machine (no longer necessary!) + + + + + Helper class for scaling UI window elements + + Multiplying factor for the window width + Allows manual overriding of the window content offset if required + + + + Used in UI window OnClose method to restore default window settings + + + + + A class that provides Interopability between Storage and Machines for Pre-StorageInterface mods + + + + + Checks to see if the entity has any items + + A SegmentEntity + True if the entity has any items, false otherwise + + + + + + + + + + + + Will attempt to return the requested item from the entity + + The entity to try and get the item from + The ItemBase with details of what to retrrieve + + + + + Will return any item from the entity + + The entity to get a item from + A item, or NULL + + + + This interface needs to mimic CommunityItemInterface's methods, + but take a SegmentEntity as the first param. + + + + diff --git a/bin/FCECommunityTools.dll b/bin/FCECommunityTools.dll new file mode 100644 index 0000000..3471490 Binary files /dev/null and b/bin/FCECommunityTools.dll differ