(2402e736e) Tester's build, January 25th 2020

This commit is contained in:
Joonas Rikkonen
2020-01-25 12:48:13 +02:00
parent 4a58987eae
commit eaa18a20a3
57 changed files with 710 additions and 139 deletions
@@ -176,6 +176,8 @@ namespace Barotrauma
healthBar = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
barSize: 1.0f, color: Color.Green, style: horizontal ? "GUIProgressBar" : "GUIProgressBarVertical")
{
Enabled = true,
HoverCursor = CursorState.Hand,
IsHorizontal = horizontal
};
healthBarShadow = new GUIProgressBar(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.HealthBarAreaLeft, GUI.Canvas),
@@ -26,17 +26,14 @@ namespace Barotrauma
/// <seealso cref="NetLobbyScreen.Select"/> where I'm utilizing this
private readonly List<GUITextBox> registers = new List<GUITextBox>();
private readonly bool skipDuplicate;
// Selector index
private int index;
// Local changes we've made into previously stored messages
private string[] localChanges;
public ChatManager(bool skipDuplicate, bool loop, short maxCount)
public ChatManager(bool loop, short maxCount)
{
this.skipDuplicate = skipDuplicate;
this.loop = loop;
this.maxCount = maxCount;
localChanges = new string[maxCount];
@@ -87,13 +84,10 @@ namespace Barotrauma
public void Store(string message)
{
Clear();
string strip = StripMessage(message);
var strip = StripMessage(message);
if (string.IsNullOrWhiteSpace(strip)) { return; }
if (skipDuplicate && messageList.Any(p => message == p))
{
return;
}
if (messageList.Count > 1 && messageList[1] == message) { return; }
// insert to the second position as the first position is reserved for the original message if any
messageList.Insert(1, message);
@@ -104,7 +98,7 @@ namespace Barotrauma
}
// [It's also possible to lambdas too in short methods, if you like: string StripMessage(string text) => ChatMessage.GetChatMessageCommand(text, out string msg);]
string StripMessage(string text)
static string StripMessage(string text)
{
ChatMessage.GetChatMessageCommand(text, out string msg);
return msg;
@@ -129,40 +123,61 @@ namespace Barotrauma
/// <returns>A message or null</returns>
private string SelectMessage(Direction direction, string original)
{
if (direction == Direction.Other) { return null; }
// temporarily save our changes in case we fat-finger and want to go back
localChanges[index] = original;
int dir = (int) direction;
int nextIndex = (index + dir);
if (loop && messageList.Count > 1)
var originalIndex = index;
while (true)
{
nextIndex = LoopAround(nextIndex);
}
else
{
if (nextIndex > messageList.Count - 1)
if (direction == Direction.Other)
{
return null;
}
}
return nextIndex < 0 ? localChanges.FirstOrDefault() : EntryAt(index = nextIndex);
string EntryAt(int i)
{
// if we've previously edited the entry then give us that, else give us the original message
return localChanges[i] ?? messageList[i];
}
int LoopAround(int next)
{
if (next > (messageList.Count - 1)) { return 1; }
if (next < 1) { return messageList.Count - 1; }
return next;
// temporarily save our changes in case we fat-finger and want to go back
localChanges[index] = original;
var dir = (int) direction;
var nextIndex = (index + dir);
if (loop && messageList.Count > 1)
{
nextIndex = LoopAround(nextIndex);
}
else
{
if (nextIndex > messageList.Count - 1)
{
return null;
}
}
if (nextIndex >= 0 && EntryAt(nextIndex) == original && nextIndex != originalIndex && originalIndex != 0)
{
index = nextIndex;
continue;
}
return nextIndex < 0 ? localChanges.FirstOrDefault() : EntryAt(index = nextIndex);
string EntryAt(int i)
{
// if we've previously edited the entry then give us that, else give us the original message
return localChanges[i] ?? messageList[i];
}
int LoopAround(int next)
{
if (next > (messageList.Count - 1))
{
return 1;
}
if (next < 1)
{
return messageList.Count - 1;
}
return next;
}
}
}
@@ -61,7 +61,7 @@ namespace Barotrauma
public static GUITextBox TextBox => textBox;
private static readonly ChatManager chatManager = new ChatManager(true, true, 64);
private static readonly ChatManager chatManager = new ChatManager(true, 64);
public static void Init()
{
@@ -1,17 +1,19 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.CharacterEditor;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Barotrauma.Networking;
using Barotrauma.Sounds;
using Barotrauma.Tutorials;
using EventInput;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -26,11 +28,23 @@ namespace Barotrauma
PickItemFail,
DropItem
}
public enum CursorState
{
Default, // Cursor
Hand, // Hand with a finger
Move, // arrows pointing to all directions
IBeam, // Text
Dragging,// Closed hand
Waiting, // Hourglass
WaitingBackground // Cursor + Hourglass
}
public static class GUI
{
public static GUICanvas Canvas => GUICanvas.Instance;
public static CursorState MouseCursor = CursorState.Default;
public static readonly SamplerState SamplerState = new SamplerState()
{
Filter = TextureFilter.Linear,
@@ -82,8 +96,7 @@ namespace Barotrauma
public static GUIStyle Style;
private static Texture2D t;
private static Sprite Cursor => Style.CursorSprite;
private static Sprite[] MouseCursorSprites => Style.CursorSprite;
private static bool debugDrawSounds, debugDrawEvents;
@@ -184,7 +197,7 @@ namespace Barotrauma
public static void Init(GameWindow window, IEnumerable<ContentPackage> selectedContentPackages, GraphicsDevice graphicsDevice)
{
GUI.GraphicsDevice = graphicsDevice;
GraphicsDevice = graphicsDevice;
var files = ContentPackage.GetFilesOfType(selectedContentPackages, ContentType.UIStyle);
XElement selectedStyle = null;
@@ -306,7 +319,7 @@ namespace Barotrauma
if (GameMain.ShowFPS || GameMain.DebugDraw)
{
DrawString(spriteBatch, new Vector2(10, 10),
"FPS: " + (int)GameMain.PerformanceCounter.AverageFramesPerSecond,
"FPS: " + Math.Round(GameMain.PerformanceCounter.AverageFramesPerSecond),
Color.White, Color.Black * 0.5f, 0, SmallFont);
}
@@ -339,7 +352,7 @@ namespace Barotrauma
y += 15;
}
if (FarseerPhysics.Settings.EnableDiagnostics)
if (Settings.EnableDiagnostics)
{
DrawString(spriteBatch, new Vector2(320, y), "ContinuousPhysicsTime: " + GameMain.World.ContinuousPhysicsTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, Color.Red, (float)GameMain.World.ContinuousPhysicsTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, SmallFont);
DrawString(spriteBatch, new Vector2(320, y + 15), "ControllersUpdateTime: " + GameMain.World.ControllersUpdateTime.TotalMilliseconds, Color.Lerp(Color.LightGreen, Color.Red, (float)GameMain.World.ControllersUpdateTime.TotalMilliseconds / 10.0f), Color.Black * 0.5f, 0, SmallFont);
@@ -415,10 +428,10 @@ namespace Barotrauma
}
else
{
soundStr += System.IO.Path.GetFileNameWithoutExtension(playingSoundChannel.Sound.Filename);
soundStr += Path.GetFileNameWithoutExtension(playingSoundChannel.Sound.Filename);
#if DEBUG
if (PlayerInput.GetKeyboardState.IsKeyDown(Microsoft.Xna.Framework.Input.Keys.G))
if (PlayerInput.GetKeyboardState.IsKeyDown(Keys.G))
{
if (PlayerInput.MousePosition.Y >= y && PlayerInput.MousePosition.Y <= y + 12)
{
@@ -507,10 +520,13 @@ namespace Barotrauma
if (GameMain.WindowActive && !HideCursor)
{
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerStateClamp, rasterizerState: GameMain.ScissorTestEnable);
Cursor.Draw(spriteBatch, PlayerInput.LatestMousePosition, 0, Scale / 2f);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerStateClamp, rasterizerState: GameMain.ScissorTestEnable);
var sprite = MouseCursorSprites[(int) MouseCursor];
sprite.Draw(spriteBatch, PlayerInput.LatestMousePosition, Color.White, sprite.Origin, 0f, Scale / 1.5f);
spriteBatch.End();
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: SamplerState, rasterizerState: GameMain.ScissorTestEnable);
}
HideCursor = false;
}
@@ -723,13 +739,14 @@ namespace Barotrauma
GUIComponent prevMouseOn = MouseOn;
MouseOn = null;
int inventoryIndex = -1;
if (Inventory.IsMouseOnInventory())
{
inventoryIndex = updateList.IndexOf(CharacterHUD.HUDFrame);
}
for (int i = updateList.Count - 1; i > inventoryIndex; i--)
for (var i = updateList.Count - 1; i > inventoryIndex; i--)
{
GUIComponent c = updateList[i];
var c = updateList[i];
if (!c.CanBeFocused) { continue; }
if (c.MouseRect.Contains(PlayerInput.MousePosition))
{
@@ -740,8 +757,198 @@ namespace Barotrauma
break;
}
}
MouseCursor = UpdateMouseCursorState(MouseOn);
return MouseOn;
}
private static CursorState UpdateMouseCursorState(GUIComponent c)
{
// Waiting and drag cursor override everything else
if (MouseCursor == CursorState.Waiting) { return CursorState.Waiting; }
if (GUIScrollBar.DraggingBar != null) { return GUIScrollBar.DraggingBar.Bar.HoverCursor; }
// Wire cursors
if (ConnectionPanel.HighlightedWire != null) { return CursorState.Hand; }
if (Wire.DraggingWire != null) { return CursorState.Dragging; }
if (Connection.DraggingConnected != null) { return CursorState.Dragging; }
if (c == null || c is GUICustomComponent)
{
switch (Screen.Selected)
{
// Character editor limbs
case CharacterEditorScreen editor:
return editor.GetMouseCursorState();
// Portrait area during gameplay
case GameScreen _ when HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition):
return CursorState.Hand;
// Sub editor drag and highlight
case SubEditorScreen editor:
{
// Portrait area
if ((editor.CharacterMode || editor.WiringMode) &&
HUDLayoutSettings.PortraitArea.Contains(PlayerInput.MousePosition))
{
return CursorState.Hand;
}
foreach (var mapEntity in MapEntity.mapEntityList)
{
if (MapEntity.StartMovingPos != Vector2.Zero)
{
return CursorState.Dragging;
}
if (mapEntity.IsHighlighted)
{
return CursorState.Hand;
}
}
break;
}
// Campaign map highlighted location
case LobbyScreen lobby:
{
if (lobby.CampaignUI?.Campaign.Map.HighlightedLocation != null) { return CursorState.Hand; }
break;
}
case NetLobbyScreen lobby:
{
if (lobby.CampaignUI?.Campaign.Map.HighlightedLocation != null) { return CursorState.Hand; }
break;
}
}
}
if (c != null && c.Visible)
{
// When a button opens a submenu, it increases to the size of the entire screen.
// And this is of course picked up as clickable area.
// There has to be a better way of checking this but for now this works.
var monitorRect = new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight);
var parent = FindInteractParent(c);
if (c.Enabled)
{
// Some parent elements take priority
// but not when the child is a GUIButton or GUITickBox
if (!(parent is GUIButton) && !(parent is GUIListBox) ||
(c is GUIButton) || (c is GUITickBox))
{
if (!c.Rect.Equals(monitorRect)) { return c.HoverCursor; }
}
}
// Children in list boxes can be interacted with despite not having
// a GUIButton inside of them so instead of hard coding we check if
// the children can be interacted with by checking their hover state
if (parent is GUIListBox)
{
var hoverParent = c;
while (true)
{
if (hoverParent == parent || hoverParent == null) { break; }
if (hoverParent.State == GUIComponent.ComponentState.Hover) { return CursorState.Hand; }
hoverParent = hoverParent.Parent;
}
}
if (parent != null)
{
if (!parent.Rect.Equals(monitorRect)) { return parent.HoverCursor; }
}
}
if (Inventory.IsMouseOnInventory()) { return Inventory.GetInventoryMouseCursor(); }
var character = Character.Controlled;
// ReSharper disable once InvertIf
if (character != null)
{
// Health menus
if (character.CharacterHealth.MouseOnElement) { return CursorState.Hand; }
if (character.SelectedCharacter != null)
{
if (character.SelectedCharacter.CharacterHealth.MouseOnElement)
{
return CursorState.Hand;
}
}
// Character is hovering over an item placed in the world
if (character.FocusedItem != null) { return CursorState.Hand; }
}
return CursorState.Default;
static GUIComponent FindInteractParent(GUIComponent component)
{
while (true)
{
var parent = component.Parent;
if (parent == null) { return null; }
if (ContainsMouse(parent))
{
if (parent.Enabled)
{
switch (parent)
{
case GUIButton button:
return button;
case GUITextBox box:
return box;
case GUIListBox list:
return list;
case GUIScrollBar bar:
return bar;
}
}
component = parent;
}
else
{
return null;
}
}
}
static bool ContainsMouse(GUIComponent component)
{
// If component has a mouse rectangle then use that, if not use it's physical rect
return !component.MouseRect.Equals(Rectangle.Empty) ?
component.MouseRect.Contains(PlayerInput.MousePosition) :
component.Rect.Contains(PlayerInput.MousePosition);
}
}
/// <summary>
/// Set the cursor to an hourglass.
/// Will automatically revert after 10 seconds or when <see cref="ClearCursorWait"/> is called.
/// </summary>
public static void SetCursorWaiting()
{
CoroutineManager.StartCoroutine(WaitCursorCoroutine(), "WaitCursorTimeout");
static IEnumerable<object> WaitCursorCoroutine()
{
MouseCursor = CursorState.Waiting;
var timeOut = DateTime.Now + new TimeSpan(0, 0, 10);
while (DateTime.Now < timeOut) { yield return CoroutineStatus.Running; }
if (MouseCursor == CursorState.Waiting) { MouseCursor = CursorState.Default; }
yield return CoroutineStatus.Success;
}
}
public static void ClearCursorWait()
{
CoroutineManager.StopCoroutines("WaitCursorTimeout");
MouseCursor = CursorState.Default;
}
public static bool HasSizeChanged(Point referenceResolution, float referenceUIScale, float referenceHUDScale)
{
@@ -754,7 +961,7 @@ namespace Barotrauma
HandlePersistingElements(deltaTime);
RefreshUpdateList();
UpdateMouseOn();
System.Diagnostics.Debug.Assert(updateList.Count == updateListSet.Count);
Debug.Assert(updateList.Count == updateListSet.Count);
updateList.ForEach(c => c.UpdateAuto(deltaTime));
UpdateMessages(deltaTime);
}
@@ -154,6 +154,7 @@ namespace Barotrauma
public GUIButton(RectTransform rectT, string text = "", Alignment textAlignment = Alignment.Center, string style = "", Color? color = null, ScalableFont font = null) : base(style, rectT)
{
CanBeFocused = true;
HoverCursor = CursorState.Hand;
if (color.HasValue)
{
@@ -16,6 +16,8 @@ namespace Barotrauma
#region Hierarchy
public GUIComponent Parent => RectTransform.Parent?.GUIComponent;
public CursorState HoverCursor = CursorState.Default;
public IEnumerable<GUIComponent> Children => RectTransform.Children.Select(c => c.GUIComponent);
public T GetChild<T>() where T : GUIComponent
@@ -147,6 +147,7 @@ namespace Barotrauma
public GUIDropDown(RectTransform rectT, string text = "", int elementCount = 4, string style = "", bool selectMultiple = false, bool dropAbove = false) : base(style, rectT)
{
HoverCursor = CursorState.Hand;
CanBeFocused = true;
this.selectMultiple = selectMultiple;
@@ -192,12 +192,28 @@ namespace Barotrauma
public GUIScrollBar(RectTransform rectT, float barSize = 1, Color? color = null, string style = "", bool? isHorizontal = null) : base(style, rectT)
{
CanBeFocused = true;
this.isHorizontal = isHorizontal ?? (Rect.Width > Rect.Height);
Frame = new GUIFrame(new RectTransform(Vector2.One, rectT));
GUI.Style.Apply(Frame, IsHorizontal ? "GUIFrameHorizontal" : "GUIFrameVertical", this);
this.barSize = barSize;
Bar = new GUIButton(new RectTransform(Vector2.One, rectT, IsHorizontal ? Anchor.CenterLeft : Anchor.TopCenter), color: color);
switch (style)
{
case "":
HoverCursor = CursorState.Default;
Bar.HoverCursor = CursorState.Default;
break;
case "GUISlider":
HoverCursor = CursorState.Default;
Bar.HoverCursor = CursorState.Hand;
break;
default:
HoverCursor = CursorState.Hand;
Bar.HoverCursor = CursorState.Hand;
break;
}
GUI.Style.Apply(Bar, IsHorizontal ? "GUIButtonHorizontal" : "GUIButtonVertical", this);
Bar.OnPressed = SelectBar;
enabled = true;
@@ -222,8 +238,6 @@ namespace Barotrauma
{
if (!Visible) { return; }
base.Update(deltaTime);
if (!enabled) { return; }
Frame.State = GUI.MouseOn == Frame ? ComponentState.Hover : ComponentState.None;
@@ -25,7 +25,7 @@ namespace Barotrauma
public ScalableFont ObjectiveTitleFont { get; private set; }
public ScalableFont ObjectiveNameFont { get; private set; }
public Sprite CursorSprite { get; private set; }
public readonly Sprite[] CursorSprite = new Sprite[7];
public UISprite UIGlow { get; private set; }
@@ -38,10 +38,15 @@ namespace Barotrauma
configElement = element;
foreach (XElement subElement in configElement.Elements())
{
switch (subElement.Name.ToString().ToLowerInvariant())
var name = subElement.Name.ToString().ToLowerInvariant();
switch (name)
{
case "cursor":
CursorSprite = new Sprite(subElement);
foreach (var children in subElement.Descendants())
{
var index = children.GetAttributeInt("state", (int) CursorState.Default);
CursorSprite[index] = new Sprite(children);
}
break;
case "uiglow":
UIGlow = new UISprite(subElement);
@@ -231,6 +231,7 @@ namespace Barotrauma
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null)
: base(style, rectT)
{
HoverCursor = CursorState.IBeam;
CanBeFocused = true;
Enabled = true;
@@ -134,6 +134,7 @@ namespace Barotrauma
public GUITickBox(RectTransform rectT, string label, ScalableFont font = null, string style = "") : base(null, rectT)
{
CanBeFocused = true;
HoverCursor = CursorState.Hand;
layoutGroup = new GUILayoutGroup(new RectTransform(Vector2.One, rectT), true);
@@ -176,6 +177,7 @@ namespace Barotrauma
protected override void Update(float deltaTime)
{
if (!Visible) return;
base.Update(deltaTime);
if (GUI.MouseOn == this && Enabled)
{
@@ -891,7 +891,13 @@ namespace Barotrauma
double deltaTime = gameTime.ElapsedGameTime.TotalSeconds;
PerformanceCounter.Update(deltaTime);
double step = 1.0 / Timing.FrameLimit;
while (!Config.VSyncEnabled && sw.Elapsed.TotalSeconds + deltaTime < step)
{
Thread.Sleep(1);
}
PerformanceCounter.Update(sw.Elapsed.TotalSeconds + deltaTime);
if (loadingScreenOpen)
{
@@ -97,7 +97,10 @@ namespace Barotrauma.Tutorials
stunbaton.Unequip(officer);
officer.Inventory.RemoveItem(stunbaton);
var ballistichelmet = FindOrGiveItem(officer, "ballistichelmet");
var ballistichelmet =
officer.Inventory.FindItemByIdentifier("ballistichelmet1") ??
officer.Inventory.FindItemByIdentifier("ballistichelmet2") ??
FindOrGiveItem(officer, "ballistichelmet3");
ballistichelmet.Unequip(officer);
officer.Inventory.RemoveItem(ballistichelmet);
@@ -24,6 +24,12 @@ namespace Barotrauma.Items.Components
{
get { return flashTimer; }
}
public static Wire DraggingConnected
{
get => draggingConnected;
}
private float flashTimer;
public static void DrawConnections(SpriteBatch spriteBatch, ConnectionPanel panel, Character character)
@@ -51,6 +51,11 @@ namespace Barotrauma.Items.Components
get { return sectionExtents; }
}
public static Wire DraggingWire
{
get => draggingWire;
}
partial void InitProjSpecific(XElement element)
{
if (defaultWireSprite == null)
@@ -653,10 +653,19 @@ namespace Barotrauma
if (Character.Controlled.Inventory != null)
{
foreach (InventorySlot slot in Character.Controlled.Inventory.slots)
var inv = Character.Controlled.Inventory;
for (var i = 0; i < inv.slots.Length; i++)
{
if (slot.InteractRect.Contains(PlayerInput.MousePosition) ||
slot.EquipButtonRect.Contains(PlayerInput.MousePosition))
var slot = inv.slots[i];
if (slot.InteractRect.Contains(PlayerInput.MousePosition))
{
return true;
}
// check if the equip button actually exists
if (slot.EquipButtonRect.Contains(PlayerInput.MousePosition) &&
i >= 0 && inv.Items.Length > i &&
inv.Items[i] != null)
{
return true;
}
@@ -664,10 +673,19 @@ namespace Barotrauma
}
if (Character.Controlled.SelectedCharacter?.Inventory != null)
{
foreach (InventorySlot slot in Character.Controlled.SelectedCharacter.Inventory.slots)
var inv = Character.Controlled.SelectedCharacter.Inventory;
for (var i = 0; i < inv.slots.Length; i++)
{
if (slot.InteractRect.Contains(PlayerInput.MousePosition) ||
slot.EquipButtonRect.Contains(PlayerInput.MousePosition))
var slot = inv.slots[i];
if (slot.InteractRect.Contains(PlayerInput.MousePosition))
{
return true;
}
// check if the equip button actually exists
if (slot.EquipButtonRect.Contains(PlayerInput.MousePosition) &&
i >= 0 && inv.Items.Length > i &&
inv.Items[i] != null)
{
return true;
}
@@ -676,7 +694,7 @@ namespace Barotrauma
if (Character.Controlled.SelectedConstruction != null)
{
foreach (ItemComponent ic in Character.Controlled.SelectedConstruction.Components)
foreach (var ic in Character.Controlled.SelectedConstruction.ActiveHUDs)
{
var itemContainer = ic as ItemContainer;
if (itemContainer?.Inventory?.slots == null) continue;
@@ -699,6 +717,88 @@ namespace Barotrauma
return false;
}
public static CursorState GetInventoryMouseCursor()
{
var character = Character.Controlled;
if (character == null) { return CursorState.Default; }
if (draggingItem != null || DraggingInventory != null) { return CursorState.Dragging; }
var inv = character.Inventory;
var selInv = character.SelectedCharacter?.Inventory;
if (inv == null) { return CursorState.Default; }
foreach (var item in inv.Items)
{
var container = item?.GetComponent<ItemContainer>();
if (container == null) { continue; }
if (container.Inventory.slots != null)
{
if (container.Inventory.slots.Any(slot => slot.IsHighlighted))
{
return CursorState.Hand;
}
}
if (container.Inventory.movableFrameRect.Contains(PlayerInput.MousePosition))
{
return CursorState.Move;
}
}
if (selInv != null)
{
foreach (var slot in selInv.slots)
{
if (slot.InteractRect.Contains(PlayerInput.MousePosition) ||
slot.EquipButtonRect.Contains(PlayerInput.MousePosition))
{
return CursorState.Hand;
}
}
}
if (character.SelectedConstruction != null)
{
foreach (var ic in character.SelectedConstruction.ActiveHUDs)
{
var itemContainer = ic as ItemContainer;
if (itemContainer?.Inventory?.slots == null) continue;
foreach (var slot in itemContainer.Inventory.slots)
{
if (slot.InteractRect.Contains(PlayerInput.MousePosition) ||
slot.EquipButtonRect.Contains(PlayerInput.MousePosition))
{
return CursorState.Hand;
}
}
}
}
foreach (var slot in inv.slots)
{
if (slot.EquipButtonRect.Contains(PlayerInput.MousePosition))
{
return CursorState.Hand;
}
// This is the only place we double check this because if we have a inventory container
// highlighting any area within that container registers as highlighting the
// original slot the item is in thus giving us a false hand cursor.
if (slot.InteractRect.Contains(PlayerInput.MousePosition))
{
if (slot.IsHighlighted)
{
return CursorState.Hand;
}
}
}
return CursorState.Default;
}
protected static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle highlightedSlot, List<ColorData> colorData = null)
{
@@ -88,8 +88,15 @@ namespace Barotrauma
float arrowWidth = 32.0f;
float arrowSize = 15.0f;
bool invalidDir = false;
if (dir == Vector2.Zero)
{
invalidDir = true;
dir = IsHorizontal ? Vector2.UnitX : Vector2.UnitY;
}
GUI.Arrow.Draw(sb,
arrowPos, clr * 0.8f,
arrowPos, invalidDir ? Color.Red : clr * 0.8f,
GUI.Arrow.Origin, MathUtils.VectorToAngle(dir) + MathHelper.PiOver2,
IsHorizontal ?
new Vector2(Math.Min(rect.Height, arrowWidth) / GUI.Arrow.size.X, arrowSize / GUI.Arrow.size.Y) :
@@ -44,6 +44,8 @@ namespace Barotrauma
private Location highlightedLocation;
public Location HighlightedLocation => highlightedLocation;
private Vector2 drawOffset;
private Vector2 drawOffsetNoise;
@@ -13,7 +13,9 @@ namespace Barotrauma
protected static Vector2 selectionPos = Vector2.Zero;
protected static Vector2 selectionSize = Vector2.Zero;
protected static Vector2 startMovingPos = Vector2.Zero;
private static Vector2 startMovingPos = Vector2.Zero;
public static Vector2 StartMovingPos => startMovingPos;
private static bool resizing;
private int resizeDirX, resizeDirY;
@@ -66,7 +66,7 @@ namespace Barotrauma.Networking
}
txt = order.GetChatMessage(targetCharacter?.Name, senderCharacter?.CurrentHull?.DisplayName, givingOrderToSelf: targetCharacter == senderCharacter, orderOption: orderOption);
if (GameMain.Client.GameStarted)
if (GameMain.Client.GameStarted && Screen.Selected == GameMain.GameScreen)
{
if (order.TargetAllCharacters)
{
@@ -401,6 +401,7 @@ namespace Barotrauma.Networking
// Before main looping starts, we loop here and wait for approval message
private IEnumerable<object> WaitForStartingInfo()
{
GUI.SetCursorWaiting();
requiresPw = false;
pwRetries = -1;
@@ -503,6 +504,7 @@ namespace Barotrauma.Networking
reconnectBox?.Close(); reconnectBox = null;
GUI.ClearCursorWait();
if (connectCancelled) { yield return CoroutineStatus.Success; }
yield return CoroutineStatus.Success;
@@ -1435,6 +1437,11 @@ namespace Barotrauma.Networking
if (clientPeer is SteamP2POwnerPeer)
{
TaskPool.Add(Steamworks.SteamNetworkingUtils.WaitForPingDataAsync(), (task) =>
{
Steam.SteamManager.UpdateLobby(serverSettings);
});
Steam.SteamManager.UpdateLobby(serverSettings);
}
}
@@ -1978,7 +1985,7 @@ namespace Barotrauma.Networking
if (ChildServerRelay.Process != null)
{
int checks = 0;
while (!ChildServerRelay.Process.HasExited)
while (ChildServerRelay.Process != null && !ChildServerRelay.Process.HasExited)
{
if (checks > 10)
{
@@ -509,11 +509,6 @@ namespace Barotrauma.Networking
IP = "";
Port = "";
QueryPort = "";
string pingLocation = lobby.GetData("pinglocation");
if (!string.IsNullOrEmpty(pingLocation))
{
PingLocation = Steamworks.Data.PingLocation.TryParseFromString(pingLocation);
}
PlayerCount = currPlayers;
MaxPlayers = maxPlayers;
HasPassword = hasPassword;
@@ -118,6 +118,8 @@ namespace Barotrauma.Steam
TaskPool.Add(Steamworks.SteamMatchmaking.CreateLobbyAsync(serverSettings.MaxPlayers + 10),
(lobby) =>
{
currentLobby = lobby.Result;
if (currentLobby == null)
{
DebugConsole.ThrowError("Failed to create Steam lobby");
@@ -125,8 +127,6 @@ namespace Barotrauma.Steam
return;
}
currentLobby = lobby.Result;
DebugConsole.NewMessage("Lobby created!", Microsoft.Xna.Framework.Color.Lime);
lobbyState = LobbyState.Owner;
@@ -169,7 +169,8 @@ namespace Barotrauma.Steam
currentLobby?.SetData("playercount", (GameMain.Client?.ConnectedClients?.Count ?? 0).ToString());
currentLobby?.SetData("maxplayernum", serverSettings.MaxPlayers.ToString());
//currentLobby?.SetData("hostipaddress", lobbyIP);
currentLobby?.SetData("pinglocation", Steamworks.SteamNetworkingUtils.LocalPingLocation.ToString() ?? "");
string pingLocation = Steamworks.SteamNetworkingUtils.LocalPingLocation.ToString();
currentLobby?.SetData("pinglocation", pingLocation ?? "");
currentLobby?.SetData("lobbyowner", SteamIDUInt64ToString(GetSteamID()));
currentLobby?.SetData("haspassword", serverSettings.HasPassword.ToString());
@@ -254,6 +255,7 @@ namespace Barotrauma.Steam
ServerInfo serverInfo = new ServerInfo();
serverInfo.ServerName = lobby.GetData("name");
serverInfo.OwnerID = SteamIDStringToUInt64(lobby.GetData("lobbyowner"));
serverInfo.LobbyID = lobby.Id;
serverInfo.PlayerCount = int.TryParse(lobby.GetData("playercount"), out int playerCount) ? playerCount : 0;
serverInfo.MaxPlayers = int.TryParse(lobby.GetData("maxplayernum"), out int maxPlayers) ? maxPlayers : 1;
@@ -371,6 +373,12 @@ namespace Barotrauma.Steam
serverInfo.ContentPackageHashes.Clear();
}
string pingLocation = lobby.GetData("pinglocation");
if (!string.IsNullOrEmpty(pingLocation))
{
serverInfo.PingLocation = Steamworks.Data.PingLocation.TryParseFromString(pingLocation);
}
bool? getLobbyBool(string key)
{
string data = lobby.GetData(key);
@@ -112,6 +112,7 @@ namespace Barotrauma
if (GameMain.Config != null)
{
sb.AppendLine("Graphics mode: " + GameMain.Config.GraphicsWidth + "x" + GameMain.Config.GraphicsHeight + " (" + GameMain.Config.WindowMode.ToString() + ")");
sb.AppendLine("VSync "+ (GameMain.Config.VSyncEnabled ? "ON" : "OFF"));
}
if (GameMain.SelectedPackages != null)
{
@@ -244,6 +244,7 @@ namespace Barotrauma
private IEnumerable<object> WaitForCampaignSetup()
{
GUI.SetCursorWaiting();
string headerText = TextManager.Get("CampaignStartingPleaseWait");
var msgBox = new GUIMessageBox(headerText, TextManager.Get("CampaignStarting"), new string[] { TextManager.Get("Cancel") });
@@ -251,6 +252,7 @@ namespace Barotrauma
{
GameMain.NetLobbyScreen.HighlightMode(GameMain.NetLobbyScreen.SelectedModeIndex);
GameMain.NetLobbyScreen.SelectMode(GameMain.NetLobbyScreen.SelectedModeIndex);
GUI.ClearCursorWait();
CoroutineManager.StopCoroutines("WaitForCampaignSetup");
return true;
};
@@ -263,6 +265,7 @@ namespace Barotrauma
yield return CoroutineStatus.Running;
}
msgBox.Close();
GUI.ClearCursorWait();
yield return CoroutineStatus.Success;
}
@@ -746,6 +746,21 @@ namespace Barotrauma.CharacterEditor
buttonsPanelToggle?.UpdateOpenState((float)deltaTime, new Vector2(-buttonsPanel.Rect.Width - leftArea.RectTransform.AbsoluteOffset.X, 0), buttonsPanel.RectTransform);
}
public CursorState GetMouseCursorState()
{
foreach (var limb in character.AnimController.Limbs)
{
if (limb?.ActiveSprite == null) { continue; }
if (selectedJoints.Any(j => j.LimbA == limb || j.LimbB == limb)) { continue; }
// character limbs
if (editLimbs && !spriteSheetRect.Contains(PlayerInput.MousePosition) &&
MathUtils.RectangleContainsPoint(GetLimbPhysicRect(limb), PlayerInput.MousePosition)) { return CursorState.Hand; }
// spritesheet
if (GetLimbSpritesheetRect(limb).Contains(PlayerInput.MousePosition)) { return CursorState.Hand; }
}
return CursorState.Default;
}
/// <summary>
/// Fps independent mouse input. The draw method is called multiple times per frame.
/// </summary>
@@ -18,6 +18,11 @@ namespace Barotrauma
get { return GameMain.GameSession.CrewManager; }
}
public CampaignUI CampaignUI
{
get { return campaignUI; }
}
public string GetMoney()
{
return campaignUI == null ? "" : campaignUI.GetMoney();
@@ -545,10 +545,10 @@ namespace Barotrauma
break;
case Tab.CharacterEditor:
Submarine.MainSub = null;
GameMain.CharacterEditorScreen.Select();
CoroutineManager.StartCoroutine(SelectScreenWithWaitCursor(GameMain.CharacterEditorScreen));
break;
case Tab.SubmarineEditor:
GameMain.SubEditorScreen.Select();
CoroutineManager.StartCoroutine(SelectScreenWithWaitCursor(GameMain.SubEditorScreen));
break;
case Tab.QuickStartDev:
QuickStart();
@@ -560,7 +560,7 @@ namespace Barotrauma
break;
case Tab.SteamWorkshop:
if (!Steam.SteamManager.IsInitialized) return false;
GameMain.SteamWorkshopScreen.Select();
CoroutineManager.StartCoroutine(SelectScreenWithWaitCursor(GameMain.SteamWorkshopScreen));
break;
case Tab.Credits:
titleText.Visible = false;
@@ -577,6 +577,16 @@ namespace Barotrauma
return true;
}
private IEnumerable<object> SelectScreenWithWaitCursor(Screen screen)
{
GUI.SetCursorWaiting();
//tiny delay to get the cursor to render
yield return new WaitForSeconds(0.02f);
GUI.ClearCursorWait();
screen.Select();
yield return CoroutineStatus.Success;
}
public bool ReturnToMainMenu(GUIButton button, object obj)
{
GUI.PreventPauseMenuToggle = false;
@@ -1165,7 +1175,8 @@ namespace Barotrauma
maxPlayersBox = new GUITextBox(new RectTransform(new Vector2(0.6f, 1.0f), buttonContainer.RectTransform), textAlignment: Alignment.Center)
{
Text = maxPlayers.ToString(),
Enabled = false
// ?
// Enabled = false
};
new GUIButton(new RectTransform(new Vector2(0.2f, 1.0f), buttonContainer.RectTransform), "+", textAlignment: Alignment.Center)
{
@@ -1080,6 +1080,7 @@ namespace Barotrauma
public IEnumerable<object> WaitForStartRound(GUIButton startButton, bool allowCancel)
{
GUI.SetCursorWaiting();
string headerText = TextManager.Get("RoundStartingPleaseWait");
var msgBox = new GUIMessageBox(headerText, TextManager.Get("RoundStarting"),
allowCancel ? new string[] { TextManager.Get("Cancel") } : new string[0]);
@@ -1091,6 +1092,7 @@ namespace Barotrauma
startButton.Enabled = true;
GameMain.Client.RequestRoundEnd();
CoroutineManager.StopCoroutines("WaitForStartRound");
GUI.ClearCursorWait();
return true;
};
msgBox.Buttons[0].OnClicked += msgBox.Close;
@@ -1113,7 +1115,7 @@ namespace Barotrauma
{
startButton.Enabled = true;
}
GUI.ClearCursorWait();
yield return CoroutineStatus.Success;
}
@@ -147,6 +147,8 @@ namespace Barotrauma
private DateTime refreshDisableTimer;
private bool waitingForRefresh;
private bool steamPingInfoReady;
private const float sidebarWidth = 0.2f;
public ServerListScreen()
{
@@ -1423,6 +1425,15 @@ namespace Barotrauma
{
if (waitingForRefresh) { return; }
steamPingInfoReady = false;
CoroutineManager.StopCoroutines("EstimateLobbyPing");
TaskPool.Add(Steamworks.SteamNetworkingUtils.WaitForPingDataAsync(), (task) =>
{
steamPingInfoReady = true;
});
friendsListUpdateTime = Timing.TotalTime - 1.0;
UpdateFriendsList();
@@ -1684,11 +1695,7 @@ namespace Barotrauma
}
else if (serverInfo.PingLocation != null)
{
Steamworks.Data.PingLocation pingLocation = serverInfo.PingLocation.Value;
serverInfo.Ping = Steamworks.SteamNetworkingUtils.LocalPingLocation?.EstimatePingTo(pingLocation) ?? -1;
serverInfo.PingChecked = true;
serverPingText.TextColor = GetPingTextColor(serverInfo.Ping);
serverPingText.Text = serverInfo.Ping > -1 ? serverInfo.Ping.ToString() : "?";
CoroutineManager.StartCoroutine(EstimateLobbyPing(serverInfo, serverPingText), "EstimateLobbyPing");
}
if (serverInfo.LobbyID == 0 && (string.IsNullOrWhiteSpace(serverInfo.IP) || string.IsNullOrWhiteSpace(serverInfo.Port)))
@@ -1749,6 +1756,22 @@ namespace Barotrauma
FilterServers();
}
private IEnumerable<object> EstimateLobbyPing(ServerInfo serverInfo, GUITextBlock serverPingText)
{
while (!steamPingInfoReady)
{
yield return CoroutineStatus.Running;
}
Steamworks.Data.PingLocation pingLocation = serverInfo.PingLocation.Value;
serverInfo.Ping = Steamworks.SteamNetworkingUtils.LocalPingLocation?.EstimatePingTo(pingLocation) ?? -1;
serverInfo.PingChecked = true;
serverPingText.TextColor = GetPingTextColor(serverInfo.Ping);
serverPingText.Text = serverInfo.Ping > -1 ? serverInfo.Ping.ToString() : "?";
yield return CoroutineStatus.Success;
}
private void ServerQueryFinished()
{
if (!serverList.Content.Children.Any())
@@ -1435,7 +1435,7 @@ namespace Barotrauma
#if DEBUG
deleteBtn.Enabled = true;
#else
deleteBtn.Enabled = userData is Submarine sub && sub.IsVanillaSubmarine();
deleteBtn.Enabled = userData is Submarine sub && !sub.IsVanillaSubmarine();
#endif
}
return true;