From d974a5d72f3b35d4982b4eb4069c06466b1cbdf3 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Fri, 29 Mar 2019 17:21:37 +0200 Subject: [PATCH] (3a98135bd) Merge branch 'dev' of https://github.com/Regalis11/Barotrauma-development into dev --- .../Source/Characters/Character.cs | 11 ++ .../Source/Characters/CharacterHUD.cs | 2 +- .../Source/GUI/VideoPlayer.cs | 136 ++++-------------- .../GameModes/Tutorials/ContextualTutorial.cs | 74 +--------- .../Source/Items/Components/LevelResource.cs | 2 +- .../Source/Items/Components/RepairTool.cs | 22 +++ .../Source/Items/Inventory.cs | 38 ++++- .../Source/Characters/Character.cs | 3 +- .../Components/Holdable/LevelResource.cs | 29 +++- .../Items/Components/Holdable/RepairTool.cs | 3 + .../BarotraumaShared/Source/Map/Submarine.cs | 28 +++- 11 files changed, 151 insertions(+), 197 deletions(-) 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/GUI/VideoPlayer.cs b/Barotrauma/BarotraumaClient/Source/GUI/VideoPlayer.cs index 45bb4a52b..8c8733a36 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/VideoPlayer.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/VideoPlayer.cs @@ -2,7 +2,6 @@ using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; using System.Xml.Linq; -using System.Collections.Generic; using Barotrauma.Media; using System.IO; using Microsoft.Xna.Framework.Input; @@ -12,8 +11,8 @@ namespace Barotrauma class VideoPlayer { private Video currentVideo; - private Point resolution; private string filePath; + private bool isPlaying; private GUIFrame background, videoFrame, textFrame; private GUITextBlock title, textContent, objectiveTitle, objectiveText; @@ -22,14 +21,7 @@ namespace Barotrauma private Color backgroundColor = new Color(0f, 0f, 0f, 1f); private Action callbackOnStop; - private bool isPlaying; - - public bool IsPlaying() - { - return isPlaying; - } - - private Point defaultResolution = new Point(936, 540); + private Point scaledResolution; private readonly int borderSize = 20; private readonly Point buttonSize = new Point(160, 50); private readonly int titleHeight = 30; @@ -51,41 +43,35 @@ namespace Barotrauma public struct VideoSettings { public string File; - public int Width; - public int Height; public VideoSettings(XElement element) { File = element.GetAttributeString("file", string.Empty); - Width = 0; - Height = 0; } } - public VideoPlayer() + public VideoPlayer() // GUI elements with size set to Point.Zero are resized based on content { int screenWidth = (int)(GameMain.GraphicsWidth * 0.55f); - defaultResolution = new Point(screenWidth, (int)(screenWidth / 16f * 9f)); + scaledResolution = new Point(screenWidth, (int)(screenWidth / 16f * 9f)); - int width = defaultResolution.X; - int height = defaultResolution.Y; + int width = scaledResolution.X; + int height = scaledResolution.Y; background = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center), "InnerFrame", backgroundColor); - videoFrame = new GUIFrame(new RectTransform(new Point(width + borderSize, height + borderSize), background.RectTransform, Anchor.Center, Pivot.Center) { AbsoluteOffset = new Point((int)(-100 / (GUI.Scale * 0.6f)), 0) }, "SonarFrame"); - //videoFrame.RectTransform.AbsoluteOffset = new Point(-borderSize, 0); + videoFrame = new GUIFrame(new RectTransform(Point.Zero, background.RectTransform, Anchor.Center, Pivot.Center) { AbsoluteOffset = new Point((int)(-100 / (GUI.Scale * 0.6f)), 0) }, "SonarFrame"); - textFrame = new GUIFrame(new RectTransform(new Point(width + borderSize, height + borderSize * 2), videoFrame.RectTransform, Anchor.CenterLeft, Pivot.CenterLeft), "TextFrame"); - textFrame.RectTransform.AbsoluteOffset = new Point(borderSize + videoFrame.Rect.Width, 0); + textFrame = new GUIFrame(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.CenterLeft, Pivot.CenterLeft), "TextFrame"); + textFrame.RectTransform.AbsoluteOffset = new Point(width + borderSize * 2, 0); - videoView = new GUICustomComponent(new RectTransform(new Point(width, height), videoFrame.RectTransform, Anchor.Center), - (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); }); + videoView = new GUICustomComponent(new RectTransform(Point.Zero, videoFrame.RectTransform, Anchor.Center), (spriteBatch, guiCustomComponent) => { DrawVideo(spriteBatch, guiCustomComponent.Rect); }); title = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(5, 10) }, string.Empty, font: GUI.VideoTitleFont, textColor: new Color(253, 174, 0), textAlignment: Alignment.Left); - textContent = new GUITextBlock(new RectTransform(new Vector2(1f, .8f), textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(0, borderSize + titleHeight) }, string.Empty, font: GUI.Font, textAlignment: Alignment.TopLeft); + textContent = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopLeft, Pivot.TopLeft) { AbsoluteOffset = new Point(0, borderSize + titleHeight) }, string.Empty, font: GUI.Font, textAlignment: Alignment.TopLeft); objectiveTitle = new GUITextBlock(new RectTransform(new Vector2(1f, 0f), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight, textColor: Color.White); objectiveTitle.Text = TextManager.Get("NewObjective"); - objectiveText = new GUITextBlock(new RectTransform(new Point(textFrame.Rect.Width, textHeight), textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveNameFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight); + objectiveText = new GUITextBlock(new RectTransform(Point.Zero, textFrame.RectTransform, Anchor.TopCenter, Pivot.TopCenter), string.Empty, font: GUI.ObjectiveNameFont, textColor: new Color(4, 180, 108), textAlignment: Alignment.CenterRight); objectiveTitle.Visible = objectiveText.Visible = false; } @@ -124,16 +110,16 @@ namespace Barotrauma currentVideo.Dispose(); currentVideo = null; - currentVideo = CreateVideo(); + currentVideo = CreateVideo(scaledResolution); } public void AddToGUIUpdateList(bool ignoreChildren = false, int order = 0) { - if (!IsPlaying()) return; + if (!isPlaying) return; background.AddToGUIUpdateList(ignoreChildren, order); } - public void LoadContentWithObjective(string contentPath, VideoSettings videoSettings, TextSettings textSettings, string contentId, bool startPlayback, string objective, Action callback = null) + public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, string contentId, bool startPlayback, string objective = "", Action callback = null) { callbackOnStop = callback; filePath = contentPath + videoSettings.File; @@ -153,19 +139,10 @@ namespace Barotrauma currentVideo = null; } - resolution = new Point(videoSettings.Width, videoSettings.Height); + currentVideo = CreateVideo(scaledResolution); - if (resolution.X == 0 || resolution.Y == 0) - { - resolution = defaultResolution; - } - - currentVideo = CreateVideo(); - - objectiveTitle.Visible = objectiveText.Visible = true; - - videoFrame.RectTransform.NonScaledSize += resolution + new Point(borderSize, borderSize); - videoView.RectTransform.NonScaledSize += resolution; + videoFrame.RectTransform.NonScaledSize += scaledResolution + new Point(borderSize, borderSize); + videoView.RectTransform.NonScaledSize += scaledResolution; title.Text = TextManager.Get(contentId); title.RectTransform.NonScaledSize += new Point(textSettings.Width, titleHeight); @@ -175,79 +152,27 @@ namespace Barotrauma textSettings.Text = ToolBox.WrapText(textSettings.Text, textSettings.Width, GUI.Font); int wrappedHeight = textSettings.Text.Split('\n').Length * textHeight; textFrame.RectTransform.NonScaledSize += new Point(textSettings.Width + borderSize, wrappedHeight + borderSize + buttonSize.Y + titleHeight); - textContent.RectTransform.NonScaledSize = new Point(textSettings.Width, wrappedHeight); + textContent.RectTransform.NonScaledSize += new Point(textSettings.Width, wrappedHeight); } textContent.Text = textSettings.Text; - objectiveTitle.RectTransform.AbsoluteOffset = new Point(-10, textContent.RectTransform.Rect.Height + (int)(textHeight * 1.75f)); - objectiveText.RectTransform.AbsoluteOffset = new Point(-10, textContent.RectTransform.Rect.Height + objectiveTitle.Rect.Height + (int)(textHeight * 2.25f)); - - textFrame.RectTransform.NonScaledSize += new Point(0, objectiveFrameHeight); - objectiveText.RectTransform.NonScaledSize += new Point(textFrame.Rect.Width, textHeight); - objectiveText.Text = objective; - - var okButton = new GUIButton(new RectTransform(buttonSize, textFrame.RectTransform, Anchor.BottomRight, Pivot.BottomRight) { AbsoluteOffset = new Point(20, 20) }, - TextManager.Get("OK")) + if (!string.IsNullOrEmpty(objective)) { - OnClicked = DisposeVideo - }; + objectiveTitle.RectTransform.AbsoluteOffset = new Point(-10, textContent.RectTransform.Rect.Height + (int)(textHeight * 1.95f)); + objectiveText.RectTransform.AbsoluteOffset = new Point(-10, textContent.RectTransform.Rect.Height + objectiveTitle.Rect.Height + (int)(textHeight * 2.25f)); - if (startPlayback) Play(); - } - - public void LoadContent(string contentPath, VideoSettings videoSettings, TextSettings textSettings, string contentId, bool startPlayback, Action callback = null) - { - callbackOnStop = callback; - filePath = contentPath + videoSettings.File; - - if (!File.Exists(filePath)) - { - DebugConsole.ThrowError("No video found at: " + filePath); - DisposeVideo(null, null); - return; + textFrame.RectTransform.NonScaledSize += new Point(0, objectiveFrameHeight); + objectiveText.RectTransform.NonScaledSize += new Point(textFrame.Rect.Width, textHeight); + objectiveText.Text = objective; + objectiveTitle.Visible = objectiveText.Visible = true; } - - ResetFrameSizes(); - - if (currentVideo != null) + else { - currentVideo.Dispose(); - currentVideo = null; + textFrame.RectTransform.NonScaledSize += new Point(0, borderSize); + objectiveTitle.Visible = objectiveText.Visible = false; } - resolution = new Point(0, 0); - - if (currentVideo == null) // No preloaded video found - { - resolution = new Point(videoSettings.Width, videoSettings.Height); - - if (resolution.X == 0 || resolution.Y == 0) - { - resolution = defaultResolution; - } - - currentVideo = CreateVideo(); - } - - objectiveTitle.Visible = objectiveText.Visible = false; - - videoFrame.RectTransform.NonScaledSize += resolution + new Point(borderSize, borderSize); - videoView.RectTransform.NonScaledSize += resolution; - - title.Text = TextManager.Get(contentId); - title.RectTransform.NonScaledSize += new Point(textSettings.Width, titleHeight); - - if (textSettings.Text != string.Empty) - { - textSettings.Text = ToolBox.WrapText(textSettings.Text, textSettings.Width, GUI.Font); - int wrappedHeight = textSettings.Text.Split('\n').Length * textHeight; - textFrame.RectTransform.NonScaledSize += new Point(textSettings.Width + borderSize, wrappedHeight + borderSize + buttonSize.Y + titleHeight); - textContent.RectTransform.NonScaledSize = new Point(textSettings.Width, wrappedHeight); - } - - textContent.Text = textSettings.Text; - var okButton = new GUIButton(new RectTransform(buttonSize, textFrame.RectTransform, Anchor.BottomRight, Pivot.BottomRight) { AbsoluteOffset = new Point(20, 20) }, TextManager.Get("OK")) { @@ -269,13 +194,12 @@ namespace Barotrauma objectiveText.RectTransform.NonScaledSize = Point.Zero; } - private Video CreateVideo() + private Video CreateVideo(Point resolution) { Video video = null; try { - //video = new Video(GameMain.Instance.GraphicsDevice, GameMain.SoundManager, "Content/splashscreen.mp4", 1280, 720); video = new Video(GameMain.Instance.GraphicsDevice, GameMain.SoundManager, filePath, (uint)resolution.X, (uint)resolution.Y); } catch (Exception e) diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/ContextualTutorial.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/ContextualTutorial.cs index 8d44d5ea2..b0c6a86bd 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/ContextualTutorial.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/ContextualTutorial.cs @@ -5,7 +5,6 @@ using Microsoft.Xna.Framework; using Barotrauma.Items.Components; using System.Linq; using Microsoft.Xna.Framework.Input; -using System.Windows; namespace Barotrauma.Tutorials { @@ -42,12 +41,8 @@ namespace Barotrauma.Tutorials private bool disableTutorialOnDeficiencyFound = true; private GUIFrame holderFrame, objectiveFrame; - //private GUIButton toggleButton; - //private bool objectivesOpen = false; - //private float openState = 0f; private List activeObjectives = new List(); private string objectiveTranslated; - //private Point objectiveBaseOffset = Point.Zero; private float floodTutorialTimer = 0.0f; private const float floodTutorialDelay = 2.0f; @@ -113,7 +108,6 @@ namespace Barotrauma.Tutorials base.Initialize(); videoPlayer = new VideoPlayer(); characterTimeOnSonar = new List>(); - //objectivesOpen = true; } public void LoadPartiallyComplete(XElement element) @@ -137,15 +131,6 @@ namespace Barotrauma.Tutorials } } - private void PreloadVideoContent() // Have to see if needed with videos - { - /*for (int i = 0; i < segments.Count; i++) - { - if (segments[i].ContentType != ContentTypes.Video || segments[i].IsTriggered) continue; - spriteSheetPlayer.PreloadContent(playableContentPath, "tutorial", segments[i].Id, segments[i].VideoContent); - }*/ - } - public void SavePartiallyComplete(XElement element) { XElement tutorialElement = new XElement("contextualtutorial"); @@ -177,10 +162,7 @@ namespace Barotrauma.Tutorials { if (!Initialized) return; - PreloadVideoContent(); - base.Start(); - injuredMember = null; activeObjectives.Clear(); objectiveTranslated = TextManager.Get("Objective"); @@ -249,21 +231,6 @@ namespace Barotrauma.Tutorials { holderFrame = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center)); objectiveFrame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ObjectiveAnchor, holderFrame.RectTransform), style: null); - - /*int toggleButtonWidth = (int)(30 * GUI.Scale); - int toggleButtonHeight = (int)(40 * GUI.Scale); - toggleButton = new GUIButton(new RectTransform(new Point(toggleButtonWidth, toggleButtonHeight), objectiveFrame.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(0, 20) }, style: "UIToggleButton"); - toggleButton.OnClicked += (GUIButton btn, object userdata) => - { - objectivesOpen = !objectivesOpen; - foreach (GUIComponent child in btn.Children) - { - child.SpriteEffects = objectivesOpen ? SpriteEffects.FlipHorizontally : SpriteEffects.None; - } - return true; - }; - - objectiveBaseOffset = new Point((int)(-2.5f * toggleButton.Rect.Width), 0);*/ } public override void AddToGUIUpdateList() @@ -311,48 +278,11 @@ namespace Barotrauma.Tutorials { CheckActiveObjectives(activeObjectives[i], deltaTime); } - - /*if (activeObjectives.Count > 0) - { - if (objectivesOpen) - { - openState -= deltaTime * 5.0f; - } - else - { - openState += deltaTime * 5.0f; - } - - openState = MathHelper.Clamp(openState, 0.0f, 1.0f); - - float widestObjective = 0f; - for (int i = 0; i < activeObjectives.Count; i++) - { - if (activeObjectives[i].ReplayButton.Rect.Width > widestObjective) - { - widestObjective = activeObjectives[i].ReplayButton.Rect.Width; - } - } - - float objectivesHiddenOffset = widestObjective + toggleButton.Rect.Width + 100f; - - for (int i = 0; i < activeObjectives.Count; i++) - { - activeObjectives[i].ReplayButton.RectTransform.AbsoluteOffset = objectiveBaseOffset + new Point((int)MathHelper.SmoothStep(0, objectivesHiddenOffset, openState), 0); - } - }*/ } private void ClosePreTextAndTriggerVideoCallback() { - if (!string.IsNullOrEmpty(activeSegment.Objective)) - { - videoPlayer.LoadContentWithObjective(playableContentPath, new VideoPlayer.VideoSettings(activeSegment.VideoContent), new VideoPlayer.TextSettings(activeSegment.VideoContent), activeSegment.Id, true, activeSegment.Objective, CurrentSegmentStopCallback); - } - else - { - videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(activeSegment.VideoContent), new VideoPlayer.TextSettings(activeSegment.VideoContent), activeSegment.Id, true, CurrentSegmentStopCallback); - } + videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(activeSegment.VideoContent), new VideoPlayer.TextSettings(activeSegment.VideoContent), activeSegment.Id, true, activeSegment.Objective, CurrentSegmentStopCallback); } private void CurrentSegmentStopCallback() @@ -804,7 +734,7 @@ namespace Barotrauma.Tutorials { if (ContentRunning) return; ContentRunning = true; - videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, () => ContentRunning = false); + videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, callback: () => ContentRunning = false); } private IEnumerable WaitToStop() diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/LevelResource.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/LevelResource.cs index 8a73e7e2e..b7951ce7d 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/LevelResource.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/LevelResource.cs @@ -7,7 +7,7 @@ namespace Barotrauma.Items.Components { public void ClientRead(ServerNetObject type, NetBuffer msg, float sendingTime) { - DeattachTimer = msg.ReadSingle(); + deattachTimer = msg.ReadSingle(); if (deattachTimer >= DeattachDuration) { holdable.DeattachFromWall(); diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/RepairTool.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/RepairTool.cs index 9b14effac..f8f82df50 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/RepairTool.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/RepairTool.cs @@ -1,6 +1,7 @@ using Barotrauma.Particles; using FarseerPhysics; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using System; using System.Collections.Generic; using System.Linq; @@ -11,12 +12,21 @@ using System.Xml.Linq; namespace Barotrauma.Items.Components { partial class RepairTool +#if DEBUG + : IDrawableComponent +#endif { public ParticleEmitter ParticleEmitter { get; private set; } +#if DEBUG + public Vector2 DrawSize + { + get { return GameMain.DebugDraw ? Vector2.One * Range : Vector2.Zero; } + } +#endif private List ParticleEmitterHitStructure = new List(); private List ParticleEmitterHitCharacter = new List(); @@ -122,5 +132,17 @@ namespace Barotrauma.Items.Components emitter.Second.Emit(deltaTime, particlePos, item.CurrentHull, particleAngle + MathHelper.Pi, -particleAngle + MathHelper.Pi); } } +#if DEBUG + public void Draw(SpriteBatch spriteBatch, bool editing) + { + if (GameMain.DebugDraw && IsActive) + { + GUI.DrawLine(spriteBatch, + new Vector2(debugRayStartPos.X, -debugRayStartPos.Y), + new Vector2(debugRayEndPos.X, -debugRayEndPos.Y), + Color.Yellow); + } + } +#endif } } 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 a3fe980a6..abe389538 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Character.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Character.cs @@ -1656,7 +1656,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/Components/Holdable/LevelResource.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/LevelResource.cs index 458bf0c57..90a7a0665 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/LevelResource.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/LevelResource.cs @@ -2,12 +2,15 @@ using Lidgren.Network; using Microsoft.Xna.Framework; using System; +using System.Linq; using System.Xml.Linq; namespace Barotrauma.Items.Components { partial class LevelResource : ItemComponent, IServerSerializable { + private float lastSentDeattachTimer; + [Serialize(1.0f, false)] public float DeattachDuration { @@ -21,12 +24,29 @@ namespace Barotrauma.Items.Components get { return deattachTimer; } set { - deattachTimer = Math.Max(0.0f, value); //clients don't deattach the item until the server says so (handled in ClientRead) - if ((GameMain.NetworkMember == null || !GameMain.NetworkMember.IsClient) && deattachTimer >= DeattachDuration) + if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient) + { + return; + } + deattachTimer = Math.Max(0.0f, value); +#if SERVER + if (deattachTimer >= DeattachDuration) + { + if (holdable.Attached){ item.CreateServerEvent(this); } + holdable.DeattachFromWall(); + } + else if (Math.Abs(lastSentDeattachTimer - deattachTimer) > 0.1f) + { + item.CreateServerEvent(this); + lastSentDeattachTimer = deattachTimer; + } +#else + if (deattachTimer >= DeattachDuration) { holdable.DeattachFromWall(); } +#endif } } @@ -67,7 +87,10 @@ namespace Barotrauma.Items.Components return; } holdable.Reattachable = false; - holdable.PickingTime = float.MaxValue; + if (requiredItems.Any()) + { + holdable.PickingTime = float.MaxValue; + } var body = item.body ?? holdable.Body; diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs index 5752bb1de..153e694ef 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Holdable/RepairTool.cs @@ -17,6 +17,8 @@ namespace Barotrauma.Items.Components private readonly List fixableEntities; private Vector2 pickedPosition; private float activeTimer; + + private Vector2 debugRayStartPos, debugRayEndPos; [Serialize(0.0f, false)] public float Range { get; set; } @@ -247,6 +249,7 @@ namespace Barotrauma.Items.Components var levelResource = targetItem.GetComponent(); if (levelResource != null && levelResource.IsActive && + levelResource.requiredItems.Any() && levelResource.HasRequiredItems(user, addMessage: false)) { levelResource.DeattachTimer += deltaTime; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 1629b9bff..738c9fa16 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -678,17 +678,24 @@ namespace Barotrauma Body closestBody = null; if (allowInsideFixture) { - var aabb = new FarseerPhysics.Collision.AABB(rayStart - Vector2.UnitY * 0.001f, rayStart + Vector2.UnitY * 0.001f); + var aabb = new FarseerPhysics.Collision.AABB(rayStart - Vector2.One * 0.001f, rayStart + Vector2.One * 0.001f); GameMain.World.QueryAABB((fixture) => { - if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return false; } + if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return true; } + + fixture.Body.GetTransform(out FarseerPhysics.Common.Transform transform); + if (!fixture.Shape.TestPoint(ref transform, ref rayStart)) { return true; } + closestFraction = 0.0f; closestNormal = Vector2.Normalize(rayEnd - rayStart); if (fixture.Body != null) closestBody = fixture.Body; - return true; + return false; }, ref aabb); if (closestFraction <= 0.0f) { + lastPickedPosition = rayStart; + lastPickedFraction = closestFraction; + lastPickedNormal = closestNormal; return closestBody; } } @@ -740,14 +747,21 @@ namespace Barotrauma if (allowInsideFixture) { - var aabb = new FarseerPhysics.Collision.AABB(rayStart - Vector2.UnitY * 0.001f, rayStart + Vector2.UnitY * 0.001f); + var aabb = new FarseerPhysics.Collision.AABB(rayStart - Vector2.One * 0.001f, rayStart + Vector2.One * 0.001f); GameMain.World.QueryAABB((fixture) => { - if (bodies.Contains(fixture.Body) || fixture.Body == null) { return false; } - if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return false; } + if (bodies.Contains(fixture.Body) || fixture.Body == null) { return true; } + if (!CheckFixtureCollision(fixture, ignoredBodies, collisionCategory, ignoreSensors, customPredicate)) { return true; } + + fixture.Body.GetTransform(out FarseerPhysics.Common.Transform transform); + if (!fixture.Shape.TestPoint(ref transform, ref rayStart)) { return true; } + closestFraction = 0.0f; + lastPickedPosition = rayStart; + lastPickedFraction = 0.0f; + lastPickedNormal = Vector2.Normalize(rayEnd - rayStart); bodies.Add(fixture.Body); - return true; + return false; }, ref aabb); }