Unstable 0.15.15.0 (and the one before it I forgor)
This commit is contained in:
@@ -494,7 +494,7 @@ namespace Barotrauma
|
||||
GUIFrame.Parent.Visible = visible;
|
||||
}
|
||||
|
||||
private IEnumerable<object> UpdateMessageAnimation(GUIComponent message, float animDuration)
|
||||
private IEnumerable<CoroutineStatus> UpdateMessageAnimation(GUIComponent message, float animDuration)
|
||||
{
|
||||
float timer = 0.0f;
|
||||
while (timer < animDuration)
|
||||
|
||||
@@ -399,7 +399,7 @@ namespace Barotrauma
|
||||
" Max: " + GameMain.PerformanceCounter.DrawTimeGraph.LargestValue().ToString("0.00") + " ms",
|
||||
GUI.Style.Green, Color.Black * 0.8f, font: SmallFont);
|
||||
y += 15;
|
||||
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), null, 0, GUI.Style.Green);
|
||||
GameMain.PerformanceCounter.DrawTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Style.Green);
|
||||
y += 50;
|
||||
|
||||
DrawString(spriteBatch, new Vector2(300, y),
|
||||
@@ -407,8 +407,8 @@ namespace Barotrauma
|
||||
" Max: " + GameMain.PerformanceCounter.UpdateTimeGraph.LargestValue().ToString("0.00") + " ms",
|
||||
Color.LightBlue, Color.Black * 0.8f, font: SmallFont);
|
||||
y += 15;
|
||||
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), null, 0, Color.LightBlue);
|
||||
GameMain.PerformanceCounter.UpdateIterationsGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), 20, 0, GUI.Style.Red);
|
||||
GameMain.PerformanceCounter.UpdateTimeGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), color: Color.LightBlue);
|
||||
GameMain.PerformanceCounter.UpdateIterationsGraph.Draw(spriteBatch, new Rectangle(300, y, 170, 50), maxValue: 20, color: Style.Red);
|
||||
y += 50;
|
||||
foreach (string key in GameMain.PerformanceCounter.GetSavedIdentifiers)
|
||||
{
|
||||
@@ -941,7 +941,8 @@ namespace Barotrauma
|
||||
inventoryIndex = updateList.IndexOf(CharacterHUD.HUDFrame);
|
||||
}
|
||||
|
||||
if ((!PlayerInput.PrimaryMouseButtonHeld() && !PlayerInput.PrimaryMouseButtonClicked()) || (prevMouseOn == null && !PlayerInput.SecondaryMouseButtonHeld()))
|
||||
if ((!PlayerInput.PrimaryMouseButtonHeld() && !PlayerInput.PrimaryMouseButtonClicked()) ||
|
||||
(prevMouseOn == null && !PlayerInput.SecondaryMouseButtonHeld() && !Inventory.DraggingItems.Any()))
|
||||
{
|
||||
for (var i = updateList.Count - 1; i > inventoryIndex; i--)
|
||||
{
|
||||
@@ -1052,10 +1053,10 @@ namespace Barotrauma
|
||||
// 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 listBox)
|
||||
if (parent is GUIListBox listBox && c.Parent == listBox.Content)
|
||||
{
|
||||
if (listBox.DraggedElement != null) { return CursorState.Dragging; }
|
||||
if (listBox.CanDragElements) { return CursorState.Move; }
|
||||
if (listBox.CurrentDragMode != GUIListBox.DragMode.NoDragging) { return CursorState.Move; }
|
||||
|
||||
if (listBox.HoverCursor != CursorState.Default)
|
||||
{
|
||||
@@ -1148,7 +1149,7 @@ namespace Barotrauma
|
||||
{
|
||||
CoroutineManager.StartCoroutine(WaitCursorCoroutine(), "WaitCursorTimeout");
|
||||
|
||||
IEnumerable<object> WaitCursorCoroutine()
|
||||
IEnumerable<CoroutineStatus> WaitCursorCoroutine()
|
||||
{
|
||||
MouseCursor = CursorState.Waiting;
|
||||
var timeOut = DateTime.Now + new TimeSpan(0, 0, waitSeconds);
|
||||
@@ -1360,7 +1361,7 @@ namespace Barotrauma
|
||||
|
||||
float symbolScale = Math.Min(64.0f / sprite.size.X, 1.0f) * scaleMultiplier * Scale;
|
||||
|
||||
if (overrideAlpha.HasValue || (dist > visibleRange.Start && dist < visibleRange.End))
|
||||
if (overrideAlpha.HasValue || visibleRange.Contains(dist))
|
||||
{
|
||||
float alpha = overrideAlpha ?? MathUtils.Min((dist - visibleRange.Start) / 100.0f, 1.0f - ((dist - visibleRange.End + 100f) / 100.0f), 1.0f);
|
||||
Vector2 targetScreenPos = cam.WorldToScreen(worldPosition);
|
||||
@@ -2254,8 +2255,8 @@ namespace Barotrauma
|
||||
#region Misc
|
||||
public static void TogglePauseMenu()
|
||||
{
|
||||
if (Screen.Selected == GameMain.MainMenuScreen) return;
|
||||
if (PreventPauseMenuToggle) return;
|
||||
if (Screen.Selected == GameMain.MainMenuScreen) { return; }
|
||||
if (PreventPauseMenuToggle) { return; }
|
||||
|
||||
settingsMenuOpen = false;
|
||||
|
||||
@@ -2276,162 +2277,121 @@ namespace Barotrauma
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.1f, 0.1f), pauseMenuInner.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point((int)(15 * GUI.Scale)) },
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.1f, 0.1f), pauseMenuInner.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point((int)(15 * GUI.Scale)) },
|
||||
"", style: "GUIBugButton")
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
ToolTip = TextManager.Get("bugreportbutton"),
|
||||
ToolTip = TextManager.Get("bugreportbutton") + $" (v{GameMain.Version})",
|
||||
OnClicked = (btn, userdata) => { GameMain.Instance.ShowBugReporter(); return true; }
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform), TextManager.Get("PauseMenuResume"))
|
||||
{
|
||||
OnClicked = TogglePauseMenu
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform), TextManager.Get("PauseMenuSettings"))
|
||||
{
|
||||
OnClicked = (btn, userData) =>
|
||||
{
|
||||
TogglePauseMenu();
|
||||
settingsMenuOpen = !settingsMenuOpen;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
CreateButton("PauseMenuResume", buttonContainer, null);
|
||||
CreateButton("PauseMenuSettings", buttonContainer, () => { settingsMenuOpen = !settingsMenuOpen; });
|
||||
|
||||
bool IsOutpostLevel() => GameMain.GameSession != null && Level.IsLoadedOutpost;
|
||||
if (Screen.Selected == GameMain.GameScreen && GameMain.GameSession != null)
|
||||
{
|
||||
if (GameMain.GameSession.GameMode is SinglePlayerCampaign spMode)
|
||||
{
|
||||
var retryButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform), TextManager.Get("PauseMenuRetry"));
|
||||
retryButton.OnClicked += (btn, userData) =>
|
||||
CreateButton("PauseMenuRetry", buttonContainer, verificationTextTag: "PauseMenuRetryVerification", action: () =>
|
||||
{
|
||||
var msgBox = new GUIMessageBox("", TextManager.Get("PauseMenuRetryVerification"), new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") })
|
||||
if (GameMain.GameSession.RoundSummary?.Frame != null)
|
||||
{
|
||||
UserData = "verificationprompt"
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked = (_, userdata) =>
|
||||
{
|
||||
if (GameMain.GameSession.RoundSummary?.Frame != null)
|
||||
{
|
||||
GUIMessageBox.MessageBoxes.Remove(GameMain.GameSession.RoundSummary.Frame);
|
||||
}
|
||||
GUIMessageBox.MessageBoxes.Remove(GameMain.GameSession.RoundSummary.Frame);
|
||||
}
|
||||
GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData as string == "ConversationAction");
|
||||
GameMain.GameSession.LoadPreviousSave();
|
||||
});
|
||||
|
||||
GUIMessageBox.MessageBoxes.RemoveAll(mb => mb.UserData as string == "ConversationAction");
|
||||
TogglePauseMenu(btn, userData);
|
||||
GameMain.GameSession.LoadPreviousSave();
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked = (_, userdata) =>
|
||||
{
|
||||
TogglePauseMenu(btn, userData);
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
if (IsOutpostLevel())
|
||||
{
|
||||
var saveAndQuitButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform), TextManager.Get("PauseMenuSaveQuit"))
|
||||
CreateButton("PauseMenuSaveQuit", buttonContainer, verificationTextTag: "PauseMenuSaveAndReturnToMainMenuVerification", action: () =>
|
||||
{
|
||||
UserData = "save",
|
||||
OnClicked = (btn, userData) =>
|
||||
{
|
||||
pauseMenuOpen = false;
|
||||
if (IsOutpostLevel())
|
||||
{
|
||||
GameMain.QuitToMainMenu(save: true);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
if (IsOutpostLevel()) { GameMain.QuitToMainMenu(save: true); }
|
||||
});
|
||||
}
|
||||
}
|
||||
else if (GameMain.GameSession.GameMode is TestGameMode)
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform), text: TextManager.Get("PauseMenuReturnToEditor"))
|
||||
CreateButton("PauseMenuReturnToEditor", buttonContainer, action: () =>
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
GameMain.GameSession.EndRound("");
|
||||
pauseMenuOpen = false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GameMain.GameSession?.EndRound("");
|
||||
});
|
||||
}
|
||||
else if (!GameMain.GameSession.GameMode.IsSinglePlayer && GameMain.Client != null && GameMain.Client.HasPermission(ClientPermissions.ManageRound))
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform),
|
||||
text: TextManager.Get(GameMain.GameSession.GameMode is CampaignMode ? "ReturnToServerlobby": "EndRound"))
|
||||
bool canSave = GameMain.GameSession.GameMode is CampaignMode && IsOutpostLevel();
|
||||
if (canSave)
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
CreateButton("PauseMenuSaveQuit", buttonContainer, verificationTextTag: "PauseMenuSaveAndReturnToServerLobbyVerification", action: () =>
|
||||
{
|
||||
if (!GameMain.Client.HasPermission(ClientPermissions.ManageRound)) { return false; }
|
||||
if (GameMain.GameSession.GameMode is CampaignMode && !IsOutpostLevel() || (!Submarine.MainSub.AtStartExit && !Submarine.MainSub.AtEndExit))
|
||||
{
|
||||
var msgBox = new GUIMessageBox("",
|
||||
TextManager.Get(GameMain.GameSession.GameMode is CampaignMode ? "PauseMenuReturnToServerLobbyVerification" : "EndRoundSubNotAtLevelEnd"),
|
||||
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
|
||||
{
|
||||
UserData = "verificationprompt"
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked = (_, __) =>
|
||||
{
|
||||
pauseMenuOpen = false;
|
||||
GameMain.Client.RequestRoundEnd();
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
||||
}
|
||||
else
|
||||
{
|
||||
pauseMenuOpen = false;
|
||||
GameMain.Client.RequestRoundEnd();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
GameMain.Client?.RequestRoundEnd(save: true);
|
||||
});
|
||||
}
|
||||
|
||||
CreateButton(GameMain.GameSession.GameMode is CampaignMode ? "ReturnToServerlobby" : "EndRound", buttonContainer,
|
||||
verificationTextTag: GameMain.GameSession.GameMode is CampaignMode ? "PauseMenuReturnToServerLobbyVerification" : "EndRoundSubNotAtLevelEnd",
|
||||
action: () =>
|
||||
{
|
||||
GameMain.Client?.RequestRoundEnd(save: false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var quitButton = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform), TextManager.Get("PauseMenuQuit"));
|
||||
quitButton.OnClicked += (btn, userData) =>
|
||||
|
||||
if (GameMain.GameSession != null || Screen.Selected is CharacterEditorScreen || Screen.Selected is SubEditorScreen)
|
||||
{
|
||||
if (GameMain.GameSession != null || (Screen.Selected is CharacterEditorScreen || Screen.Selected is SubEditorScreen))
|
||||
{
|
||||
string text = GameMain.GameSession == null ? "PauseMenuQuitVerificationEditor" : "PauseMenuQuitVerification";
|
||||
var msgBox = new GUIMessageBox("", TextManager.Get(text), new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") })
|
||||
{
|
||||
UserData = "verificationprompt"
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked = (yesBtn, userdata) =>
|
||||
CreateButton("PauseMenuQuit", buttonContainer,
|
||||
verificationTextTag: GameMain.GameSession == null ? "PauseMenuQuitVerificationEditor" : "PauseMenuQuitVerification",
|
||||
action: () =>
|
||||
{
|
||||
GameMain.QuitToMainMenu(save: false);
|
||||
pauseMenuOpen = false;
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked = (_, userdata) =>
|
||||
{
|
||||
pauseMenuOpen = false;
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
GameMain.QuitToMainMenu(save: false);
|
||||
pauseMenuOpen = false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateButton("PauseMenuQuit", buttonContainer, action: () => { GameMain.QuitToMainMenu(save: false); });
|
||||
}
|
||||
|
||||
GUITextBlock.AutoScaleAndNormalize(buttonContainer.Children.Where(c => c is GUIButton).Select(c => ((GUIButton)c).TextBlock));
|
||||
}
|
||||
|
||||
void CreateButton(string textTag, GUIComponent parent, Action action, string verificationTextTag = null)
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), parent.RectTransform), TextManager.Get(textTag))
|
||||
{
|
||||
OnClicked = (btn, userData) =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(verificationTextTag))
|
||||
{
|
||||
pauseMenuOpen = false;
|
||||
action?.Invoke();
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateVerificationPrompt(verificationTextTag, action);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
void CreateVerificationPrompt(string textTag, Action confirmAction)
|
||||
{
|
||||
var msgBox = new GUIMessageBox("", TextManager.Get(textTag),
|
||||
new string[] { TextManager.Get("Yes"), TextManager.Get("No") })
|
||||
{
|
||||
UserData = "verificationprompt"
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked = (_, __) =>
|
||||
{
|
||||
pauseMenuOpen = false;
|
||||
confirmAction?.Invoke();
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TogglePauseMenu(GUIButton button, object obj)
|
||||
|
||||
@@ -531,6 +531,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ForceLayoutRecalculation()
|
||||
{
|
||||
//This is very ugly but it gets the job done, it
|
||||
//would be real nice to un-jank this some day
|
||||
ForceUpdate();
|
||||
ForceUpdate();
|
||||
foreach (var child in Children) { child.ForceLayoutRecalculation(); }
|
||||
}
|
||||
|
||||
public void ForceUpdate() => Update((float)Timing.Step);
|
||||
|
||||
/// <summary>
|
||||
/// Updates all the children manually.
|
||||
/// </summary>
|
||||
@@ -831,7 +842,7 @@ namespace Barotrauma
|
||||
CoroutineManager.StartCoroutine(SlideToPosition(duration, 0.0f, targetPos));
|
||||
}
|
||||
|
||||
private IEnumerable<object> SlideToPosition(float duration, float wait, Vector2 target)
|
||||
private IEnumerable<CoroutineStatus> SlideToPosition(float duration, float wait, Vector2 target)
|
||||
{
|
||||
float t = 0.0f;
|
||||
var (startX, startY) = RectTransform.ScreenSpaceOffset.ToVector2();
|
||||
@@ -855,7 +866,7 @@ namespace Barotrauma
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
|
||||
private IEnumerable<object> LerpAlpha(float to, float duration, bool removeAfter, float wait = 0.0f)
|
||||
private IEnumerable<CoroutineStatus> LerpAlpha(float to, float duration, bool removeAfter, float wait = 0.0f)
|
||||
{
|
||||
State = ComponentState.None;
|
||||
float t = 0.0f;
|
||||
@@ -894,7 +905,7 @@ namespace Barotrauma
|
||||
pulsateCoroutine = CoroutineManager.StartCoroutine(DoPulsate(startScale, endScale, duration), "Pulsate" + ToString());
|
||||
}
|
||||
|
||||
private IEnumerable<object> DoPulsate(Vector2 startScale, Vector2 endScale, float duration)
|
||||
private IEnumerable<CoroutineStatus> DoPulsate(Vector2 startScale, Vector2 endScale, float duration)
|
||||
{
|
||||
float t = 0.0f;
|
||||
while (t < duration)
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Barotrauma
|
||||
public GUIScrollBar ScrollBar { get; private set; }
|
||||
|
||||
private readonly Dictionary<GUIComponent, bool> childVisible = new Dictionary<GUIComponent, bool>();
|
||||
|
||||
|
||||
private int totalSize;
|
||||
private bool childrenNeedsRecalculation;
|
||||
private bool scrollBarNeedsRecalculation;
|
||||
@@ -53,7 +53,23 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public bool SelectMultiple;
|
||||
public enum SelectMode
|
||||
{
|
||||
SelectSingle,
|
||||
SelectMultiple,
|
||||
RequireShiftToSelectMultiple
|
||||
}
|
||||
|
||||
public SelectMode CurrentSelectMode = SelectMode.SelectSingle;
|
||||
|
||||
public bool SelectMultiple
|
||||
{
|
||||
get { return CurrentSelectMode != SelectMode.SelectSingle; }
|
||||
set
|
||||
{
|
||||
CurrentSelectMode = value ? SelectMode.SelectMultiple : SelectMode.SelectSingle;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HideChildrenOutsideFrame = true;
|
||||
|
||||
@@ -103,7 +119,7 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// true if mouse down should select elements instead of mouse up
|
||||
/// </summary>
|
||||
private bool useMouseDownToSelect = false;
|
||||
private readonly bool useMouseDownToSelect = false;
|
||||
|
||||
private Vector4? overridePadding;
|
||||
public Vector4 Padding
|
||||
@@ -132,10 +148,7 @@ namespace Barotrauma
|
||||
// TODO: fix implicit hiding
|
||||
public bool Selected { get; set; }
|
||||
|
||||
public List<GUIComponent> AllSelected
|
||||
{
|
||||
get { return selected; }
|
||||
}
|
||||
public IReadOnlyList<GUIComponent> AllSelected => selected;
|
||||
|
||||
public object SelectedData
|
||||
{
|
||||
@@ -214,25 +227,34 @@ namespace Barotrauma
|
||||
public bool AutoHideScrollBar { get; set; } = true;
|
||||
private bool IsScrollBarOnDefaultSide { get; set; }
|
||||
|
||||
public bool CanDragElements
|
||||
public enum DragMode
|
||||
{
|
||||
NoDragging,
|
||||
DragWithinBox,
|
||||
DragOutsideBox
|
||||
}
|
||||
|
||||
private DragMode currentDragMode = DragMode.NoDragging;
|
||||
public DragMode CurrentDragMode
|
||||
{
|
||||
get
|
||||
{
|
||||
return canDragElements;
|
||||
return currentDragMode;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == false && canDragElements && draggedElement != null)
|
||||
if (value == DragMode.NoDragging && currentDragMode != DragMode.NoDragging && isDraggingElement)
|
||||
{
|
||||
DraggedElement = null;
|
||||
}
|
||||
canDragElements = value;
|
||||
currentDragMode = value;
|
||||
}
|
||||
}
|
||||
private bool canDragElements = false;
|
||||
|
||||
private GUIComponent draggedElement;
|
||||
private Rectangle draggedReferenceRectangle;
|
||||
private Point draggedReferenceOffset;
|
||||
private Point dragMousePosRelativeToTopLeftCorner;
|
||||
private bool isDraggingElement => draggedElement != null;
|
||||
|
||||
public bool HasDraggedElementIndexChanged { get; private set; }
|
||||
|
||||
public GUIComponent DraggedElement
|
||||
@@ -246,8 +268,24 @@ namespace Barotrauma
|
||||
if (value == draggedElement) { return; }
|
||||
draggedElement = value;
|
||||
HasDraggedElementIndexChanged = false;
|
||||
|
||||
if (value == null) { return; }
|
||||
|
||||
dragMousePosRelativeToTopLeftCorner = PlayerInput.MousePosition.ToPoint() - value.Rect.Location;
|
||||
|
||||
if (SelectMultiple)
|
||||
{
|
||||
if (!AllSelected.Contains(DraggedElement))
|
||||
{
|
||||
Select(DraggedElement.ToEnumerable());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//This exists to work around the fact that rendering child
|
||||
//elements on top of the listbox's siblings is a clusterfuck.
|
||||
public bool HideDraggedElement = false;
|
||||
|
||||
private readonly bool isHorizontal;
|
||||
|
||||
@@ -354,7 +392,7 @@ namespace Barotrauma
|
||||
(child.UserData == null && userData == null))
|
||||
{
|
||||
Select(i, force, autoScroll);
|
||||
if (!SelectMultiple) return;
|
||||
if (!SelectMultiple) { return; }
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -363,9 +401,10 @@ namespace Barotrauma
|
||||
private Point CalculateFrameSize(bool isHorizontal, int scrollBarSize)
|
||||
=> isHorizontal ? new Point(Rect.Width, Rect.Height - scrollBarSize) : new Point(Rect.Width - scrollBarSize, Rect.Height);
|
||||
|
||||
private void RepositionChildren()
|
||||
public Vector2 CalculateTopOffset()
|
||||
{
|
||||
int x = 0, y = 0;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
if (ScrollBar.BarSize < 1.0f)
|
||||
{
|
||||
if (ScrollBar.IsHorizontal)
|
||||
@@ -378,53 +417,59 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
private void CalculateChildrenOffsets(Action<int, Point> callback)
|
||||
{
|
||||
Vector2 topOffset = CalculateTopOffset();
|
||||
int x = (int)topOffset.X;
|
||||
int y = (int)topOffset.Y;
|
||||
|
||||
for (int i = 0; i < Content.CountChildren; i++)
|
||||
{
|
||||
GUIComponent child = Content.GetChild(i);
|
||||
if (!child.Visible) { continue; }
|
||||
if (RectTransform != null)
|
||||
{
|
||||
if (child != draggedElement && (child.RectTransform.AbsoluteOffset.X != x || child.RectTransform.AbsoluteOffset.Y != y))
|
||||
{
|
||||
child.RectTransform.AbsoluteOffset = new Point(x, y);
|
||||
}
|
||||
callback(i, new Point(x, y));
|
||||
}
|
||||
|
||||
if (useGridLayout)
|
||||
{
|
||||
void advanceGridLayout(
|
||||
ref int primaryCoord,
|
||||
ref int secondaryCoord,
|
||||
int primaryChildDimension,
|
||||
int secondaryChildDimension,
|
||||
int primaryParentDimension)
|
||||
{
|
||||
if (primaryCoord + primaryChildDimension + Spacing > primaryParentDimension)
|
||||
{
|
||||
primaryCoord = 0;
|
||||
secondaryCoord += secondaryChildDimension + Spacing;
|
||||
callback(i, new Point(x, y));
|
||||
}
|
||||
primaryCoord += primaryChildDimension + Spacing;
|
||||
}
|
||||
|
||||
if (ScrollBar.IsHorizontal)
|
||||
{
|
||||
if (y + child.Rect.Height + Spacing > Content.Rect.Height)
|
||||
{
|
||||
y = 0;
|
||||
x += child.Rect.Width + Spacing;
|
||||
if (child != draggedElement && (child.RectTransform.AbsoluteOffset.X != x || child.RectTransform.AbsoluteOffset.Y != y))
|
||||
{
|
||||
child.RectTransform.AbsoluteOffset = new Point(x, y);
|
||||
}
|
||||
y += child.Rect.Height + Spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
y += child.Rect.Height + Spacing;
|
||||
}
|
||||
advanceGridLayout(
|
||||
primaryCoord: ref y,
|
||||
secondaryCoord: ref x,
|
||||
primaryChildDimension: child.Rect.Height,
|
||||
secondaryChildDimension: child.Rect.Width,
|
||||
primaryParentDimension: Content.Rect.Height);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (x + child.Rect.Width + Spacing > Content.Rect.Width)
|
||||
{
|
||||
x = 0;
|
||||
y += child.Rect.Height + Spacing;
|
||||
if (child != draggedElement && (child.RectTransform.AbsoluteOffset.X != x || child.RectTransform.AbsoluteOffset.Y != y))
|
||||
{
|
||||
child.RectTransform.AbsoluteOffset = new Point(x, y);
|
||||
}
|
||||
x += child.Rect.Width + Spacing;
|
||||
}
|
||||
else
|
||||
{
|
||||
x += child.Rect.Width + Spacing;
|
||||
}
|
||||
advanceGridLayout(
|
||||
primaryCoord: ref x,
|
||||
secondaryCoord: ref y,
|
||||
primaryChildDimension: child.Rect.Width,
|
||||
secondaryChildDimension: child.Rect.Height,
|
||||
primaryParentDimension: Content.Rect.Width);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -440,6 +485,18 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RepositionChildren()
|
||||
{
|
||||
CalculateChildrenOffsets((index, offset) =>
|
||||
{
|
||||
var child = Content.GetChild(index);
|
||||
if (child != draggedElement && child.RectTransform.AbsoluteOffset != offset)
|
||||
{
|
||||
child.RectTransform.AbsoluteOffset = offset;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scrolls the list to the specific element, currently only works when smooth scrolling and PadBottom are enabled.
|
||||
@@ -466,7 +523,7 @@ namespace Barotrauma
|
||||
{
|
||||
CoroutineManager.StartCoroutine(ScrollCoroutine());
|
||||
|
||||
IEnumerable<object> ScrollCoroutine()
|
||||
IEnumerable<CoroutineStatus> ScrollCoroutine()
|
||||
{
|
||||
if (BarSize >= 1.0f)
|
||||
{
|
||||
@@ -490,68 +547,122 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void UpdateChildrenRect()
|
||||
private void StartDraggingElement(GUIComponent child)
|
||||
{
|
||||
//dragging
|
||||
if (CanDragElements && draggedElement != null)
|
||||
DraggedElement = child;
|
||||
}
|
||||
|
||||
private bool UpdateDragging()
|
||||
{
|
||||
if (CurrentDragMode == DragMode.NoDragging || !isDraggingElement) { return false; }
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
{
|
||||
if (!PlayerInput.PrimaryMouseButtonHeld())
|
||||
var draggedElem = draggedElement;
|
||||
OnRearranged?.Invoke(this, draggedElem.UserData);
|
||||
DraggedElement = null;
|
||||
RepositionChildren();
|
||||
if (AllSelected.Contains(draggedElem)) { return true; }
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector2 topOffset = CalculateTopOffset();
|
||||
var mousePos = PlayerInput.MousePosition.ToPoint();
|
||||
draggedElement.RectTransform.AbsoluteOffset = mousePos - Content.Rect.Location - dragMousePosRelativeToTopLeftCorner;
|
||||
if (CurrentDragMode != DragMode.DragOutsideBox)
|
||||
{
|
||||
OnRearranged?.Invoke(this, draggedElement.UserData);
|
||||
DraggedElement = null;
|
||||
RepositionChildren();
|
||||
var offset = draggedElement.RectTransform.AbsoluteOffset;
|
||||
draggedElement.RectTransform.AbsoluteOffset =
|
||||
isHorizontal ? new Point(offset.X, 0) : new Point(0, offset.Y);
|
||||
}
|
||||
|
||||
int index = Content.RectTransform.GetChildIndex(draggedElement.RectTransform);
|
||||
int newIndex = index;
|
||||
|
||||
Point draggedOffsetWhenReleased = Point.Zero;
|
||||
CalculateChildrenOffsets((i, offset) =>
|
||||
{
|
||||
if (index != i) { return; }
|
||||
draggedOffsetWhenReleased = offset;
|
||||
});
|
||||
Rectangle draggedRectWhenReleased = new Rectangle(Content.Rect.Location + draggedOffsetWhenReleased, draggedElement.Rect.Size);
|
||||
|
||||
void shiftIndices(
|
||||
float mousePos,
|
||||
ref int draggedRectWhenReleasedLocation,
|
||||
int draggedRectWhenReleasedSize)
|
||||
{
|
||||
while (mousePos > (draggedRectWhenReleasedLocation + draggedRectWhenReleasedSize) && newIndex < Content.CountChildren-1)
|
||||
{
|
||||
newIndex++;
|
||||
draggedRectWhenReleasedLocation += draggedRectWhenReleasedSize;
|
||||
}
|
||||
while (mousePos < draggedRectWhenReleasedLocation && newIndex > 0)
|
||||
{
|
||||
newIndex--;
|
||||
draggedRectWhenReleasedLocation -= draggedRectWhenReleasedSize;
|
||||
}
|
||||
|
||||
if (newIndex != index && AllSelected.Count > 1)
|
||||
{
|
||||
this.selected.Sort((a, b) => Content.GetChildIndex(a) - Content.GetChildIndex(b));
|
||||
int draggedPos = AllSelected.IndexOf(draggedElement);
|
||||
if (newIndex < draggedPos)
|
||||
{
|
||||
newIndex = draggedPos;
|
||||
}
|
||||
if (newIndex >= Content.CountChildren - (AllSelected.Count - draggedPos))
|
||||
{
|
||||
int max = Content.CountChildren - (AllSelected.Count - draggedPos);
|
||||
newIndex = max;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isHorizontal)
|
||||
{
|
||||
shiftIndices(
|
||||
mousePos.X,
|
||||
ref draggedRectWhenReleased.X,
|
||||
draggedRectWhenReleased.Width);
|
||||
}
|
||||
else
|
||||
{
|
||||
draggedElement.RectTransform.AbsoluteOffset = isHorizontal ?
|
||||
draggedReferenceOffset + new Point((int)PlayerInput.MousePosition.X - draggedReferenceRectangle.Center.X, 0) :
|
||||
draggedReferenceOffset + new Point(0, (int)PlayerInput.MousePosition.Y - draggedReferenceRectangle.Center.Y);
|
||||
shiftIndices(
|
||||
mousePos.Y,
|
||||
ref draggedRectWhenReleased.Y,
|
||||
draggedRectWhenReleased.Height);
|
||||
}
|
||||
|
||||
int index = Content.RectTransform.GetChildIndex(draggedElement.RectTransform);
|
||||
int currIndex = index;
|
||||
|
||||
if (isHorizontal)
|
||||
if (newIndex != index)
|
||||
{
|
||||
if (AllSelected.Count > 1)
|
||||
{
|
||||
while (currIndex > 0 && PlayerInput.MousePosition.X < draggedReferenceRectangle.Left)
|
||||
this.selected.Sort((a, b) => Content.GetChildIndex(a) - Content.GetChildIndex(b));
|
||||
int indexOfDraggedElem = AllSelected.IndexOf(draggedElement);
|
||||
IEnumerable<GUIComponent> allSelected = AllSelected;
|
||||
if (newIndex > index) { allSelected = allSelected.Reverse(); }
|
||||
foreach (var elem in allSelected)
|
||||
{
|
||||
currIndex--;
|
||||
draggedReferenceRectangle.X -= draggedReferenceRectangle.Width;
|
||||
draggedReferenceOffset.X -= draggedReferenceRectangle.Width;
|
||||
}
|
||||
while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.X > draggedReferenceRectangle.Right)
|
||||
{
|
||||
currIndex++;
|
||||
draggedReferenceRectangle.X += draggedReferenceRectangle.Width;
|
||||
draggedReferenceOffset.X += draggedReferenceRectangle.Width;
|
||||
elem.RectTransform.RepositionChildInHierarchy(newIndex + AllSelected.IndexOf(elem) - indexOfDraggedElem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (currIndex > 0 && PlayerInput.MousePosition.Y < draggedReferenceRectangle.Top)
|
||||
{
|
||||
currIndex--;
|
||||
draggedReferenceRectangle.Y -= draggedReferenceRectangle.Height;
|
||||
draggedReferenceOffset.Y -= draggedReferenceRectangle.Height;
|
||||
}
|
||||
while (currIndex < Content.CountChildren - 1 && PlayerInput.MousePosition.Y > draggedReferenceRectangle.Bottom)
|
||||
{
|
||||
currIndex++;
|
||||
draggedReferenceRectangle.Y += draggedReferenceRectangle.Height;
|
||||
draggedReferenceOffset.Y += draggedReferenceRectangle.Height;
|
||||
}
|
||||
draggedElement.RectTransform.RepositionChildInHierarchy(newIndex);
|
||||
}
|
||||
|
||||
if (currIndex != index)
|
||||
{
|
||||
draggedElement.RectTransform.RepositionChildInHierarchy(currIndex);
|
||||
HasDraggedElementIndexChanged = true;
|
||||
}
|
||||
|
||||
return;
|
||||
HasDraggedElementIndexChanged = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void UpdateChildrenRect()
|
||||
{
|
||||
if (UpdateDragging()) { return; }
|
||||
|
||||
if (SelectTop)
|
||||
{
|
||||
foreach (GUIComponent child in Content.Children)
|
||||
@@ -581,7 +692,7 @@ namespace Barotrauma
|
||||
for (int i = 0; i < Content.CountChildren; i++)
|
||||
{
|
||||
var child = Content.RectTransform.GetChild(i)?.GUIComponent;
|
||||
if (child == null || !child.Visible) { continue; }
|
||||
if (!(child is { Visible: true })) { continue; }
|
||||
|
||||
// selecting
|
||||
if (Enabled && (CanBeFocused || CanInteractWhenUnfocusable) && child.CanBeFocused && child.Rect.Contains(PlayerInput.MousePosition) && GUI.IsMouseOn(child))
|
||||
@@ -595,19 +706,15 @@ namespace Barotrauma
|
||||
if (SelectTop)
|
||||
{
|
||||
ScrollToElement(child);
|
||||
Select(i, autoScroll: false, takeKeyBoardFocus: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Select(i, autoScroll: false, takeKeyBoardFocus: true);
|
||||
}
|
||||
Select(i, autoScroll: false, takeKeyBoardFocus: true);
|
||||
}
|
||||
|
||||
if (CanDragElements && PlayerInput.PrimaryMouseButtonDown() && GUI.MouseOn == child)
|
||||
if (CurrentDragMode != DragMode.NoDragging
|
||||
&& (CurrentSelectMode != SelectMode.RequireShiftToSelectMultiple || (!PlayerInput.IsShiftDown() && !PlayerInput.IsCtrlDown()))
|
||||
&& PlayerInput.PrimaryMouseButtonDown() && GUI.MouseOn == child)
|
||||
{
|
||||
DraggedElement = child;
|
||||
draggedReferenceRectangle = child.Rect;
|
||||
draggedReferenceOffset = child.RectTransform.AbsoluteOffset;
|
||||
StartDraggingElement(child);
|
||||
}
|
||||
}
|
||||
else if (selected.Contains(child))
|
||||
@@ -686,6 +793,13 @@ namespace Barotrauma
|
||||
OnAddedToGUIUpdateList?.Invoke(this);
|
||||
}
|
||||
|
||||
public override void ForceLayoutRecalculation()
|
||||
{
|
||||
base.ForceLayoutRecalculation();
|
||||
Content.ForceLayoutRecalculation();
|
||||
ScrollBar.ForceLayoutRecalculation();
|
||||
}
|
||||
|
||||
public void RecalculateChildren()
|
||||
{
|
||||
foreach (GUIComponent child in Content.Children)
|
||||
@@ -709,8 +823,6 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void ForceUpdate() => Update((float)Timing.Step);
|
||||
|
||||
protected override void Update(float deltaTime)
|
||||
{
|
||||
if (!Visible) { return; }
|
||||
@@ -805,7 +917,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
ScrollBar.BarScroll -= (PlayerInput.ScrollWheelSpeed / 500.0f) * BarSize;
|
||||
ScrollBar.BarScroll -= (PlayerInput.ScrollWheelSpeed / 500.0f) * ScrollBar.UnclampedBarSize;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -870,6 +982,7 @@ namespace Barotrauma
|
||||
if (childIndex >= Content.CountChildren || childIndex < 0) { return; }
|
||||
|
||||
GUIComponent child = Content.GetChild(childIndex);
|
||||
if (child is null) { return; }
|
||||
|
||||
bool wasSelected = true;
|
||||
if (OnSelected != null)
|
||||
@@ -880,7 +993,8 @@ namespace Barotrauma
|
||||
|
||||
if (!wasSelected) { return; }
|
||||
|
||||
if (SelectMultiple)
|
||||
if (CurrentSelectMode == SelectMode.SelectMultiple ||
|
||||
(CurrentSelectMode == SelectMode.RequireShiftToSelectMultiple && PlayerInput.IsCtrlDown()))
|
||||
{
|
||||
if (selected.Contains(child))
|
||||
{
|
||||
@@ -891,6 +1005,23 @@ namespace Barotrauma
|
||||
selected.Add(child);
|
||||
}
|
||||
}
|
||||
else if (CurrentSelectMode == SelectMode.RequireShiftToSelectMultiple && PlayerInput.IsShiftDown())
|
||||
{
|
||||
var first = SelectedComponent ?? child;
|
||||
var last = child;
|
||||
int firstIndex = Content.GetChildIndex(first);
|
||||
int lastIndex = Content.GetChildIndex(last);
|
||||
int sgn = Math.Sign(lastIndex - firstIndex);
|
||||
selected.Clear(); selected.Add(first);
|
||||
for (int i = firstIndex + sgn; i != lastIndex; i += sgn)
|
||||
{
|
||||
if (Content.GetChild(i) is { Visible: true } interChild)
|
||||
{
|
||||
selected.Add(interChild);
|
||||
}
|
||||
}
|
||||
if (first != last) { selected.Add(last); }
|
||||
}
|
||||
else
|
||||
{
|
||||
selected.Clear();
|
||||
@@ -937,6 +1068,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void Select(IEnumerable<GUIComponent> children)
|
||||
{
|
||||
Selected = true;
|
||||
selected.Clear();
|
||||
selected.AddRange(children.Where(c => Content.Children.Contains(c)));
|
||||
foreach (var child in selected) { OnSelected?.Invoke(child, child.UserData); }
|
||||
}
|
||||
|
||||
public void Deselect()
|
||||
{
|
||||
Selected = false;
|
||||
@@ -1007,9 +1146,12 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
float minScrollBarSize = 20.0f;
|
||||
ScrollBar.UnclampedBarSize = ScrollBar.IsHorizontal ?
|
||||
Math.Min(Content.Rect.Width / (float)totalSize, 1.0f) :
|
||||
Math.Min(Content.Rect.Height / (float)totalSize, 1.0f);
|
||||
ScrollBar.BarSize = ScrollBar.IsHorizontal ?
|
||||
Math.Max(Math.Min(Content.Rect.Width / (float)totalSize, 1.0f), minScrollBarSize / Content.Rect.Width) :
|
||||
Math.Max(Math.Min(Content.Rect.Height / (float)totalSize, 1.0f), minScrollBarSize / Content.Rect.Height);
|
||||
Math.Max(ScrollBar.UnclampedBarSize, minScrollBarSize / Content.Rect.Width) :
|
||||
Math.Max(ScrollBar.UnclampedBarSize, minScrollBarSize / Content.Rect.Height);
|
||||
}
|
||||
|
||||
public override void ClearChildren()
|
||||
@@ -1052,10 +1194,11 @@ namespace Barotrauma
|
||||
int i = 0;
|
||||
foreach (GUIComponent child in Content.Children)
|
||||
{
|
||||
if (!child.Visible) continue;
|
||||
if (!child.Visible) { continue; }
|
||||
if (child == draggedElement && CurrentDragMode == DragMode.DragOutsideBox) { continue; }
|
||||
if (!IsChildInsideFrame(child))
|
||||
{
|
||||
if (lastVisible > 0) break;
|
||||
if (lastVisible > 0) { break; }
|
||||
continue;
|
||||
}
|
||||
lastVisible = i;
|
||||
@@ -1070,6 +1213,11 @@ namespace Barotrauma
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
||||
}
|
||||
|
||||
if (isDraggingElement && CurrentDragMode == DragMode.DragOutsideBox && !HideDraggedElement)
|
||||
{
|
||||
draggedElement.DrawManually(spriteBatch, alsoChildren: true, recursive: true);
|
||||
}
|
||||
|
||||
if (ScrollBarVisible)
|
||||
{
|
||||
ScrollBar.DrawManually(spriteBatch, alsoChildren: true, recursive: true);
|
||||
|
||||
@@ -183,6 +183,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ListBoxes with lots of content in them clamp the size of the scrollbar above a certain minimum size; this is the relative bar size without the clamping applied.
|
||||
/// </summary>
|
||||
public float UnclampedBarSize;
|
||||
|
||||
public float BarSize
|
||||
{
|
||||
get { return barSize; }
|
||||
@@ -299,9 +304,15 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
float barScale = 1.0f;
|
||||
if (UnclampedBarSize > 0.0f)
|
||||
{
|
||||
barScale = (UnclampedBarSize / BarSize);
|
||||
}
|
||||
|
||||
MoveButton(new Vector2(
|
||||
Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width,
|
||||
Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height));
|
||||
Math.Sign(PlayerInput.MousePosition.X - Bar.Rect.Center.X) * Bar.Rect.Width * barScale,
|
||||
Math.Sign(PlayerInput.MousePosition.Y - Bar.Rect.Center.Y) * Bar.Rect.Height * barScale));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@ namespace Barotrauma
|
||||
|
||||
public UISprite PingCircle { get; private set; }
|
||||
|
||||
public UISprite YouAreHereCircle { get; private set; }
|
||||
|
||||
public UISprite UIGlowCircular { get; private set; }
|
||||
|
||||
public UISprite UIGlowSolidCircular { get; private set; }
|
||||
@@ -253,6 +255,9 @@ namespace Barotrauma
|
||||
case "pingcircle":
|
||||
PingCircle = new UISprite(subElement);
|
||||
break;
|
||||
case "youareherecircle":
|
||||
YouAreHereCircle = new UISprite(subElement);
|
||||
break;
|
||||
case "radiation":
|
||||
RadiationSprite = new UISprite(subElement);
|
||||
break;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -376,6 +377,7 @@ namespace Barotrauma
|
||||
|
||||
public void SetTextPos()
|
||||
{
|
||||
cachedCaretPositions = ImmutableArray<Vector2>.Empty;
|
||||
if (text == null) { return; }
|
||||
|
||||
censoredText = string.IsNullOrEmpty(text) ? "" : new string('\u2022', text.Length);
|
||||
@@ -389,7 +391,7 @@ namespace Barotrauma
|
||||
|
||||
if (Wrap && rect.Width > 0)
|
||||
{
|
||||
wrappedText = ToolBox.WrapText(text, rect.Width - padding.X - padding.Z, Font, textScale, playerInput);
|
||||
wrappedText = ToolBox.WrapText(text, rect.Width - padding.X - padding.Z, Font, textScale);
|
||||
TextSize = MeasureText(wrappedText);
|
||||
}
|
||||
else if (OverflowClip)
|
||||
@@ -477,108 +479,49 @@ namespace Barotrauma
|
||||
disabledTextColor = color;
|
||||
}
|
||||
|
||||
protected List<Tuple<Vector2, int>> GetAllPositions()
|
||||
private ImmutableArray<Vector2> cachedCaretPositions = ImmutableArray<Vector2>.Empty;
|
||||
|
||||
public ImmutableArray<Vector2> GetAllCaretPositions()
|
||||
{
|
||||
float halfHeight = Font.MeasureString("T").Y * 0.5f * textScale;
|
||||
string textDrawn = Censor ? CensoredText : WrappedText;
|
||||
var positions = new List<Tuple<Vector2, int>>();
|
||||
if (textDrawn.Contains("\n"))
|
||||
if (cachedCaretPositions.Any())
|
||||
{
|
||||
string[] lines = textDrawn.Split('\n');
|
||||
int index = 0;
|
||||
int totalIndex = 0;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
string line = lines[i];
|
||||
totalIndex += line.Length;
|
||||
float totalTextHeight = Font.MeasureString(textDrawn.Substring(0, totalIndex)).Y * textScale;
|
||||
for (int j = 0; j <= line.Length; j++)
|
||||
{
|
||||
Vector2 lineTextSize = Font.MeasureString(line.Substring(0, j)) * textScale;
|
||||
Vector2 indexPos = new Vector2(lineTextSize.X, totalTextHeight - halfHeight) + TextPos - Origin * textScale;
|
||||
//DebugConsole.NewMessage($"index: {index}, pos: {indexPos}", Color.AliceBlue);
|
||||
positions.Add(new Tuple<Vector2, int>(indexPos, index + j));
|
||||
}
|
||||
index = totalIndex;
|
||||
}
|
||||
return cachedCaretPositions;
|
||||
}
|
||||
else
|
||||
{
|
||||
textDrawn = Censor ? CensoredText : Text;
|
||||
for (int i = 0; i <= Text.Length; i++)
|
||||
{
|
||||
Vector2 textSize = Font.MeasureString(textDrawn.Substring(0, i)) * textScale;
|
||||
Vector2 indexPos = new Vector2(textSize.X, textSize.Y - halfHeight) + TextPos - Origin * textScale;
|
||||
//DebugConsole.NewMessage($"index: {i}, pos: {indexPos}", Color.WhiteSmoke);
|
||||
positions.Add(new Tuple<Vector2, int>(indexPos, i));
|
||||
}
|
||||
}
|
||||
return positions;
|
||||
string textDrawn = Censor ? CensoredText : Text;
|
||||
float w = Wrap
|
||||
? (Rect.Width - Padding.X - Padding.Z) / TextScale
|
||||
: float.PositiveInfinity;
|
||||
Font.WrapText(textDrawn, w, out Vector2[] positions);
|
||||
cachedCaretPositions = positions.Select(p => p * TextScale + TextPos - Origin * TextScale).ToImmutableArray();
|
||||
return cachedCaretPositions;
|
||||
}
|
||||
|
||||
public int GetCaretIndexFromScreenPos(Vector2 pos)
|
||||
public int GetCaretIndexFromScreenPos(in Vector2 pos)
|
||||
{
|
||||
return GetCaretIndexFromLocalPos(pos - Rect.Location.ToVector2());
|
||||
}
|
||||
|
||||
public int GetCaretIndexFromLocalPos(Vector2 pos)
|
||||
public int GetCaretIndexFromLocalPos(in Vector2 pos)
|
||||
{
|
||||
var positions = GetAllPositions();
|
||||
if (positions.Count == 0) { return 0; }
|
||||
float halfHeight = Font.MeasureString("T").Y * 0.5f * textScale;
|
||||
var positions = GetAllCaretPositions();
|
||||
if (positions.Length == 0) { return 0; }
|
||||
|
||||
var currPosition = positions[0];
|
||||
|
||||
float topY = positions.Min(p => p.Item1.Y);
|
||||
|
||||
for (int i = 1; i < positions.Count; i++)
|
||||
float closestXDist = float.PositiveInfinity;
|
||||
float closestYDist = float.PositiveInfinity;
|
||||
int closestIndex = -1;
|
||||
for (int i = 0; i < positions.Length; i++)
|
||||
{
|
||||
var p1 = positions[i];
|
||||
var p2 = currPosition;
|
||||
|
||||
float diffY = Math.Abs(p1.Item1.Y - pos.Y) - Math.Abs(p2.Item1.Y - pos.Y);
|
||||
if (diffY < -3.0f)
|
||||
float xDist = Math.Abs(pos.X - positions[i].X);
|
||||
float yDist = Math.Abs(pos.Y - (positions[i].Y + Font.LineHeight * 0.5f));
|
||||
if (yDist < closestYDist || (MathUtils.NearlyEqual(yDist, closestYDist) && xDist < closestXDist))
|
||||
{
|
||||
currPosition = p1;
|
||||
continue;
|
||||
}
|
||||
else if (diffY > 3.0f)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
diffY = Math.Abs(p1.Item1.Y - pos.Y);
|
||||
if (diffY < halfHeight || (p1.Item1.Y == topY && pos.Y < topY))
|
||||
{
|
||||
//we are on this line, select the nearest character
|
||||
float diffX = Math.Abs(p1.Item1.X - pos.X) - Math.Abs(p2.Item1.X - pos.X);
|
||||
if (diffX < -1.0f)
|
||||
{
|
||||
currPosition = p1; continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//we are on a different line, preserve order
|
||||
if (p1.Item2 < p2.Item2)
|
||||
{
|
||||
if (p1.Item1.Y > pos.Y) { currPosition = p1; }
|
||||
}
|
||||
else if (p1.Item2 > p2.Item2)
|
||||
{
|
||||
if (p1.Item1.Y < pos.Y) { currPosition = p1; }
|
||||
}
|
||||
continue;
|
||||
}
|
||||
closestIndex = i;
|
||||
closestXDist = xDist;
|
||||
closestYDist = yDist;
|
||||
}
|
||||
}
|
||||
//GUI.AddMessage($"index: {posIndex.Item2}, pos: {posIndex.Item1}", Color.WhiteSmoke);
|
||||
return currPosition != null ? currPosition.Item2 : Text.Length;
|
||||
|
||||
return closestIndex >= 0 ? closestIndex : Text.Length;
|
||||
}
|
||||
|
||||
protected override void Update(float deltaTime)
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Barotrauma
|
||||
private int? maxTextLength;
|
||||
|
||||
private int _caretIndex;
|
||||
private int CaretIndex
|
||||
public int CaretIndex
|
||||
{
|
||||
get { return _caretIndex; }
|
||||
set
|
||||
@@ -343,34 +343,23 @@ namespace Barotrauma
|
||||
|
||||
private void CalculateCaretPos()
|
||||
{
|
||||
string textDrawn = Censor ? textBlock.CensoredText : textBlock.WrappedText;
|
||||
if (textDrawn.Contains("\n"))
|
||||
if (Censor || !Wrap)
|
||||
{
|
||||
string[] lines = textDrawn.Split('\n');
|
||||
int totalIndex = 0;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
{
|
||||
int currentLineLength = lines[i].Length;
|
||||
totalIndex += currentLineLength;
|
||||
// The caret is on this line
|
||||
if (CaretIndex < totalIndex || totalIndex == textBlock.Text.Length)
|
||||
{
|
||||
int diff = totalIndex - CaretIndex;
|
||||
int index = currentLineLength - diff;
|
||||
Vector2 lineTextSize = Font.MeasureString(lines[i].Substring(0, index)) * TextBlock.TextScale;
|
||||
Vector2 lastLineSize = Font.MeasureString(lines[i]) * TextBlock.TextScale;
|
||||
float totalTextHeight = Font.MeasureString(textDrawn.Substring(0, totalIndex)).Y * TextBlock.TextScale;
|
||||
caretPos = new Vector2(lineTextSize.X, totalTextHeight - lastLineSize.Y) + textBlock.TextPos - textBlock.Origin * TextBlock.TextScale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string textDrawn = textBlock.CensoredText;
|
||||
CaretIndex = Math.Min(CaretIndex, textDrawn.Length);
|
||||
textDrawn = Censor ? textBlock.CensoredText : textBlock.Text;
|
||||
Vector2 textSize = Font.MeasureString(textDrawn[..CaretIndex]) * TextBlock.TextScale;
|
||||
caretPos = new Vector2(textSize.X, 0) + textBlock.TextPos - textBlock.Origin * TextBlock.TextScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
CaretIndex = Math.Min(CaretIndex, textDrawn.Length);
|
||||
textDrawn = Censor ? textBlock.CensoredText : textBlock.Text;
|
||||
Vector2 textSize = Font.MeasureString(textDrawn.Substring(0, CaretIndex)) * TextBlock.TextScale;
|
||||
caretPos = new Vector2(textSize.X, 0) + textBlock.TextPos - textBlock.Origin * TextBlock.TextScale;
|
||||
CaretIndex = Math.Min(CaretIndex, textBlock.Text.Length);
|
||||
textBlock.Font.WrapText(
|
||||
textBlock.Text,
|
||||
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
|
||||
CaretIndex,
|
||||
out Vector2 requestedCharPos);
|
||||
caretPos = requestedCharPos * TextBlock.TextScale + textBlock.TextPos - textBlock.Origin * TextBlock.TextScale;
|
||||
}
|
||||
caretPosDirty = false;
|
||||
}
|
||||
@@ -383,6 +372,7 @@ namespace Barotrauma
|
||||
memento.Store(Text);
|
||||
}
|
||||
CaretIndex = forcedCaretIndex == - 1 ? textBlock.GetCaretIndexFromScreenPos(PlayerInput.MousePosition) : forcedCaretIndex;
|
||||
CalculateCaretPos();
|
||||
ClearSelection();
|
||||
selected = true;
|
||||
GUI.KeyboardDispatcher.Subscriber = this;
|
||||
@@ -538,59 +528,37 @@ namespace Barotrauma
|
||||
if (textBlock.WrappedText.Contains("\n"))
|
||||
{
|
||||
// Multiline selection
|
||||
string[] lines = textBlock.WrappedText.Split('\n');
|
||||
int totalIndex = 0;
|
||||
int previousCharacters = 0;
|
||||
Vector2 offset = textBlock.TextPos - textBlock.Origin;
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
var characterPositions = textBlock.GetAllCaretPositions();
|
||||
(int startIndex, int endIndex) = selectionStartIndex < selectionEndIndex
|
||||
? (selectionStartIndex, selectionEndIndex)
|
||||
: (selectionEndIndex, selectionStartIndex);
|
||||
endIndex--;
|
||||
|
||||
void drawRect(Vector2 topLeft, Vector2 bottomRight)
|
||||
{
|
||||
string currentLine = lines[i];
|
||||
int currentLineLength = currentLine.Length;
|
||||
totalIndex += currentLineLength;
|
||||
bool containsSelection = IsLeftToRight
|
||||
? selectionStartIndex < totalIndex && selectionEndIndex > previousCharacters
|
||||
: selectionEndIndex < totalIndex && selectionStartIndex > previousCharacters;
|
||||
if (containsSelection)
|
||||
{
|
||||
Vector2 currentLineSize = Font.MeasureString(currentLine) * TextBlock.TextScale;
|
||||
if ((IsLeftToRight && selectionStartIndex < previousCharacters && selectionEndIndex > totalIndex)
|
||||
|| !IsLeftToRight && selectionEndIndex < previousCharacters && selectionStartIndex > totalIndex)
|
||||
{
|
||||
// select the whole line
|
||||
Vector2 topLeft = offset + new Vector2(0, currentLineSize.Y * i);
|
||||
GUI.DrawRectangle(spriteBatch, Rect.Location.ToVector2() + topLeft, currentLineSize, SelectionColor, isFilled: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsLeftToRight)
|
||||
{
|
||||
bool selectFromTheBeginning = selectionStartIndex <= previousCharacters;
|
||||
int startIndex = selectFromTheBeginning ? 0 : Math.Abs(selectionStartIndex - previousCharacters);
|
||||
int endIndex = Math.Abs(selectionEndIndex - previousCharacters);
|
||||
int characters = Math.Min(endIndex - startIndex, currentLineLength - startIndex);
|
||||
Vector2 selectedTextSize = Font.MeasureString(currentLine.Substring(startIndex, characters)) * TextBlock.TextScale;
|
||||
Vector2 topLeft = selectFromTheBeginning
|
||||
? new Vector2(offset.X, offset.Y + currentLineSize.Y * i)
|
||||
: new Vector2(selectionStartPos.X, offset.Y + currentLineSize.Y * i);
|
||||
GUI.DrawRectangle(spriteBatch, Rect.Location.ToVector2() + topLeft, selectedTextSize, SelectionColor, isFilled: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool selectFromTheBeginning = selectionStartIndex >= totalIndex;
|
||||
bool selectFromTheStart = selectionEndIndex <= previousCharacters;
|
||||
int startIndex = selectFromTheBeginning ? currentLineLength : Math.Abs(selectionStartIndex - previousCharacters);
|
||||
int endIndex = selectFromTheStart ? 0 : Math.Abs(selectionEndIndex - previousCharacters);
|
||||
int characters = Math.Min(Math.Abs(endIndex - startIndex), currentLineLength);
|
||||
Vector2 selectedTextSize = Font.MeasureString(currentLine.Substring(endIndex, characters)) * TextBlock.TextScale;
|
||||
Vector2 topLeft = selectFromTheBeginning
|
||||
? new Vector2(offset.X + currentLineSize.X - selectedTextSize.X, offset.Y + currentLineSize.Y * i)
|
||||
: new Vector2(selectionStartPos.X - selectedTextSize.X, offset.Y + currentLineSize.Y * i);
|
||||
GUI.DrawRectangle(spriteBatch, Rect.Location.ToVector2() + topLeft, selectedTextSize, SelectionColor, isFilled: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
previousCharacters = totalIndex;
|
||||
int minWidth = GUI.IntScale(5);
|
||||
if (bottomRight.X - topLeft.X < minWidth) { bottomRight.X = topLeft.X + minWidth; }
|
||||
GUI.DrawRectangle(spriteBatch,
|
||||
Rect.Location.ToVector2() + topLeft,
|
||||
bottomRight - topLeft,
|
||||
SelectionColor, isFilled: true);
|
||||
}
|
||||
|
||||
Vector2 topLeft = characterPositions[startIndex];
|
||||
for (int i = startIndex+1; i <= endIndex; i++)
|
||||
{
|
||||
Vector2 currPos = characterPositions[i];
|
||||
if (!MathUtils.NearlyEqual(topLeft.Y, currPos.Y))
|
||||
{
|
||||
Vector2 bottomRight = characterPositions[i - 1];
|
||||
bottomRight += Font.MeasureChar(Text[i - 1]);
|
||||
drawRect(topLeft, bottomRight);
|
||||
topLeft = currPos;
|
||||
}
|
||||
}
|
||||
Vector2 finalBottomRight = characterPositions[endIndex];
|
||||
finalBottomRight += Font.MeasureChar(Text[endIndex]);
|
||||
drawRect(topLeft, finalBottomRight);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -728,8 +696,15 @@ namespace Barotrauma
|
||||
{
|
||||
InitSelectionStart();
|
||||
}
|
||||
float lineHeight = Font.MeasureString("T").Y * TextBlock.TextScale;
|
||||
int newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y - lineHeight));
|
||||
float lineHeight = Font.LineHeight * TextBlock.TextScale;
|
||||
int newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y - lineHeight * 0.5f));
|
||||
textBlock.Font.WrapText(
|
||||
textBlock.Text,
|
||||
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
|
||||
newIndex,
|
||||
out Vector2 requestedCharPos);
|
||||
requestedCharPos *= TextBlock.TextScale;
|
||||
if (MathUtils.NearlyEqual(requestedCharPos.Y, caretPos.Y)) { newIndex = 0; }
|
||||
CaretIndex = newIndex;
|
||||
caretTimer = 0;
|
||||
HandleSelection();
|
||||
@@ -739,8 +714,15 @@ namespace Barotrauma
|
||||
{
|
||||
InitSelectionStart();
|
||||
}
|
||||
lineHeight = Font.MeasureString("T").Y * TextBlock.TextScale;
|
||||
newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y + lineHeight));
|
||||
lineHeight = Font.LineHeight * TextBlock.TextScale;
|
||||
newIndex = textBlock.GetCaretIndexFromLocalPos(new Vector2(caretPos.X, caretPos.Y + lineHeight * 1.5f));
|
||||
textBlock.Font.WrapText(
|
||||
textBlock.Text,
|
||||
(textBlock.Rect.Width - textBlock.Padding.X - textBlock.Padding.Z) / TextBlock.TextScale,
|
||||
newIndex,
|
||||
out Vector2 requestedCharPos2);
|
||||
requestedCharPos2 *= TextBlock.TextScale;
|
||||
if (MathUtils.NearlyEqual(requestedCharPos2.Y, caretPos.Y)) { newIndex = Text.Length; }
|
||||
CaretIndex = newIndex;
|
||||
caretTimer = 0;
|
||||
HandleSelection();
|
||||
@@ -803,6 +785,7 @@ namespace Barotrauma
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (caretPosDirty) { CalculateCaretPos(); }
|
||||
OnKeyHit?.Invoke(this, key);
|
||||
void HandleSelection()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma
|
||||
@@ -37,39 +38,44 @@ namespace Barotrauma
|
||||
values[0] = newValue;
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle rect, float? maxVal, float xOffset, Color color)
|
||||
public delegate void GraphDelegate(SpriteBatch spriteBatch, float value, int order, Vector2 position);
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, Rectangle rect, float? maxValue = null, float xOffset = 0, Color? color = null, GraphDelegate doForEachValue = null)
|
||||
{
|
||||
color ??= Color.White;
|
||||
float graphMaxVal = 1.0f;
|
||||
if (maxVal == null)
|
||||
if (maxValue == null)
|
||||
{
|
||||
graphMaxVal = LargestValue();
|
||||
}
|
||||
else if (maxVal > 0.0f)
|
||||
else if (maxValue > 0.0f)
|
||||
{
|
||||
graphMaxVal = (float)maxVal;
|
||||
graphMaxVal = (float)maxValue;
|
||||
}
|
||||
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.White);
|
||||
|
||||
if (values.Length == 0) return;
|
||||
if (values.Length == 0) { return; }
|
||||
|
||||
float lineWidth = (float)rect.Width / (float)(values.Length - 2);
|
||||
float yScale = (float)rect.Height / graphMaxVal;
|
||||
float lineWidth = rect.Width / (float)(values.Length - 2);
|
||||
float yScale = rect.Height / graphMaxVal;
|
||||
|
||||
Vector2 prevPoint = new Vector2(rect.Right, rect.Bottom - (values[1] + (values[0] - values[1]) * xOffset) * yScale);
|
||||
float currX = rect.Right - ((xOffset - 1.0f) * lineWidth);
|
||||
for (int i = 1; i < values.Length - 1; i++)
|
||||
{
|
||||
float value = values[i];
|
||||
currX -= lineWidth;
|
||||
Vector2 newPoint = new Vector2(currX, rect.Bottom - values[i] * yScale);
|
||||
GUI.DrawLine(spriteBatch, prevPoint, newPoint - new Vector2(1.0f, 0), color);
|
||||
Vector2 newPoint = new Vector2(currX, rect.Bottom - value * yScale);
|
||||
GUI.DrawLine(spriteBatch, prevPoint, newPoint - new Vector2(1.0f, 0), color.Value);
|
||||
prevPoint = newPoint;
|
||||
doForEachValue?.Invoke(spriteBatch, value, i, newPoint);
|
||||
}
|
||||
|
||||
Vector2 lastPoint = new Vector2(rect.X,
|
||||
rect.Bottom - (values[values.Length - 1] + (values[values.Length - 2] - values[values.Length - 1]) * xOffset) * yScale);
|
||||
|
||||
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color);
|
||||
int lastIndex = values.Length - 1;
|
||||
float lastValue = values[lastIndex];
|
||||
Vector2 lastPoint = new Vector2(rect.X, rect.Bottom - (lastValue + (values[values.Length - 2] - lastValue) * xOffset) * yScale);
|
||||
GUI.DrawLine(spriteBatch, prevPoint, lastPoint, color.Value);
|
||||
doForEachValue?.Invoke(spriteBatch, lastValue, lastIndex, lastPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,11 +379,42 @@ namespace Barotrauma
|
||||
|
||||
if (currSplashScreen.IsPlaying)
|
||||
{
|
||||
graphics.Clear(Color.Black);
|
||||
float videoAspectRatio = (float)currSplashScreen.Width / (float)currSplashScreen.Height;
|
||||
int width; int height;
|
||||
if (GameMain.GraphicsHeight * videoAspectRatio > GameMain.GraphicsWidth)
|
||||
{
|
||||
width = GameMain.GraphicsWidth;
|
||||
height = (int)(GameMain.GraphicsWidth / videoAspectRatio);
|
||||
}
|
||||
else
|
||||
{
|
||||
width = (int)(GameMain.GraphicsHeight * videoAspectRatio);
|
||||
height = GameMain.GraphicsHeight;
|
||||
}
|
||||
|
||||
spriteBatch.Begin();
|
||||
spriteBatch.Draw(currSplashScreen.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White);
|
||||
spriteBatch.Draw(
|
||||
currSplashScreen.GetTexture(),
|
||||
destinationRectangle: new Rectangle(
|
||||
GameMain.GraphicsWidth / 2 - width / 2,
|
||||
GameMain.GraphicsHeight / 2 - height / 2,
|
||||
width,
|
||||
height),
|
||||
sourceRectangle: new Rectangle(0, 0, currSplashScreen.Width, currSplashScreen.Height),
|
||||
Color.White,
|
||||
rotation: 0.0f,
|
||||
origin: Vector2.Zero,
|
||||
SpriteEffects.None,
|
||||
layerDepth: 0.0f);
|
||||
spriteBatch.End();
|
||||
|
||||
if (DateTime.Now > videoStartTime + new TimeSpan(0, 0, 0, 0, milliseconds: 500) && GameMain.WindowActive && (PlayerInput.KeyHit(Keys.Escape) || PlayerInput.KeyHit(Keys.Space) || PlayerInput.KeyHit(Keys.Enter) || PlayerInput.PrimaryMouseButtonDown()))
|
||||
if (DateTime.Now > videoStartTime + new TimeSpan(0, 0, 0, 0, milliseconds: 500)
|
||||
&& GameMain.WindowActive
|
||||
&& (PlayerInput.KeyHit(Keys.Escape)
|
||||
|| PlayerInput.KeyHit(Keys.Space)
|
||||
|| PlayerInput.KeyHit(Keys.Enter)
|
||||
|| PlayerInput.PrimaryMouseButtonDown()))
|
||||
{
|
||||
currSplashScreen.Dispose(); currSplashScreen = null;
|
||||
}
|
||||
@@ -395,7 +426,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
bool drawn;
|
||||
public IEnumerable<object> DoLoading(IEnumerable<object> loader)
|
||||
public IEnumerable<CoroutineStatus> DoLoading(IEnumerable<CoroutineStatus> loader)
|
||||
{
|
||||
drawn = false;
|
||||
LoadState = null;
|
||||
|
||||
@@ -732,7 +732,7 @@ namespace Barotrauma
|
||||
CoroutineManager.StartCoroutine(DoScaleAnimation(targetSize, duration));
|
||||
}
|
||||
|
||||
private IEnumerable<object> DoMoveAnimation(Point targetPos, float duration)
|
||||
private IEnumerable<CoroutineStatus> DoMoveAnimation(Point targetPos, float duration)
|
||||
{
|
||||
Vector2 startPos = AbsoluteOffset.ToVector2();
|
||||
float t = 0.0f;
|
||||
@@ -746,7 +746,7 @@ namespace Barotrauma
|
||||
animTargetPos = null;
|
||||
yield return CoroutineStatus.Success;
|
||||
}
|
||||
private IEnumerable<object> DoScaleAnimation(Point targetSize, float duration)
|
||||
private IEnumerable<CoroutineStatus> DoScaleAnimation(Point targetSize, float duration)
|
||||
{
|
||||
Vector2 startSize = NonScaledSize.ToVector2();
|
||||
float t = 0.0f;
|
||||
|
||||
@@ -151,9 +151,8 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
public static void DrawPoint(this SpriteBatch spriteBatch, Vector2 position, Color color, float size = 1f)
|
||||
{
|
||||
var scale = Vector2.One * size;
|
||||
var offset = new Vector2(0.5f) - new Vector2(size * 0.5f);
|
||||
spriteBatch.Draw(GetTexture(spriteBatch), position + offset, null, color, 0.0f, Vector2.Zero, Vector2.One, SpriteEffects.None, 0);
|
||||
spriteBatch.Draw(GetTexture(spriteBatch), position + offset, null, color, 0.0f, Vector2.Zero, new Vector2(size), SpriteEffects.None, 0);
|
||||
}
|
||||
|
||||
public static void DrawCircle(this SpriteBatch spriteBatch, Vector2 center, float radius, int sides, Color color,
|
||||
|
||||
@@ -266,7 +266,7 @@ namespace Barotrauma
|
||||
};
|
||||
if (balanceAfterTransaction != CurrentLocation.StoreCurrentBalance)
|
||||
{
|
||||
var newStatus = Location.GetStoreBalanceStatus(balanceAfterTransaction);
|
||||
var newStatus = CurrentLocation.GetStoreBalanceStatus(balanceAfterTransaction);
|
||||
if (CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier != newStatus.SellPriceModifier)
|
||||
{
|
||||
string tooltipTag = newStatus.SellPriceModifier > CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier ?
|
||||
|
||||
@@ -471,7 +471,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
// Initial submarine selection needs a slight wait to allow the layoutgroups to place content properly
|
||||
private IEnumerable<object> SelectOwnSubmarineWithDelay(SubmarineInfo info, SubmarineDisplayContent display)
|
||||
private IEnumerable<CoroutineStatus> SelectOwnSubmarineWithDelay(SubmarineInfo info, SubmarineDisplayContent display)
|
||||
{
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
SelectSubmarine(info, display.background.Rect);
|
||||
|
||||
@@ -1541,13 +1541,41 @@ namespace Barotrauma
|
||||
GUITextBlock.AutoScaleAndNormalize(skillNames);
|
||||
}
|
||||
|
||||
private bool HasUnlockedAllTalents(Character controlledCharacter)
|
||||
{
|
||||
if (TalentTree.JobTalentTrees.TryGetValue(controlledCharacter.Info.Job.Prefab.Identifier, out TalentTree talentTree))
|
||||
{
|
||||
foreach (TalentSubTree talentSubTree in talentTree.TalentSubTrees)
|
||||
{
|
||||
foreach (TalentOption talentOption in talentSubTree.TalentOptionStages)
|
||||
{
|
||||
if (talentOption.Talents.None(t => controlledCharacter.HasTalent(t.Identifier)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UpdateTalentButtons()
|
||||
{
|
||||
Character controlledCharacter = Character.Controlled;
|
||||
if (controlledCharacter?.Info == null) { return; }
|
||||
|
||||
experienceText.Text = $"{controlledCharacter.Info.ExperiencePoints - controlledCharacter.Info.GetExperienceRequiredForCurrentLevel()} / {controlledCharacter.Info.GetExperienceRequiredToLevelUp() - controlledCharacter.Info.GetExperienceRequiredForCurrentLevel()}";
|
||||
experienceBar.BarSize = controlledCharacter.Info.GetProgressTowardsNextLevel();
|
||||
//experienceBar.ToolTip = $"{controlledCharacter.Info.ExperiencePoints - controlledCharacter.Info.GetExperienceRequiredForCurrentLevel()} / {controlledCharacter.Info.GetExperienceRequiredToLevelUp() - controlledCharacter.Info.GetExperienceRequiredForCurrentLevel()}";
|
||||
bool unlockedAllTalents = HasUnlockedAllTalents(controlledCharacter);
|
||||
|
||||
if (unlockedAllTalents)
|
||||
{
|
||||
experienceText.Text = string.Empty;
|
||||
experienceBar.BarSize = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
experienceText.Text = $"{controlledCharacter.Info.ExperiencePoints - controlledCharacter.Info.GetExperienceRequiredForCurrentLevel()} / {controlledCharacter.Info.GetExperienceRequiredToLevelUp() - controlledCharacter.Info.GetExperienceRequiredForCurrentLevel()}";
|
||||
experienceBar.BarSize = controlledCharacter.Info.GetProgressTowardsNextLevel();
|
||||
}
|
||||
|
||||
selectedTalents = TalentTree.CheckTalentSelection(controlledCharacter, selectedTalents);
|
||||
|
||||
@@ -1555,7 +1583,11 @@ namespace Barotrauma
|
||||
|
||||
int talentCount = selectedTalents.Count - controlledCharacter.Info.GetUnlockedTalentsInTree().Count();
|
||||
|
||||
if (talentCount > 0)
|
||||
if (unlockedAllTalents)
|
||||
{
|
||||
talentPointText.SetRichText($"‖color:{XMLExtensions.ToStringHex(Color.Gray)}‖{TextManager.Get("talentmenu.alltalentsunlocked")}‖color:end‖");
|
||||
}
|
||||
else if (talentCount > 0)
|
||||
{
|
||||
string pointsUsed = $"‖color:{XMLExtensions.ColorToString(GUI.Style.Red)}‖{-talentCount}‖color:end‖";
|
||||
string localizedString = TextManager.GetWithVariables("talentmenu.points.spending", new []{ "[amount]", "[used]" }, new []{ pointsLeft, pointsUsed});
|
||||
|
||||
Reference in New Issue
Block a user