Release 1.9.7.0 - Summer Update 2025

This commit is contained in:
Regalis11
2025-06-17 16:38:11 +03:00
parent 22227f13e5
commit ea5a2bc693
297 changed files with 7344 additions and 2421 deletions
@@ -11,6 +11,14 @@ namespace Barotrauma
{
abstract class CampaignSetupUI
{
protected enum SaveSortingType
{
LastPlayedDescending, LastPlayedAscending,
NameDescending, NameAscending
}
private const SaveSortingType DefaultSaveSortingType = SaveSortingType.LastPlayedDescending;
protected readonly GUIComponent newGameContainer, loadGameContainer;
protected GUIListBox saveList;
@@ -111,24 +119,54 @@ namespace Barotrauma
return saveFrame;
}
protected void SortSaveList()
protected void SortSaveList(SaveSortingType sortingType = DefaultSaveSortingType) => saveList?.Content.RectTransform.SortChildren((rect1, rect2) =>
{
saveList.Content.RectTransform.SortChildren((c1, c2) =>
if (rect1.GUIComponent.UserData is not CampaignMode.SaveInfo file1 || rect2.GUIComponent.UserData is not CampaignMode.SaveInfo file2) { return 0; }
if (!file1.SaveTime.TryUnwrap(out SerializableDateTime file1WriteTime) || !file2.SaveTime.TryUnwrap(out SerializableDateTime file2WriteTime)) { return 0; }
return sortingType switch
{
if (c1.GUIComponent.UserData is not CampaignMode.SaveInfo file1
|| c2.GUIComponent.UserData is not CampaignMode.SaveInfo file2)
{
return 0;
}
SaveSortingType.LastPlayedDescending => file2WriteTime.CompareTo(file1WriteTime),
SaveSortingType.LastPlayedAscending => file1WriteTime.CompareTo(file2WriteTime),
SaveSortingType.NameDescending => string.Compare(Path.GetFileNameWithoutExtension(file1.FilePath), Path.GetFileNameWithoutExtension(file2.FilePath), StringComparison.OrdinalIgnoreCase),
SaveSortingType.NameAscending => string.Compare(Path.GetFileNameWithoutExtension(file2.FilePath), Path.GetFileNameWithoutExtension(file1.FilePath), StringComparison.OrdinalIgnoreCase),
_ => 0
};
});
if (!file1.SaveTime.TryUnwrap(out var file1WriteTime)
|| !file2.SaveTime.TryUnwrap(out var file2WriteTime))
protected void CreateSaveFilteringHeader(GUIComponent parent)
{
GUILayoutGroup container = new(new RectTransform(Vector2.UnitX, parent.RectTransform), true) { Stretch = true };
GUI.CreateFilterBox(new RectTransform(new Vector2(0.6f, 1f), container.RectTransform)).OnTextChanged += (_, filterText) =>
{
filterText = filterText.Trim();
foreach (GUIComponent saveElement in saveList.Content.Children)
{
return 0;
if (saveElement.UserData is not CampaignMode.SaveInfo saveInfo) { continue; }
saveElement.Visible = filterText.IsNullOrEmpty()
|| Path.GetFileNameWithoutExtension(saveInfo.FilePath).Contains(filterText, StringComparison.OrdinalIgnoreCase);
}
return file2WriteTime.CompareTo(file1WriteTime);
});
return true;
};
SaveSortingType[] sortingTypes = Enum.GetValues<SaveSortingType>();
GUIDropDown dropDown = new(new RectTransform(new Vector2(0.4f, 1f), container.RectTransform), elementCount: sortingTypes.Length)
{
OnSelected = (_, data) =>
{
SortSaveList((SaveSortingType)data);
return true;
}
};
foreach (SaveSortingType sortingType in sortingTypes)
{
dropDown.AddItem(TextManager.Get($"SaveSortingType.{sortingType}"), sortingType);
}
dropDown.SelectItem(DefaultSaveSortingType);
container.RectTransform.MinSize = (0, container.Children.Max(child => child.Rect.Size.Y));
}
public struct CampaignSettingElements
@@ -217,6 +217,8 @@ namespace Barotrauma
RelativeSpacing = 0.03f
};
CreateSaveFilteringHeader(leftColumn);
saveList = new GUIListBox(new RectTransform(Vector2.One, leftColumn.RectTransform))
{
PlaySoundOnSelect = true,
@@ -320,14 +320,14 @@ namespace Barotrauma
if (string.IsNullOrWhiteSpace(sender.Text))
{
characterInfo.Name = characterInfo.GetRandomName(Rand.RandSync.Unsynced);
sender.Text = characterInfo.Name;
sender.UserData = "random";
}
else
{
characterInfo.Name = sender.Text;
characterInfo.Rename(sender.Text);
sender.UserData = "user";
}
sender.Text = characterInfo.Name;
};
characterName.OnEnterPressed += (sender, text) =>
{
@@ -594,6 +594,8 @@ namespace Barotrauma
RelativeSpacing = 0.03f
};
CreateSaveFilteringHeader(leftColumn);
saveList = new GUIListBox(new RectTransform(Vector2.One, leftColumn.RectTransform))
{
PlaySoundOnSelect = true,
@@ -352,7 +352,7 @@ namespace Barotrauma
Location currentDisplayLocation = Campaign.GetCurrentDisplayLocation();
if (connection != null && connection.Locations.Contains(currentDisplayLocation))
{
List<Mission> availableMissions = currentDisplayLocation.GetMissionsInConnection(connection).ToList();
List<Mission> availableMissions = currentDisplayLocation.GetMissionsInConnection(connection).Where(m => m.Prefab.ShowInMenus || GameMain.DebugDraw).ToList();
if (!availableMissions.Any()) { availableMissions.Insert(0, null); }
@@ -389,19 +389,26 @@ namespace Barotrauma
AbsoluteSpacing = GUI.IntScale(5)
};
var missionName = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission?.Name ?? TextManager.Get("NoMission"), font: GUIStyle.SubHeadingFont, wrap: true);
missionName.RectTransform.MinSize = new Point(0, GUI.IntScale(15));
LocalizedString missionName = mission?.Name ?? TextManager.Get("NoMission");
if (GameMain.DebugDraw && mission != null)
{
if (!mission.Prefab.ShowInMenus) { missionName = $"[HIDDEN] {missionName}"; }
missionName += $" ({mission.Prefab.Identifier})";
}
var missionNameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), missionName, font: GUIStyle.SubHeadingFont, wrap: true);
missionNameBlock.RectTransform.MinSize = new Point(0, GUI.IntScale(15));
if (mission == null)
{
missionTextContent.RectTransform.MinSize = missionName.RectTransform.MinSize = new Point(0, GUI.IntScale(35));
missionTextContent.RectTransform.MinSize = missionNameBlock.RectTransform.MinSize = new Point(0, GUI.IntScale(35));
missionTextContent.ChildAnchor = Anchor.CenterLeft;
}
else
{
GUITickBox tickBox = null;
if (!isMissionInNextLocation)
if (!isMissionInNextLocation && mission.Prefab.ShowInMenus)
{
tickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, missionName.RectTransform, anchor: Anchor.CenterLeft, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionName.Padding.X, 0) }, label: string.Empty)
tickBox = new GUITickBox(new RectTransform(Vector2.One * 0.9f, missionNameBlock.RectTransform, anchor: Anchor.CenterLeft, scaleBasis: ScaleBasis.Smallest) { AbsoluteOffset = new Point((int)missionNameBlock.Padding.X, 0) }, label: string.Empty)
{
UserData = mission,
Selected = Campaign.Map.CurrentLocation?.SelectedMissions.Contains(mission) ?? false
@@ -443,7 +450,7 @@ namespace Barotrauma
GUILayoutGroup difficultyIndicatorGroup = null;
if (mission.Difficulty.HasValue)
{
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.9f), missionName.RectTransform, anchor: Anchor.CenterRight) { AbsoluteOffset = new Point((int)missionName.Padding.Z, 0) },
difficultyIndicatorGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.9f), missionNameBlock.RectTransform, anchor: Anchor.CenterRight) { AbsoluteOffset = new Point((int)missionNameBlock.Padding.Z, 0) },
isHorizontal: true, childAnchor: Anchor.CenterRight)
{
AbsoluteSpacing = 1,
@@ -465,11 +472,11 @@ namespace Barotrauma
float extraPadding = 0;// 0.8f * tickBox.Rect.Width;
float extraZPadding = difficultyIndicatorGroup != null ? mission.Difficulty.Value * (difficultyIndicatorGroup.Children.First().Rect.Width + difficultyIndicatorGroup.AbsoluteSpacing) : 0;
missionName.Padding = new Vector4(missionName.Padding.X + (tickBox?.Rect.Width ?? 0) * 1.2f + extraPadding,
missionName.Padding.Y,
missionName.Padding.Z + extraZPadding + extraPadding,
missionName.Padding.W);
missionName.CalculateHeightFromText();
missionNameBlock.Padding = new Vector4(missionNameBlock.Padding.X + (tickBox?.Rect.Width ?? 0) * 1.2f + extraPadding,
missionNameBlock.Padding.Y,
missionNameBlock.Padding.Z + extraZPadding + extraPadding,
missionNameBlock.Padding.W);
missionNameBlock.CalculateHeightFromText();
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform) { MinSize = new Point(0, GUI.IntScale(10)) }, style: null);
@@ -544,7 +551,7 @@ namespace Barotrauma
OnClicked = (GUIButton btn, object obj) =>
{
if (missionList.Content.FindChild(c => c is GUITickBox tickBox && tickBox.Selected, recursive: true) == null &&
missionList.Content.Children.Any(c => c.UserData is Mission mission && mission.Locations.Contains(Campaign?.Map?.CurrentLocation)))
missionList.Content.Children.Any(c => c.UserData is Mission { Prefab.ShowInMenus: true } mission && mission.Locations.Contains(Campaign?.Map?.CurrentLocation)))
{
var noMissionVerification = new GUIMessageBox(string.Empty, TextManager.Get("nomissionprompt"), new LocalizedString[] { TextManager.Get("yes"), TextManager.Get("no") });
noMissionVerification.Buttons[0].OnClicked = (btn, userdata) =>
@@ -482,6 +482,11 @@ namespace Barotrauma
public void TestLevelGenerationForErrors(int amountOfLevelsToGenerate)
{
if (selectedParams == null)
{
throw new InvalidOperationException("No level generation parameters selected in the level editor.");
}
CoroutineManager.StartCoroutine(GenerateLevels());
IEnumerable<CoroutineStatus> GenerateLevels()
@@ -520,7 +525,7 @@ namespace Barotrauma
errorCatcher.Errors.ToList().ForEach(e => DebugConsole.ThrowError(e.Text));
yield return CoroutineStatus.Success;
}
yield return CoroutineStatus.Running;
yield return new WaitForSeconds(0.1f);
}
}
}
@@ -740,6 +740,30 @@ namespace Barotrauma
List<Identifier> missionTypes = MissionPrefab.GetAllMultiplayerSelectableMissionTypes().ToList();
GUILayoutGroup buttonGroup = new(new RectTransform(Vector2.UnitX, missionTypeList.Content.RectTransform), true) { Stretch = true };
GUIButton selectAllMissionsButton = new(new RectTransform(new Vector2(0.5f, 1f), buttonGroup.RectTransform), TextManager.Get("selectall"))
{
OnClicked = (_, _) =>
{
IEnumerable<Identifier> validMissions = GetValidMissions();
validMissions.ForEach(missionType => GameMain.Client.ServerSettings?.ClientAdminWrite(ServerSettings.NetFlags.Misc, addedMissionType: missionType));
return true;
}
};
GUIButton deselectAllMissionsButton = new(new RectTransform(new Vector2(0.5f, 1f), buttonGroup.RectTransform), TextManager.Get("deselectall"))
{
OnClicked = (_, _) =>
{
IEnumerable<Identifier> validMissions = GetValidMissions();
// The server must have at least one mission selected, so ensure the first in the list is enabled.
GameMain.Client?.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, addedMissionType: validMissions.First());
validMissions.Skip(1).ForEach(missionType => GameMain.Client?.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, removedMissionType: missionType));
return true;
}
};
buttonGroup.RectTransform.MinSize = (0, buttonGroup.Children.Max(child => child.Rect.Height));
missionTypeTickBoxes = new GUITickBox[missionTypes.Count];
int index = 0;
foreach (var missionType in missionTypes.OrderBy(t => TextManager.Get("MissionType." + t.Value).Value))
@@ -763,6 +787,13 @@ namespace Barotrauma
}
else
{
Identifier firstValidMission = GetValidMissions().First();
if (missionTypeTickBoxes.None(tickBox => tickBox.Selected && tickBox.Parent.Visible))
{
GameMain.Client?.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, addedMissionType: firstValidMission);
if ((Identifier)tickbox.UserData == firstValidMission) { return true; }
}
GameMain.Client?.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, removedMissionType: (Identifier)tickbox.UserData);
}
return true;
@@ -771,9 +802,16 @@ namespace Barotrauma
frame.RectTransform.MinSize = missionTypeTickBoxes[index].RectTransform.MinSize;
index++;
}
clientDisabledElements.Add(selectAllMissionsButton);
clientDisabledElements.Add(deselectAllMissionsButton);
clientDisabledElements.AddRange(missionTypeTickBoxes);
return gameModeSpecificFrame;
IEnumerable<Identifier> GetValidMissions() => missionTypeTickBoxes
.Where(tickBox => tickBox.Parent.Visible)
.Select(tickBox => (Identifier)tickBox.UserData);
}
private GUIFrame gameModeSettingsContent;
@@ -2884,6 +2922,11 @@ namespace Barotrauma
UserData = new JobVariant(jobPrefab, variant)
};
jobVariantTooltip.RectTransform.AbsoluteOffset = new Point(parentSlot.Rect.Right, parentSlot.Rect.Y);
if (jobVariantTooltip.Rect.X < 0)
{
jobVariantTooltip.RectTransform.SetPosition(anchor: Anchor.TopLeft, pivot: Pivot.BottomLeft);
jobVariantTooltip.RectTransform.AbsoluteOffset = new Point(parentSlot.Rect.X, parentSlot.Rect.Y);
}
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), jobVariantTooltip.RectTransform, Anchor.Center))
{
@@ -3049,6 +3092,8 @@ namespace Barotrauma
private void RefreshOutpostDropdown()
{
Identifier randomOutpostIdentifier = "Random".ToIdentifier();
outpostDropdown.Parent.Visible = MissionTypeFrame.Visible;
if (!outpostDropdown.Parent.Visible) { return; }
@@ -3057,7 +3102,7 @@ namespace Barotrauma
Identifier prevSelected = GameMain.NetworkMember?.ServerSettings.SelectedOutpostName ?? Identifier.Empty;
outpostDropdown.ClearChildren();
outpostDropdown.AddItem(TextManager.Get("Random"), "Random".ToIdentifier());
outpostDropdown.AddItem(TextManager.Get("Random"), randomOutpostIdentifier);
HashSet<Identifier> validOutpostTagsForMissions = new HashSet<Identifier>();
IEnumerable<Type> suitableMissionClasses =
@@ -3081,12 +3126,22 @@ namespace Barotrauma
foreach (var submarineInfo in SubmarineInfo.SavedSubmarines.DistinctBy(s => s.Name))
{
if (submarineInfo.Type == SubmarineType.Outpost &&
validOutpostTagsForMissions.Any(tag => submarineInfo.OutpostTags.Contains(tag)))
validOutpostTagsForMissions.Any(submarineInfo.OutpostTags.Contains))
{
outpostDropdown.AddItem(submarineInfo.DisplayName, userData: submarineInfo.Name.ToIdentifier(), toolTip: submarineInfo.Description);
}
}
outpostDropdown.ListBox.Select(prevSelected);
if (!outpostDropdown.ListBox.Select(prevSelected))
{
//could not select the previously selected outpost (not suitable for the selected missions)
// -> choose random instead
if (outpostDropdown.SelectedData is Identifier selectedIdentifier &&
selectedIdentifier != randomOutpostIdentifier)
{
outpostDropdown.Flash(GUIStyle.Red);
}
outpostDropdown.ListBox.Select(randomOutpostIdentifier);
}
GameMain.Client.ServerSettings.AssignGUIComponent(nameof(ServerSettings.SelectedOutpostName), outpostDropdown);
}
else
@@ -4496,26 +4551,16 @@ namespace Barotrauma
void PositionJobSelectionFrame()
{
JobSelectionFrame.RectTransform.AbsoluteOffset = new Point(characterInfoFrame.Rect.Right - JobSelectionFrame.Rect.Width, characterInfoFrame.Rect.Bottom);
if (characterInfoFrame.Rect.Bottom + JobSelectionFrame.Rect.Height > GameMain.GraphicsHeight)
//move to the left side of the info frame
JobSelectionFrame.RectTransform.AbsoluteOffset = new Point(characterInfoFrame.Rect.X - JobSelectionFrame.Rect.Width, JobList.Rect.Y);
if (JobSelectionFrame.Rect.X < 0)
{
//move to the left side of the info frame if the bottom goes below the screen
JobSelectionFrame.RectTransform.AbsoluteOffset = new Point(characterInfoFrame.Rect.X - JobSelectionFrame.Rect.Width, characterInfoFrame.Rect.Bottom - JobSelectionFrame.Rect.Height / 2);
if (JobSelectionFrame.Rect.X < 0)
{
//scale if goes outside the screen horizontally
JobSelectionFrame.RectTransform.Resize(new Point(characterInfoFrame.Rect.X, JobSelectionFrame.Rect.Height));
JobSelectionFrame.RectTransform.AbsoluteOffset = new Point(characterInfoFrame.Rect.X - JobSelectionFrame.Rect.Width, JobSelectionFrame.RectTransform.AbsoluteOffset.Y);
}
}
//scale if goes outside the screen horizontally
JobSelectionFrame.RectTransform.Resize(new Point(characterInfoFrame.Rect.X, JobSelectionFrame.Rect.Height));
JobSelectionFrame.RectTransform.AbsoluteOffset = new Point(characterInfoFrame.Rect.X - JobSelectionFrame.Rect.Width, JobSelectionFrame.RectTransform.AbsoluteOffset.Y);
}
}
new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), JobSelectionFrame.RectTransform, anchor: Anchor.Center), style: "OuterGlow", color: Color.Black)
{
UserData = "outerglow",
CanBeFocused = false
};
var jobSelectionList = new GUIListBox(new RectTransform(Vector2.One * listBoxRelativeSize, JobSelectionFrame.RectTransform, Anchor.Center), style: "GUIFrameListBox")
{
Padding = Vector4.One * GUI.IntScale(10)
@@ -368,6 +368,7 @@ namespace Barotrauma
"DecorativeSprite",
"BarrelSprite",
"RailSprite",
"ChargeSprite",
"SchematicSprite",
"WeldedSprite"
};
@@ -8,6 +8,7 @@ using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
@@ -37,6 +38,151 @@ namespace Barotrauma
Wiring
}
#region Transform Editor
private const float TransformWidgetOffset = 300f;
private GUITickBox rotateToolToggle, scaleToolToggle;
public bool TransformWidgetSelected => TransformWidget.IsSelected;
private static Vector2 GetSelectionCenter()
{
IEnumerable<MapEntity> nonWireEntities = MapEntity.FilteredSelectedList.Where(static entity => (entity as Item)?.GetComponent<Wire>() is not { Drawable: true });
if (nonWireEntities.None()) { return Vector2.Zero; }
float minX = nonWireEntities.Min(static entity => entity.DrawPosition.X);
float minY = nonWireEntities.Min(static entity => entity.DrawPosition.Y);
float maxX = nonWireEntities.Max(static entity => entity.DrawPosition.X);
float maxY = nonWireEntities.Max(static entity => entity.DrawPosition.Y);
return new Vector2(minX + maxX, minY + maxY) / 2f;
}
private Vector2 oldWidgetWorldPos;
public record struct TransformData(float Scale, float RotationRad, Vector2 Pos, Rectangle Rect, Vector2? TexOffset,
Dictionary<Wire, (List<Vector2> Nodes, float Width)> Wires,
Dictionary<ItemLabel, float> TextScales,
Dictionary<LightComponent, float> LightRanges,
Dictionary<Turret, Vector2> TurretLimits);
private TransformToolCommand transformCommand;
private Widget transformWidget;
private Widget TransformWidget
{
get
{
if (transformWidget != null) { return transformWidget; }
int size = GUI.IntScale(16f);
transformWidget = new Widget("scale", size, WidgetShape.Rectangle)
{
Enabled = false,
Color = GUIStyle.Yellow,
InputAreaMargin = 20,
RequireMouseOn = false,
TooltipOffset = (size / 2f, -size / 2f),
IsFilled = true
};
transformWidget.PreUpdate += _ =>
{
transformWidget.Enabled = MapEntity.FilteredSelectedList.Any() && (rotateToolToggle.Selected || scaleToolToggle.Selected);
if (transformWidget.IsSelected && PlayerInput.PrimaryMouseButtonReleased())
{
if (MapEntity.EditingHUD.GetChild<GUIListBox>() is GUIListBox listBox)
{
SerializableEntityEditor.LockEditing = true;
listBox.Content.Children.OfType<SerializableEntityEditor>().ForEach(editor => editor.RefreshValues());
SerializableEntityEditor.LockEditing = false;
}
Widget.SelectedWidgets.Remove(transformWidget);
StoreCommand(transformCommand);
transformWidget.Color = Color.Yellow;
}
};
transformWidget.Selected += () =>
{
transformWidget.Color = GUIStyle.Blue;
IEnumerable<Item> containedItems = MapEntity.SelectedList.OfType<Item>().SelectManyRecursive(item => item.ContainedItems);
IEnumerable<MapEntity> allEntities = MapEntity.SelectedList.Concat(containedItems).Distinct();
Dictionary<MapEntity, TransformData> oldTransformData = allEntities.ToDictionary(static entity => entity, static entity =>
{
Item item = entity as Item;
Structure structure = entity as Structure;
float rotation = entity switch
{
Structure => MathHelper.ToRadians(structure.Rotation),
Item => item.RotationRad,
_ => 0f
};
return new TransformData(entity.Scale, rotation, entity.DrawPosition, entity.Rect, structure?.TextureOffset,
GetPropertyDict<Wire, (List<Vector2>, float)>(static wire => (wire.GetNodes(), wire.Width)),
GetPropertyDict<ItemLabel, float>(static label => label.TextScale),
GetPropertyDict<LightComponent, float>(static light => light.Range),
GetPropertyDict<Turret, Vector2>(static turret => turret.RotationLimits));
Dictionary<TComponent, TProperties> GetPropertyDict<TComponent, TProperties>(Func<TComponent, TProperties> propSelector) where TComponent : ItemComponent
=> item?.GetComponents<TComponent>().ToDictionary(static comp => comp, propSelector);
});
transformCommand = new TransformToolCommand(oldTransformData, GetSelectionCenter());
};
transformWidget.MouseHeld += _ =>
{
MapEntity.DisableSelect = true;
Vector2 widgetWorldPos = Cam.ScreenToWorld(transformWidget.DrawPos * 2f); // Scale position to account for camera zooming as well.
if (MathUtils.NearlyEqual(widgetWorldPos, oldWidgetWorldPos)) { return; }
oldWidgetWorldPos = widgetWorldPos;
transformCommand.RotationRad = null;
LocalizedString rotationString = null;
if (rotateToolToggle.Selected)
{
transformCommand.RotationRad = MathUtils.VectorToAngle(PlayerInput.MousePosition - Cam.WorldToScreen(transformCommand.Pivot));
rotationString = TextManager.GetWithVariable("SubEditor.TransformWidget.Rotation", "[value]", MathHelper.ToDegrees(transformCommand.RotationRad.Value).ToString("0.000", CultureInfo.CurrentCulture));
}
transformCommand.ScaleMult = null;
LocalizedString scaleString = null;
if (scaleToolToggle.Selected)
{
transformCommand.ScaleMult = Math.Clamp(Vector2.Distance(PlayerInput.MousePosition, Cam.WorldToScreen(transformCommand.Pivot)) / (TransformWidgetOffset * GUI.Scale), transformCommand.MinScale, transformCommand.MaxScale);
scaleString = TextManager.GetWithVariable("SubEditor.TransformWidget.Scale", "[value]", transformCommand.ScaleMult.Value.ToString("0.000", CultureInfo.CurrentCulture));
}
transformWidget.Tooltip = !rotationString.IsNullOrEmpty() && !scaleString.IsNullOrEmpty()
? LocalizedString.Join("\n", rotationString, scaleString)
: transformWidget.Tooltip = rotationString ?? scaleString;
transformCommand.Execute();
};
transformWidget.PreDraw += (sb, _) =>
{
Vector2 selectionCenterScreenPos = Cam.WorldToScreen(transformWidget.IsSelected ? transformCommand.Pivot : GetSelectionCenter());
if (!GameMain.Instance.Paused)
{
if (transformWidget.IsSelected && scaleToolToggle.Selected)
{
transformWidget.DrawPos = PlayerInput.MousePosition;
}
else
{
Vector2 dir = transformWidget.IsSelected ? Vector2.Normalize(PlayerInput.MousePosition - Cam.WorldToScreen(transformCommand.Pivot)) : Vector2.UnitX;
transformWidget.DrawPos = selectionCenterScreenPos + dir * TransformWidgetOffset * GUI.Scale;
}
}
GUI.DrawLine(sb, selectionCenterScreenPos, transformWidget.DrawPos, Color.Black, width: 7f);
GUI.DrawLine(sb, selectionCenterScreenPos, transformWidget.DrawPos, Color.Red, width: 3f);
};
return transformWidget;
}
}
#endregion
public enum WarningType
{
NoWaypoints,
@@ -530,6 +676,16 @@ namespace Barotrauma
};
spacing = new GUIFrame(new RectTransform(new Vector2(0.02f, 1.0f), paddedTopPanel.RectTransform), style: null);
new GUIFrame(new RectTransform(new Vector2(0.1f, 0.9f), spacing.RectTransform, Anchor.Center), style: "VerticalLine");
rotateToolToggle = new GUITickBox(new RectTransform(new Vector2(0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "SubEditorRotateToggle")
{
ToolTip = TextManager.Get("SubEditor.RotateToggleToolTip")
};
scaleToolToggle = new GUITickBox(new RectTransform(new Vector2(0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "SubEditorScaleToggle")
{
ToolTip = TextManager.Get("SubEditor.ScaleToggleToolTip")
};
var selectedLayerText = new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), paddedTopPanel.RectTransform),
string.Empty, textAlignment: Alignment.Center);
@@ -1099,6 +1255,7 @@ namespace Barotrauma
{
Submarine.Unload();
GameMain.SubEditorScreen.Select();
GameMain.GameSession = null;
};
}
@@ -1449,6 +1606,9 @@ namespace Barotrauma
GUI.ForceMouseOn(null);
SetMode(Mode.Default);
rotateToolToggle.Selected = false;
scaleToolToggle.Selected = false;
if (backedUpSubInfo != null)
{
MainSub = new Submarine(backedUpSubInfo);
@@ -1658,6 +1818,9 @@ namespace Barotrauma
});
ClearFilter();
Widget.SelectedWidgets.Remove(TransformWidget);
TransformWidget.Color = Color.Yellow;
}
private void CreateDummyCharacter()
@@ -4634,7 +4797,10 @@ namespace Barotrauma
{
if (itemPrefab.Name.IsNullOrEmpty() || itemPrefab.HideInMenus || itemPrefab.HideInEditors) { continue; }
if (!itemPrefab.Tags.Contains(Tags.WireItem)) { continue; }
if (CircuitBox.IsInGame() && itemPrefab.Tags.Contains(Tags.Thalamus)) { continue; }
if (CircuitBox.IsInGame() && (itemPrefab.Tags.Contains(Tags.Thalamus) || itemPrefab.Tags.Contains("alien")))
{
continue;
}
wirePrefabs.Add(itemPrefab);
}
@@ -6219,6 +6385,8 @@ namespace Barotrauma
CharacterHUD.Update((float)deltaTime, dummyCharacter, cam);
}
TransformWidget.Update((float)deltaTime);
}
/// <summary>
@@ -6348,6 +6516,11 @@ namespace Barotrauma
}
MapEntity.DrawEditor(spriteBatch, cam);
if (TransformWidget.Enabled)
{
TransformWidget.Draw(spriteBatch, (float)deltaTime);
}
GUI.Draw(Cam, spriteBatch);
if (MeasurePositionStart != Vector2.Zero)