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); } } } } }
public void SetupDialog() { ItemSlot hoveredSlot = capi.World.Player.InventoryManager.CurrentHoveredSlot; if (hoveredSlot != null && hoveredSlot.Inventory == Inventory) { capi.Input.TriggerOnMouseLeaveSlot(hoveredSlot); } else { hoveredSlot = null; } ElementBounds quernBounds = ElementBounds.Fixed(0, 0, 400, 400); // 2. Around all that is 10 pixel padding ElementBounds bgBounds = ElementBounds.Fill.WithFixedPadding(GuiStyle.ElementToDialogPadding); bgBounds.BothSizing = ElementSizing.FitToChildren; bgBounds.WithChildren(quernBounds); // 3. Finally Dialog ElementBounds dialogBounds = ElementStdBounds.AutosizedMainDialog.WithAlignment(EnumDialogArea.CenterMiddle) .WithFixedAlignmentOffset(-GuiStyle.DialogToScreenPadding, 0); ClearComposers(); SingleComposer = capi.Gui .CreateCompo("BlockEntityTinkerTable" + BlockEntityPosition, dialogBounds) .AddShadedDialogBG(bgBounds) .AddDialogTitleBar(DialogTitle, OnTitleBarClose) .BeginChildElements(bgBounds) .AddItemSlotGrid(Inventory, SendInvPacket, 1, new int[] { 0 }, ElementStdBounds.SlotGrid(EnumDialogArea.CenterMiddle, 0, 0, 1, 1), "targetSlot") ; IModularItem item = Inventory[0].Itemstack?.Item as IModularItem; SlotDefinition[] slotdefs = item?.TinkerProps?.AvailableSlots; if (item != null && slotdefs != null) { var slots = item.GetSlots(Inventory[0].Itemstack); for (int i = 0; i < slotdefs.Length && i < Inventory.Count - 1; ++i) { var slotdef = slotdefs[i]; ItemStack stack = slots[slotdef.SlotName]; int invslot = i + 1; if (stack == null) { stack = Inventory[invslot].Itemstack; } Inventory[invslot].Itemstack = stack; SingleComposer = SingleComposer.AddItemSlotGrid(Inventory, SendInvPacket, 1, new int[] { invslot }, ElementStdBounds.SlotGrid(EnumDialogArea.CenterMiddle, slotdef.OffsetX, slotdef.OffsetY, 1, 1), "partSlot" + invslot.ToString()); } } else if (Inventory[0].Itemstack?.Item == null && Inventory.Count >= 4) { SingleComposer = SingleComposer .AddItemSlotGrid(Inventory, SendInvPacket, 1, new int[] { 1 }, ElementStdBounds.SlotGrid(EnumDialogArea.CenterMiddle, 0, -90.0, 1, 1), "partSlot1"); SingleComposer = SingleComposer .AddItemSlotGrid(Inventory, SendInvPacket, 1, new int[] { 3 }, ElementStdBounds.SlotGrid(EnumDialogArea.CenterMiddle, 0, 90.0, 1, 1), "partSlot2"); } SingleComposer = SingleComposer.Compose(); if (hoveredSlot != null) { SingleComposer.OnMouseMove(new MouseEvent(capi.Input.MouseX, capi.Input.MouseY)); } }