public void DrawOwn(SpriteBatch spriteBatch) { if (!AccessibleWhenAlive && !character.IsDead) { return; } if (slots == null) { CreateSlots(); } if (GameMain.GraphicsWidth != screenResolution.X || GameMain.GraphicsHeight != screenResolution.Y || prevUIScale != UIScale || prevHUDScale != GUI.Scale) { SetSlotPositions(layout); prevUIScale = UIScale; prevHUDScale = GUI.Scale; } if (layout == Layout.Center) { CalculateBackgroundFrame(); GUI.DrawRectangle(spriteBatch, BackgroundFrame, Color.Black * 0.8f, true); GUI.DrawString(spriteBatch, new Vector2((int)(BackgroundFrame.Center.X - GUI.Font.MeasureString(character.Name).X / 2), (int)BackgroundFrame.Y + 5), character.Name, Color.White * 0.9f); } base.Draw(spriteBatch); if (hideButton != null && hideButton.Visible && !Locked) { hideButton.DrawManually(spriteBatch, alsoChildren: true); } InventorySlot highlightedQuickUseSlot = null; for (int i = 0; i < capacity; i++) { if (HideSlot(i)) { continue; } if (Items[i] == null || (draggingItem == Items[i] && !slots[i].InteractRect.Contains(PlayerInput.MousePosition)) || !Items[i].AllowedSlots.Any(a => a != InvSlotType.Any)) { //draw limb icons on empty slots if (limbSlotIcons.ContainsKey(SlotTypes[i])) { var icon = limbSlotIcons[SlotTypes[i]]; icon.Draw(spriteBatch, slots[i].Rect.Center.ToVector2() + slots[i].DrawOffset, Color.White * 0.3f, origin: icon.size / 2, scale: slots[i].Rect.Width / icon.size.X); } continue; } if (draggingItem == Items[i] && !slots[i].IsHighlighted) { continue; } //draw hand icons if the item is equipped in a hand slot if (IsInLimbSlot(Items[i], InvSlotType.LeftHand)) { var icon = limbSlotIcons[InvSlotType.LeftHand]; icon.Draw(spriteBatch, new Vector2(slots[i].Rect.X, slots[i].Rect.Bottom) + slots[i].DrawOffset, Color.White * 0.6f, origin: new Vector2(icon.size.X * 0.35f, icon.size.Y * 0.75f), scale: slots[i].Rect.Width / icon.size.X * 0.7f); } if (IsInLimbSlot(Items[i], InvSlotType.RightHand)) { var icon = limbSlotIcons[InvSlotType.RightHand]; icon.Draw(spriteBatch, new Vector2(slots[i].Rect.Right, slots[i].Rect.Bottom) + slots[i].DrawOffset, Color.White * 0.6f, origin: new Vector2(icon.size.X * 0.65f, icon.size.Y * 0.75f), scale: slots[i].Rect.Width / icon.size.X * 0.7f); } Color color = slots[i].EquipButtonState == GUIComponent.ComponentState.Pressed ? Color.Gray : Color.White * 0.8f; if (slots[i].EquipButtonState == GUIComponent.ComponentState.Hover) { color = Color.White; highlightedQuickUseSlot = slots[i]; } if (Locked) { color *= 0.3f; } var quickUseIndicator = Items[i].AllowedSlots.Any(a => a == InvSlotType.Any) ? EquipIndicator : DropIndicator; var quickUseHighlight = Items[i].AllowedSlots.Any(a => a == InvSlotType.Any) ? EquipIndicatorHighlight : DropIndicatorHighlight; quickUseIndicator.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color, quickUseIndicator.Origin, 0, UIScale); slots[i].QuickUseTimer = Math.Min(slots[i].QuickUseTimer, 1.0f); if (slots[i].QuickUseTimer > 0.0f) { float indicatorFillAmount = character.HasEquippedItem(Items[i]) ? 1.0f - slots[i].QuickUseTimer : slots[i].QuickUseTimer; quickUseHighlight.DrawTiled(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2() - quickUseHighlight.Origin * UIScale * 0.85f, new Vector2(quickUseIndicator.SourceRect.Width * indicatorFillAmount, quickUseIndicator.SourceRect.Height) * UIScale * 0.85f, null, color * 0.9f, null, Vector2.One * UIScale * 0.85f); } else if (character.HasEquippedItem(Items[i])) { quickUseHighlight.Draw(spriteBatch, slots[i].EquipButtonRect.Center.ToVector2(), color * 0.9f, quickUseHighlight.Origin, 0, UIScale * 0.85f); } } if (highlightedQuickUseSlot != null && !string.IsNullOrEmpty(highlightedQuickUseSlot.QuickUseButtonToolTip)) { GUIComponent.DrawToolTip(spriteBatch, highlightedQuickUseSlot.QuickUseButtonToolTip, highlightedQuickUseSlot.EquipButtonRect); } }
public override void CreateSlots() { if (slots == null) { slots = new InventorySlot[capacity]; } for (int i = 0; i < capacity; i++) { InventorySlot prevSlot = slots[i]; Sprite slotSprite = slotSpriteSmall; Rectangle slotRect = new Rectangle( (int)(SlotPositions[i].X), (int)(SlotPositions[i].Y), (int)(slotSprite.size.X * UIScale), (int)(slotSprite.size.Y * UIScale)); if (Items[i] != null) { ItemContainer itemContainer = Items[i].GetComponent <ItemContainer>(); if (itemContainer != null) { if (itemContainer.InventoryTopSprite != null) { slotRect.Width = Math.Max(slotRect.Width, (int)(itemContainer.InventoryTopSprite.size.X * UIScale)); } if (itemContainer.InventoryBottomSprite != null) { slotRect.Width = Math.Max(slotRect.Width, (int)(itemContainer.InventoryBottomSprite.size.X * UIScale)); } } } slots[i] = new InventorySlot(slotRect) { SubInventoryDir = Math.Sign(HUDLayoutSettings.InventoryAreaUpper.Bottom - slotRect.Center.Y), Disabled = false, SlotSprite = slotSprite, Color = SlotTypes[i] == InvSlotType.Any ? Color.White * 0.2f : Color.White * 0.4f }; if (prevSlot != null) { slots[i].DrawOffset = prevSlot.DrawOffset; slots[i].Color = prevSlot.Color; } if (selectedSlot?.ParentInventory == this && selectedSlot.SlotIndex == i) { selectedSlot = new SlotReference(this, slots[i], i, selectedSlot.IsSubSlot, selectedSlot.Inventory); } } AssignQuickUseNumKeys(); highlightedSubInventorySlots.RemoveWhere(s => s.Inventory.OpenState <= 0.0f); foreach (var subSlot in highlightedSubInventorySlots) { if (subSlot.ParentInventory == this && subSlot.SlotIndex > 0 && subSlot.SlotIndex < slots.Length) { subSlot.Slot = slots[subSlot.SlotIndex]; } } screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); CalculateBackgroundFrame(); }
protected void UpdateSlot(InventorySlot slot, int slotIndex, Item item, bool isSubSlot) { bool mouseOn = slot.InteractRect.Contains(PlayerInput.MousePosition) && !Locked; slot.State = GUIComponent.ComponentState.None; if (!(this is CharacterInventory) && !mouseOn && selectedSlot == slotIndex) { selectedSlot = -1; } if (mouseOn && (draggingItem != null || selectedSlot == slotIndex || selectedSlot == -1)) { slot.State = GUIComponent.ComponentState.Hover; if (!isSubSlot && selectedSlot == -1) { selectedSlot = slotIndex; } if (draggingItem == null) { if (PlayerInput.LeftButtonHeld()) { draggingItem = Items[slotIndex]; draggingSlot = slot; } } else if (PlayerInput.LeftButtonReleased()) { if (PlayerInput.DoubleClicked()) { doubleClickedItem = item; } if (draggingItem != Items[slotIndex]) { //selectedSlot = slotIndex; if (TryPutItem(draggingItem, slotIndex, true, Character.Controlled)) { if (slots != null) { slots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f); } GUI.PlayUISound(GUISoundType.PickItem); } else { if (slots != null) { slots[slotIndex].ShowBorderHighlight(Color.Red, 0.1f, 0.9f); } GUI.PlayUISound(GUISoundType.PickItemFail); } draggingItem = null; draggingSlot = null; } } } }
public static void DrawSlot(SpriteBatch spriteBatch, Inventory inventory, InventorySlot slot, Item item, bool drawItem = true) { Rectangle rect = slot.Rect; rect.Location += slot.DrawOffset.ToPoint(); if (slot.HighlightColor.A > 0) { float scaleUpAmount = 0.5f; float inflateAmount = (slot.HighlightColor.A / 255.0f) * scaleUpAmount * 0.5f; rect.Inflate(rect.Width * inflateAmount, rect.Height * inflateAmount); } var itemContainer = item?.GetComponent <ItemContainer>(); if (itemContainer != null && (itemContainer.InventoryTopSprite != null || itemContainer.InventoryBottomSprite != null)) { if (!highlightedSubInventorySlots.Any(s => s.Slot == slot)) { itemContainer.InventoryBottomSprite?.Draw(spriteBatch, new Vector2(rect.Center.X, rect.Y), 0, UIScale); itemContainer.InventoryTopSprite?.Draw(spriteBatch, new Vector2(rect.Center.X, rect.Y), 0, UIScale); } drawItem = false; } else { Sprite slotSprite = slot.SlotSprite ?? slotSpriteSmall; spriteBatch.Draw(slotSprite.Texture, rect, slotSprite.SourceRect, slot.IsHighlighted ? Color.White : Color.White * 0.8f); if (item != null && drawItem) { if (item.Condition < item.Prefab.Health && (itemContainer == null || !itemContainer.ShowConditionInContainedStateIndicator)) { GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Bottom - 8, rect.Width, 8), Color.Black * 0.8f, true); GUI.DrawRectangle(spriteBatch, new Rectangle(rect.X, rect.Bottom - 8, (int)(rect.Width * item.Condition / item.Prefab.Health), 8), Color.Lerp(Color.Red, Color.Green, item.Condition / 100.0f) * 0.8f, true); } if (itemContainer != null) { float containedState = 0.0f; if (itemContainer.ShowConditionInContainedStateIndicator) { containedState = item.Condition / 100.0f; } else { containedState = itemContainer.Inventory.Capacity == 1 ? (itemContainer.Inventory.Items[0] == null ? 0.0f : itemContainer.Inventory.Items[0].Condition / 100.0f) : itemContainer.Inventory.Items.Count(i => i != null) / (float)itemContainer.Inventory.capacity; } int dir = slot.SubInventoryDir; Rectangle containedIndicatorArea = new Rectangle(rect.X, dir < 0 ? rect.Bottom + HUDLayoutSettings.Padding / 2 : rect.Y - HUDLayoutSettings.Padding / 2 - ContainedIndicatorHeight, rect.Width, ContainedIndicatorHeight); containedIndicatorArea.Inflate(-4, 0); if (itemContainer.ContainedStateIndicator?.Texture == null) { containedIndicatorArea.Inflate(0, -2); GUI.DrawRectangle(spriteBatch, containedIndicatorArea, Color.DarkGray * 0.8f, true); GUI.DrawRectangle(spriteBatch, new Rectangle(containedIndicatorArea.X, containedIndicatorArea.Y, (int)(containedIndicatorArea.Width * containedState), containedIndicatorArea.Height), Color.Lerp(Color.Red, Color.Green, containedState) * 0.8f, true); } else { Sprite indicatorSprite = itemContainer.ContainedStateIndicator; float indicatorScale = Math.Min( containedIndicatorArea.Width / (float)indicatorSprite.SourceRect.Width, containedIndicatorArea.Height / (float)indicatorSprite.SourceRect.Height); if (containedState > 0.0f && containedState < 0.25f) { indicatorScale += ((float)Math.Sin(Timing.TotalTime * 5.0f) + 1.0f) * 0.1f; } indicatorSprite.Draw(spriteBatch, containedIndicatorArea.Center.ToVector2(), Color.DarkGray * 0.6f, origin: indicatorSprite.size / 2, rotate: 0.0f, scale: indicatorScale); spriteBatch.Draw(indicatorSprite.Texture, containedIndicatorArea.Center.ToVector2(), sourceRectangle: new Rectangle(indicatorSprite.SourceRect.Location, new Point((int)(indicatorSprite.SourceRect.Width * containedState), indicatorSprite.SourceRect.Height)), color: ToolBox.GradientLerp(containedState, Color.Red, Color.Orange, Color.Green), rotation: 0.0f, origin: indicatorSprite.size / 2, scale: indicatorScale, effects: SpriteEffects.None, layerDepth: 0.0f); } } } } if (GameMain.DebugDraw) { GUI.DrawRectangle(spriteBatch, rect, Color.White, false, 0, 1); GUI.DrawRectangle(spriteBatch, slot.EquipButtonRect, Color.White, false, 0, 1); } if (slot.HighlightColor != Color.Transparent) { GUI.UIGlow.Draw(spriteBatch, rect, slot.HighlightColor); } if (item != null && drawItem) { Sprite sprite = item.Prefab.InventoryIcon ?? item.Sprite; float scale = Math.Min(Math.Min((rect.Width - 10) / sprite.size.X, (rect.Height - 10) / sprite.size.Y), 3.0f); Vector2 itemPos = rect.Center.ToVector2(); if (itemPos.Y > GameMain.GraphicsHeight) { itemPos.Y -= Math.Min( (itemPos.Y + sprite.size.Y / 2 * scale) - GameMain.GraphicsHeight, (itemPos.Y - sprite.size.Y / 2 * scale) - rect.Y); } float rotation = 0.0f; if (slot.HighlightColor.A > 0) { rotation = (float)Math.Sin(slot.HighlightTimer * MathHelper.TwoPi) * slot.HighlightTimer * 0.3f; } Color spriteColor = sprite == item.Sprite ? item.GetSpriteColor() : item.GetInventoryIconColor(); if (CharacterHealth.OpenHealthWindow != null && !item.UseInHealthInterface) { spriteColor = Color.Lerp(spriteColor, Color.TransparentBlack, 0.5f); } else { sprite.Draw(spriteBatch, itemPos + Vector2.One * 2, Color.Black * 0.6f, rotate: rotation, scale: scale); } sprite.Draw(spriteBatch, itemPos, spriteColor, rotation, scale); if (CharacterHealth.OpenHealthWindow != null) { float treatmentSuitability = CharacterHealth.OpenHealthWindow.GetTreatmentSuitability(item); float skill = Character.Controlled.GetSkillLevel("medical"); if (skill > 50.0f) { Rectangle highlightRect = rect; highlightRect.Inflate(3, 3); Color color = treatmentSuitability < 0.0f ? Color.Lerp(Color.Transparent, Color.Red, -treatmentSuitability) : Color.Lerp(Color.Transparent, Color.Green, treatmentSuitability); GUI.DrawRectangle(spriteBatch, highlightRect, color * (((float)Math.Sin(Timing.TotalTime * 5.0f) + 1.0f) / 2.0f), false, 0, 5); } } } if (inventory != null && Character.Controlled?.Inventory == inventory && slot.QuickUseKey != Keys.None) { GUI.DrawString(spriteBatch, rect.Location.ToVector2(), slot.QuickUseKey.ToString().Substring(1, 1), item == null || !drawItem ? Color.Gray : Color.White, Color.Black * 0.8f); } }
public static void UpdateDragging() { if (draggingItem != null && PlayerInput.LeftButtonReleased()) { if (CharacterHealth.OpenHealthWindow != null && CharacterHealth.OpenHealthWindow.OnItemDropped(draggingItem, false)) { draggingItem = null; return; } if (selectedSlot == null) { draggingItem.ParentInventory?.CreateNetworkEvent(); draggingItem.Drop(); GUI.PlayUISound(GUISoundType.DropItem); } else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem) { Inventory selectedInventory = selectedSlot.ParentInventory; int slotIndex = selectedSlot.SlotIndex; if (selectedInventory.TryPutItem(draggingItem, slotIndex, true, true, Character.Controlled)) { if (selectedInventory.slots != null) { selectedInventory.slots[slotIndex].ShowBorderHighlight(Color.White, 0.1f, 0.4f); } GUI.PlayUISound(GUISoundType.PickItem); } else { if (selectedInventory.slots != null) { selectedInventory.slots[slotIndex].ShowBorderHighlight(Color.Red, 0.1f, 0.9f); } GUI.PlayUISound(GUISoundType.PickItemFail); } selectedInventory.HideTimer = 1.0f; if (selectedSlot.ParentInventory?.Owner is Item parentItem && parentItem.ParentInventory != null) { for (int i = 0; i < parentItem.ParentInventory.capacity; i++) { if (parentItem.ParentInventory.HideSlot(i)) { continue; } if (parentItem.ParentInventory.Items[i] != parentItem) { continue; } highlightedSubInventorySlots.Add(new SlotReference( parentItem.ParentInventory, parentItem.ParentInventory.slots[i], i, false, selectedSlot.ParentInventory)); break; } } draggingItem = null; draggingSlot = null; } draggingItem = null; } if (selectedSlot != null && !selectedSlot.Slot.MouseOn()) { selectedSlot = null; } }
protected void UpdateSlot(InventorySlot slot, int slotIndex, Item item, bool isSubSlot) { Rectangle interactRect = slot.InteractRect; interactRect.Location += slot.DrawOffset.ToPoint(); bool mouseOnGUI = false; if (GUI.MouseOn != null) { //block usage if the mouse is on a GUIComponent that's not related to this inventory if (RectTransform == null || (RectTransform != GUI.MouseOn.RectTransform && !GUI.MouseOn.IsParentOf(RectTransform.GUIComponent))) { mouseOnGUI = true; } } bool mouseOn = interactRect.Contains(PlayerInput.MousePosition) && !Locked && !mouseOnGUI; if (selectedSlot != null && selectedSlot.Slot != slot) { //subinventory slot highlighted -> don't allow highlighting this one if (selectedSlot.IsSubSlot && !isSubSlot) { mouseOn = false; } else if (!selectedSlot.IsSubSlot && isSubSlot && mouseOn) { selectedSlot = null; } } slot.State = GUIComponent.ComponentState.None; if (mouseOn && (draggingItem != null || selectedSlot == null || selectedSlot.Slot == slot)) // && //(highlightedSubInventories.Count == 0 || highlightedSubInventories.Contains(this) || highlightedSubInventorySlot?.Slot == slot || highlightedSubInventory.Owner == item)) { slot.State = GUIComponent.ComponentState.Hover; if (selectedSlot == null || (!selectedSlot.IsSubSlot && isSubSlot)) { selectedSlot = new SlotReference(this, slot, slotIndex, isSubSlot, Items[slotIndex]?.GetComponent <ItemContainer>()?.Inventory); } if (draggingItem == null) { if (PlayerInput.LeftButtonHeld()) { draggingItem = Items[slotIndex]; draggingSlot = slot; } } else if (PlayerInput.LeftButtonReleased()) { if (PlayerInput.DoubleClicked()) { doubleClickedItem = item; } } } }
public virtual void CreateSlots() { slots = new InventorySlot[capacity]; int rows = (int)Math.Ceiling((double)capacity / slotsPerRow); int columns = Math.Min(slotsPerRow, capacity); Vector2 spacing = new Vector2(10 * UIScale, (10 + EquipIndicator.size.Y) * UIScale); Vector2 rectSize = new Vector2(60.0f * UIScale); //y is larger to give more space for the header padding = new Vector4(spacing.X, 40 * UIScale, spacing.X, spacing.X); Vector2 slotAreaSize = new Vector2( columns * rectSize.X + (columns - 1) * spacing.X, rows * rectSize.Y + (rows - 1) * spacing.Y); slotAreaSize.X += padding.X + padding.Z; slotAreaSize.Y += padding.Y + padding.W; Vector2 topLeft = new Vector2( GameMain.GraphicsWidth / 2 - slotAreaSize.X / 2, GameMain.GraphicsHeight / 2 - slotAreaSize.Y / 2); if (RectTransform != null) { Vector2 scale = new Vector2( RectTransform.Rect.Width / slotAreaSize.X, RectTransform.Rect.Height / slotAreaSize.Y); spacing *= scale; rectSize *= scale; padding.X *= scale.X; padding.Z *= scale.X; padding.Y *= scale.Y; padding.W *= scale.Y; topLeft = RectTransform.TopLeft.ToVector2() + new Vector2(padding.X, padding.Y); prevRect = RectTransform.Rect; } Rectangle slotRect = new Rectangle((int)topLeft.X, (int)topLeft.Y, (int)rectSize.X, (int)rectSize.Y); for (int i = 0; i < capacity; i++) { slotRect.X = (int)(topLeft.X + (rectSize.X + spacing.X) * (i % slotsPerRow)); slotRect.Y = (int)(topLeft.Y + (rectSize.Y + spacing.Y) * ((int)Math.Floor((double)i / slotsPerRow))); slots[i] = new InventorySlot(slotRect); slots[i].InteractRect = new Rectangle( (int)(slots[i].Rect.X - spacing.X / 2 - 1), (int)(slots[i].Rect.Y - spacing.Y / 2 - 1), (int)(slots[i].Rect.Width + spacing.X + 2), (int)(slots[i].Rect.Height + spacing.Y + 2)); if (slots[i].Rect.Width > slots[i].Rect.Height) { slots[i].Rect.Inflate((slots[i].Rect.Height - slots[i].Rect.Width) / 2, 0); } else { slots[i].Rect.Inflate(0, (slots[i].Rect.Width - slots[i].Rect.Height) / 2); } } if (selectedSlot != null && selectedSlot.ParentInventory == this) { selectedSlot = new SlotReference(this, slots[selectedSlot.SlotIndex], selectedSlot.SlotIndex, selectedSlot.IsSubSlot, selectedSlot.Inventory); } CalculateBackgroundFrame(); }