diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs index 615423b53..87d29a9e2 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs @@ -327,6 +327,8 @@ namespace Barotrauma debugInteractablesAtCursor.Clear(); debugInteractablesNearCursor.Clear(); + bool draggingItemToWorld = CharacterInventory.DraggingItemToWorld; + //reduce the amount of aim assist if an item has been selected //= can't switch selection to another item without deselecting the current one first UNLESS the cursor is directly on the item //otherwise it would be too easy to accidentally switch the selected item when rewiring items @@ -348,6 +350,15 @@ namespace Barotrauma if (item.body != null && !item.body.Enabled) continue; if (item.ParentInventory != null) continue; if (ignoredItems != null && ignoredItems.Contains(item)) continue; + + if (draggingItemToWorld) + { + if (item.OwnInventory == null || + !item.OwnInventory.CanBePut(CharacterInventory.draggingItem)) + { + continue; + } + } float distanceToItem = float.PositiveInfinity; if (item.IsInsideTrigger(displayPosition, out Rectangle transformedTrigger)) diff --git a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs index fd0af8cf0..a2137e660 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/CharacterHUD.cs @@ -248,7 +248,7 @@ namespace Barotrauma scale: scale); } - if (!GUI.DisableItemHighlights) + if (!GUI.DisableItemHighlights && !Inventory.DraggingItemToWorld) { var hudTexts = focusedItem.GetHUDTexts(character); diff --git a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs index f9e043913..7944ddf9d 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Inventory.cs @@ -301,7 +301,7 @@ namespace Barotrauma protected virtual void ControlInput(Camera cam) { // Note that these targets are static. Therefore the outcome is the same if this method is called multiple times or only once. - if (selectedSlot != null || draggingItem != null) + if (selectedSlot != null && !DraggingItemToWorld) { cam.Freeze = true; } @@ -609,8 +609,17 @@ namespace Barotrauma if (selectedSlot == null) { - draggingItem.Drop(Character.Controlled); - GUI.PlayUISound(GUISoundType.DropItem); + if (DraggingItemToWorld && + Character.Controlled.FocusedItem?.OwnInventory != null && + Character.Controlled.FocusedItem.OwnInventory.TryPutItem(draggingItem, Character.Controlled)) + { + GUI.PlayUISound(GUISoundType.PickItem); + } + else + { + GUI.PlayUISound(GUISoundType.DropItem); + draggingItem.Drop(Character.Controlled); + } } else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem) { @@ -702,10 +711,27 @@ namespace Barotrauma int iconSize = (int)(64 * GUI.Scale); float scale = Math.Min(Math.Min(iconSize / sprite.size.X, iconSize / sprite.size.Y), 1.5f); Vector2 itemPos = PlayerInput.MousePosition; + + if (GUI.MouseOn == null && selectedSlot == null) + { + var shadowSprite = GUI.Style.GetComponentStyle("OuterGlow").Sprites[GUIComponent.ComponentState.None][0]; + string toolTip = Character.Controlled.FocusedItem != null ? + TextManager.Get("PutItemIn").Replace("[itemname]", Character.Controlled.FocusedItem.Name) : + TextManager.Get("DropItem"); + int textWidth = (int)Math.Max(GUI.Font.MeasureString(draggingItem.Name).X, GUI.SmallFont.MeasureString(toolTip).X); + int textSpacing = (int)(15 * GUI.Scale); + Point shadowBorders = (new Point(40, 10)).Multiply(GUI.Scale); + shadowSprite.Draw(spriteBatch, + new Rectangle(itemPos.ToPoint() - new Point(iconSize / 2) - shadowBorders, new Point(iconSize + textWidth + textSpacing, iconSize) + shadowBorders.Multiply(2)), Color.Black * 0.8f); + GUI.DrawString(spriteBatch, new Vector2(itemPos.X + iconSize / 2 + textSpacing, itemPos.Y - iconSize / 2), draggingItem.Name, Color.White); + GUI.DrawString(spriteBatch, new Vector2(itemPos.X + iconSize / 2 + textSpacing, itemPos.Y), toolTip, + color: Character.Controlled.FocusedItem == null ? Color.Red : Color.LightGreen, + font: GUI.SmallFont); + } sprite.Draw(spriteBatch, itemPos + Vector2.One * 2, Color.Black, scale: scale); - sprite.Draw(spriteBatch, - itemPos, - sprite == draggingItem.Sprite ? draggingItem.GetSpriteColor() : draggingItem.GetInventoryIconColor(), + sprite.Draw(spriteBatch, + itemPos, + sprite == draggingItem.Sprite ? draggingItem.GetSpriteColor() : draggingItem.GetInventoryIconColor(), scale: scale); } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs index c45253b0b..adcdb54ac 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -1652,7 +1652,8 @@ namespace Barotrauma #if CLIENT if (isLocalPlayer) { - if (GUI.MouseOn == null && !CharacterInventory.IsMouseOnInventory()) + if (GUI.MouseOn == null && + (!CharacterInventory.IsMouseOnInventory() || CharacterInventory.DraggingItemToWorld)) { if (findFocusedTimer <= 0.0f || Screen.Selected == GameMain.SubEditorScreen) { diff --git a/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs b/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs index f8517fe73..df13f9a00 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/ItemPrefab.cs @@ -851,6 +851,39 @@ namespace Barotrauma AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList(); + if (sprite == null) + { + DebugConsole.ThrowError("Item \"" + Name + "\" has no sprite!"); +#if SERVER + sprite = new Sprite("", Vector2.Zero); + sprite.SourceRect = new Rectangle(0, 0, 32, 32); +#else + sprite = new Sprite(TextureLoader.PlaceHolderTexture, null, null) + { + Origin = TextureLoader.PlaceHolderTexture.Bounds.Size.ToVector2() / 2 + }; +#endif + size = sprite.size; + sprite.EntityID = identifier; + } + + if (!category.HasFlag(MapEntityCategory.Legacy) && string.IsNullOrEmpty(identifier)) + { + DebugConsole.ThrowError( + "Item prefab \"" + name + "\" has no identifier. All item prefabs have a unique identifier string that's used to differentiate between items during saving and loading."); + } + if (!string.IsNullOrEmpty(identifier)) + { + MapEntityPrefab existingPrefab = List.Find(e => e.Identifier == identifier); + if (existingPrefab != null) + { + DebugConsole.ThrowError( + "Map entity prefabs \"" + name + "\" and \"" + existingPrefab.Name + "\" have the same identifier!"); + } + } + + AllowedLinks = element.GetAttributeStringArray("allowedlinks", new string[0], convertToLowerInvariant: true).ToList(); + List.Add(this); }