private void OnSlotModified(int slot) { if (Api.Side == EnumAppSide.Server) { bool dirty = false; if (slot == 0) { if (Inventory[0].Itemstack == null) { DropInvalidParts(); inventory.Resize(4); dirty = true; } else if (Inventory[0].Itemstack != null) { // Drop any items that are not ToolPart into the world DropInvalidParts(); IModularItem item = Inventory[0].Itemstack?.Item as IModularItem; if (item != null) { // Fill part slots SlotDefinition[] slotdefs = item.TinkerProps.AvailableSlots; if (slotdefs != null) { inventory.Resize(slotdefs.Length + 1); var slots = item.GetSlots(Inventory[0].Itemstack); for (int i = 0; i < slotdefs.Length; ++i) { var toolpart = slots[slotdefs[i].SlotName]; Inventory[i + 1].Itemstack = toolpart; } } else { DropParts(); inventory.Resize(1); } } else { // Not a valid IModularItem, so no slots DropParts(); inventory.Resize(1); } dirty = true; } } else { if (Inventory[0].Itemstack != null) { int partindex = slot - 1; IModularItem item = Inventory[0].Itemstack.Item as IModularItem; SlotDefinition[] slotdefs = item.TinkerProps.AvailableSlots; // Only apply the part if it inside the number of available slots if (partindex < slotdefs?.Length) { SlotDefinition slotdef = slotdefs[partindex]; item.RemovePart(Inventory[0].Itemstack, slotdef.SlotName); ToolPart part = Inventory[slot].Itemstack?.Item as ToolPart; if (part != null) { item.AddPart(Inventory[0].Itemstack, slotdef.SlotName, Inventory[slot].Itemstack); } } if (!item.HasNeededParts(Inventory[0].Itemstack)) { DropOptionalParts(); Inventory[0].Itemstack = null; } } else { ToolPart toolhead = Inventory[1].Itemstack?.Item as ToolPart; ToolPart handle = Inventory[3].Itemstack?.Item as ToolPart; if (toolhead != null && handle != null && toolhead.TinkerProps.ResultItem != null) { IModularTool result = Api.World.GetItem(new AssetLocation(toolhead.TinkerProps.ResultItem)) as IModularTool; if (result != null) { Inventory[0].Itemstack = new ItemStack(result as Item, 1); if (!(result.AddPart(Inventory[0].Itemstack, "toolhead", Inventory[1].Itemstack) && result.AddPart(Inventory[0].Itemstack, "handle", Inventory[3].Itemstack))) { Inventory[0].Itemstack = null; } } } } dirty = true; } if (lastStack?.Item == null || lastStack.Item is IModularItem) { lastStack = Inventory[0].Itemstack; } // Resend the inventory if needed if (dirty) { byte[] data; using (MemoryStream ms = new MemoryStream()) { BinaryWriter writer = new BinaryWriter(ms); TreeAttribute tree = new TreeAttribute(); inventory.ToTreeAttributes(tree); tree.ToBytes(writer); data = ms.ToArray(); } foreach (string guid in Inventory.openedByPlayerGUIds) { IServerPlayer player = Api.World.PlayerByUid(guid) as IServerPlayer; // Make sure that only online players recieve the update if (player.ConnectionState != EnumClientState.Offline) { UpdateInventory(player, data); } } } } }