Unstable v0.10.600.0

This commit is contained in:
Juan Pablo Arce
2020-10-01 12:19:24 -03:00
parent 20a69375ca
commit ebe1ce1427
217 changed files with 4284 additions and 1547 deletions
@@ -1,4 +1,4 @@
using Barotrauma.Extensions;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@@ -33,6 +33,18 @@ namespace Barotrauma
Default,
Wiring
}
public enum WarningType
{
NoWaypoints,
NoHulls,
DisconnectedVents,
NoHumanSpawnpoints,
NoCargoSpawnpoints,
NoBallastTag,
NonLinkedGaps,
TooManyLights
}
public static Vector2 MouseDragStart = Vector2.Zero;
@@ -85,11 +97,19 @@ namespace Barotrauma
private GUIFrame previouslyUsedPanel;
private GUIListBox previouslyUsedList;
private GUIFrame undoBufferPanel;
private GUIListBox undoBufferList;
private GUIDropDown linkedSubBox;
private static GUIComponent autoSaveLabel;
private static int maxAutoSaves = GameSettings.MaximumAutoSaves;
public static bool BulkItemBufferInUse;
public static List<AddOrDeleteCommand> BulkItemBuffer = new List<AddOrDeleteCommand>();
public static List<WarningType> SuppressedWarnings = new List<WarningType>();
//a Character used for picking up and manipulating items
private Character dummyCharacter;
@@ -109,12 +129,17 @@ namespace Barotrauma
/// </summary>
private Vector2 oldItemPosition;
/// <summary>
/// Global undo/redo state for the sub editor and a selector index for it
/// <see cref="Command"/>
/// </summary>
public static readonly List<Command> Commands = new List<Command>();
private static int commandIndex;
private GUIFrame wiringToolPanel;
private DateTime editorSelectedTime;
private const string containerDeleteTag = "containerdelete";
private GUIImage previewImage;
private GUILayoutGroup previewImageButtonHolder;
@@ -273,6 +298,7 @@ namespace Barotrauma
OnClicked = (btn, userData) =>
{
previouslyUsedPanel.Visible = false;
undoBufferPanel.Visible = false;
showEntitiesPanel.Visible = !showEntitiesPanel.Visible;
showEntitiesPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(btn.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
return true;
@@ -285,12 +311,26 @@ namespace Barotrauma
OnClicked = (btn, userData) =>
{
showEntitiesPanel.Visible = false;
undoBufferPanel.Visible = false;
previouslyUsedPanel.Visible = !previouslyUsedPanel.Visible;
previouslyUsedPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(btn.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
return true;
}
};
var undoBufferButton = new GUIButton(new RectTransform(new Vector2(0.9f, 0.9f), paddedTopPanel.RectTransform, scaleBasis: ScaleBasis.BothHeight), "", style: "UndoHistoryButton")
{
ToolTip = TextManager.Get("Editor.UndoHistoryButton"),
OnClicked = (btn, userData) =>
{
showEntitiesPanel.Visible = false;
previouslyUsedPanel.Visible = false;
undoBufferPanel.Visible = !undoBufferPanel.Visible;
undoBufferPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(btn.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
return true;
}
};
new GUIFrame(new RectTransform(new Vector2(0.01f, 0.9f), paddedTopPanel.RectTransform), style: "VerticalLine");
subNameLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 0.9f), paddedTopPanel.RectTransform, Anchor.CenterLeft),
@@ -407,6 +447,45 @@ namespace Barotrauma
//-----------------------------------------------
undoBufferPanel = new GUIFrame(new RectTransform(new Vector2(0.15f, 0.2f), GUI.Canvas) { MinSize = new Point(200, 200) })
{
Visible = false
};
undoBufferList = new GUIListBox(new RectTransform(new Vector2(0.925f, 0.9f), undoBufferPanel.RectTransform, Anchor.Center))
{
ScrollBarVisible = true,
OnSelected = (_, userData) =>
{
int index;
if (userData is Command command)
{
index = Commands.IndexOf(command);
}
else
{
index = -1;
}
int diff = index- commandIndex;
int amount = Math.Abs(diff);
if (diff >= 0)
{
Redo(amount + 1);
}
else
{
Undo(amount - 1);
}
return true;
}
};
UpdateUndoHistoryPanel();
//-----------------------------------------------
showEntitiesPanel = new GUIFrame(new RectTransform(new Vector2(0.08f, 0.5f), GUI.Canvas)
{
MinSize = new Point(170, 0)
@@ -885,6 +964,7 @@ namespace Barotrauma
{
base.Select();
GUI.PreventPauseMenuToggle = false;
if (!Directory.Exists(autoSavePath))
{
System.IO.DirectoryInfo e = Directory.CreateDirectory(autoSavePath);
@@ -1043,6 +1123,7 @@ namespace Barotrauma
MapEntity.DeselectAll();
MapEntity.SelectionGroups.Clear();
ClearUndoBuffer();
SetMode(Mode.Default);
@@ -1062,147 +1143,15 @@ namespace Barotrauma
GameMain.World.ProcessChanges();
}
if (GUIMessageBox.MessageBoxes.Any(mbox => (mbox as GUIMessageBox)?.Tag == containerDeleteTag))
{
for (int i = 0; i < GUIMessageBox.MessageBoxes.Count; i++)
{
GUIMessageBox box = GUIMessageBox.MessageBoxes[i] as GUIMessageBox;
if (box != null && box.Tag != containerDeleteTag) continue;
box?.Close();
i--; // Take into account the message boxes removing themselves from the list when closed
}
}
ClearFilter();
}
public void HandleContainerContentsDeletion(Item itemToDelete, Inventory itemInventory)
{
string itemNames = string.Empty;
foreach (Item item in itemInventory.Items)
{
if (item == null) continue;
itemNames += item.Name + "\n";
}
if (itemNames.Length > 0)
{
// Multiple prompts open
if (GUIMessageBox.MessageBoxes.Any(mbox => (mbox as GUIMessageBox)?.Tag == containerDeleteTag))
{
var msgBox = new GUIMessageBox(itemToDelete.Name, TextManager.Get("DeletingContainerWithItems") + itemNames, new[] { TextManager.Get("Yes"), TextManager.Get("No"), TextManager.Get("YesToAll"), TextManager.Get("NoToAll") }, tag: containerDeleteTag);
// Yes
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
{
itemInventory.DeleteAllItems();
msgBox.Close();
return true;
};
// No
msgBox.Buttons[1].OnClicked = (btn, userdata) =>
{
if (Selected == GameMain.SubEditorScreen)
{
foreach (Item item in itemInventory.Items)
{
item?.Drop(null);
}
}
else // If current screen is not subeditor, delete anyway to avoid lingering objects
{
itemInventory.DeleteAllItems();
}
msgBox.Close();
return true;
};
// Yes to All
msgBox.Buttons[2].OnClicked = (btn, userdata) =>
{
for (int i = 0; i < GUIMessageBox.MessageBoxes.Count; i++)
{
GUIMessageBox box = GUIMessageBox.MessageBoxes[i] as GUIMessageBox;
if (box?.Tag != msgBox.Tag || box == msgBox) continue;
GUIButton button = box?.Buttons[0];
button?.OnClicked(button, button.UserData);
i--; // Take into account the message boxes removing themselves from the list when closed
}
itemInventory.DeleteAllItems();
msgBox.Close();
return true;
};
// No to all
msgBox.Buttons[3].OnClicked = (btn, userdata) =>
{
for (int i = 0; i < GUIMessageBox.MessageBoxes.Count; i++)
{
GUIMessageBox box = GUIMessageBox.MessageBoxes[i] as GUIMessageBox;
if (box?.Tag != msgBox.Tag || box == msgBox) continue;
GUIButton button = box?.Buttons[1];
button?.OnClicked(button, button.UserData);
i--; // Take into account the message boxes removing themselves from the list when closed
}
if (Selected == GameMain.SubEditorScreen)
{
foreach (Item item in itemInventory.Items)
{
item?.Drop(null);
}
}
else // If current screen is not subeditor, delete anyway to avoid lingering objects
{
itemInventory.DeleteAllItems();
}
msgBox.Close();
return true;
};
}
else // Single prompt
{
var msgBox = new GUIMessageBox(itemToDelete.Name, TextManager.Get("DeletingContainerWithItems") + itemNames, new[] { TextManager.Get("Yes"), TextManager.Get("No") }, tag: containerDeleteTag);
// Yes
msgBox.Buttons[0].OnClicked = (btn, userdata) =>
{
itemInventory.DeleteAllItems();
msgBox.Close();
return true;
};
// No
msgBox.Buttons[1].OnClicked = (btn, userdata) =>
{
if (Selected == GameMain.SubEditorScreen)
{
foreach (Item item in itemInventory.Items)
{
item?.Drop(null);
}
}
else // If current screen is not subeditor, delete anyway to avoid lingering objects
{
itemInventory.DeleteAllItems();
}
msgBox.Close();
return true;
};
}
}
}
private void CreateDummyCharacter()
{
if (dummyCharacter != null) RemoveDummyCharacter();
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", hasAi: false);
dummyCharacter.Info.Name = "Galldren";
//make space for the entity menu
for (int i = 0; i < dummyCharacter.Inventory.SlotPositions.Length; i++)
@@ -2609,7 +2558,7 @@ namespace Barotrauma
var selectedSub = new Submarine(selectedSubInfo);
Submarine.MainSub = selectedSub;
Submarine.MainSub.UpdateTransform(interpolate: false);
ClearUndoBuffer();
CreateDummyCharacter();
string name = Submarine.MainSub.Info.Name;
@@ -2790,6 +2739,7 @@ namespace Barotrauma
MapEntity.DeselectAll();
MapEntity.FilteredSelectedList.Clear();
ClearUndoBuffer();
CreateDummyCharacter();
if (newMode == Mode.Wiring)
@@ -2922,7 +2872,7 @@ namespace Barotrauma
CreateBackgroundColorPicker();
break;
case "selectsame":
IEnumerable<MapEntity> matching = MapEntity.mapEntityList.Where(e => targets.Any(t => t.prefab.Identifier == e.prefab.Identifier) && !MapEntity.SelectedList.Contains(e));
IEnumerable<MapEntity> matching = MapEntity.mapEntityList.Where(e => e.prefab != null && targets.Any(t => t.prefab.Identifier == e.prefab.Identifier) && !MapEntity.SelectedList.Contains(e));
MapEntity.SelectedList.AddRange(matching);
break;
case "copy":
@@ -2935,7 +2885,8 @@ namespace Barotrauma
MapEntity.Paste(cam.ScreenToWorld(contextMenu.Rect.Location.ToVector2()));
break;
case "delete":
targets.ForEach(me => { me.Remove(); });
StoreCommand(new AddOrDeleteCommand(targets, true));
targets.ForEach(me => { if (!me.Removed) { me.Remove(); }});
break;
case "open" when target != null:
OpenItem(target);
@@ -3234,7 +3185,13 @@ namespace Barotrauma
}
}
});
GUI.PlayUISound(spawnedItem ? GUISoundType.PickItem : GUISoundType.PickItemFail);
List<MapEntity> placedEntities = itemInstance.Where(it => !it.Removed).Cast<MapEntity>().ToList();
if (placedEntities.Any())
{
StoreCommand(new AddOrDeleteCommand(placedEntities, false));
}
SoundPlayer.PlayUISound(spawnedItem ? GUISoundType.PickItem : GUISoundType.PickItemFail);
break;
}
case ItemPrefab itemPrefab when PlayerInput.IsShiftDown():
@@ -3243,12 +3200,17 @@ namespace Barotrauma
if (!inv.TryPutItem(item, dummyCharacter))
{
// We failed, remove the item so it doesn't stay at x:0,y:0
GUI.PlayUISound(GUISoundType.PickItemFail);
SoundPlayer.PlayUISound(GUISoundType.PickItemFail);
item.Remove();
}
else
{
GUI.PlayUISound(GUISoundType.PickItem);
SoundPlayer.PlayUISound(GUISoundType.PickItem);
}
if (!item.Removed)
{
StoreCommand(new AddOrDeleteCommand(new List<MapEntity> { item }, false));
}
break;
}
@@ -3257,7 +3219,7 @@ namespace Barotrauma
{
// Place the item into our hands
DraggedItemPrefab = (MapEntityPrefab) obj;
GUI.PlayUISound(GUISoundType.PickItem);
SoundPlayer.PlayUISound(GUISoundType.PickItem);
break;
}
}
@@ -3265,7 +3227,7 @@ namespace Barotrauma
}
else
{
GUI.PlayUISound(GUISoundType.PickItem);
SoundPlayer.PlayUISound(GUISoundType.PickItem);
MapEntityPrefab.SelectPrefab(obj);
}
@@ -3611,6 +3573,7 @@ namespace Barotrauma
EntityMenu.AddToGUIUpdateList();
showEntitiesPanel.AddToGUIUpdateList();
previouslyUsedPanel.AddToGUIUpdateList();
undoBufferPanel.AddToGUIUpdateList();
entityCountPanel.AddToGUIUpdateList();
TopPanel.AddToGUIUpdateList();
@@ -3655,10 +3618,7 @@ namespace Barotrauma
/// </summary>
private bool IsMouseOnEditorGUI()
{
if (GUI.MouseOn == null)
{
return false;
}
if (GUI.MouseOn == null) { return false; }
return (EntityMenu?.MouseRect.Contains(PlayerInput.MousePosition) ?? false)
|| (entityCountPanel?.MouseRect.Contains(PlayerInput.MousePosition) ?? false)
@@ -3666,6 +3626,91 @@ namespace Barotrauma
|| (TopPanel?.MouseRect.Contains(PlayerInput.MousePosition) ?? false);
}
private static void Redo(int amount)
{
for (int i = 0; i < amount; i++)
{
if (commandIndex < Commands.Count)
{
Command command = Commands[commandIndex++];
command.Execute();
}
}
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
}
private static void Undo(int amount)
{
for (int i = 0; i < amount; i++)
{
if (commandIndex > 0)
{
Command command = Commands[--commandIndex];
command.UnExecute();
}
}
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
}
private static void ClearUndoBuffer()
{
SerializableEntityEditor.PropertyChangesActive = false;
SerializableEntityEditor.CommandBuffer = null;
Commands.ForEach(cmd => cmd.Cleanup());
Commands.Clear();
commandIndex = 0;
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
}
public static void StoreCommand(Command command)
{
if (commandIndex != Commands.Count)
{
Commands.RemoveRange(commandIndex, Commands.Count - commandIndex);
}
Commands.Add(command);
commandIndex++;
// Start removing old commands
if (Commands.Count > Math.Clamp(GameSettings.SubEditorMaxUndoBuffer, 1, 10240))
{
Commands.First()?.Cleanup();
Commands.RemoveRange(0, 1);
commandIndex = Commands.Count;
}
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
}
public void UpdateUndoHistoryPanel()
{
if (undoBufferPanel == null) { return; }
undoBufferList.Content.Children.ForEachMod(component =>
{
undoBufferList.Content.RemoveChild(component);
});
for (int i = 0; i < Commands.Count; i++)
{
Command command = Commands[i];
string description = command.GetDescription();
CreateTextBlock(description, description, i + 1, command).RectTransform.SetAsFirstChild();
}
CreateTextBlock(TextManager.Get("undo.beginning"), TextManager.Get("undo.beginningtooltip"), 0, null);
GUITextBlock CreateTextBlock(string name, string description, int index, Command command)
{
return new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), undoBufferList.Content.RectTransform) { MinSize = new Point(0, 15) },
ToolBox.LimitString(name, GUI.SmallFont, undoBufferList.Content.Rect.Width), font: GUI.SmallFont, textColor: index == commandIndex ? GUI.Style.Green : (Color?) null)
{
UserData = command,
ToolTip = description
};
}
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
@@ -3745,7 +3790,32 @@ namespace Barotrauma
}
}
}
if (undoBufferPanel.Visible)
{
undoBufferList.Deselect();
}
if (GUI.KeyboardDispatcher.Subscriber == null
|| MapEntity.EditingHUD != null
&& GUI.KeyboardDispatcher.Subscriber is GUIComponent sub
&& MapEntity.EditingHUD.Children.Contains(sub))
{
if (PlayerInput.IsCtrlDown() && !WiringMode)
{
if (PlayerInput.KeyHit(Keys.Z))
{
// Ctrl+Shift+Z redos while Ctrl+Z undos
if (PlayerInput.IsShiftDown()) { Redo(1); } else { Undo(1); }
}
// ctrl+Y redo
if (PlayerInput.KeyHit(Keys.Y))
{
Redo(1);
}
}
}
if (GUI.KeyboardDispatcher.Subscriber == null)
{
@@ -4019,9 +4089,15 @@ namespace Barotrauma
newItem.Remove();
}
if (!newItem.Removed)
{
BulkItemBufferInUse = true;
BulkItemBuffer.Add(new AddOrDeleteCommand(new List<MapEntity> { newItem }, false));
}
if (!dragginMouse)
{
GUI.PlayUISound(spawnedItem ? GUISoundType.PickItem : GUISoundType.PickItemFail);
SoundPlayer.PlayUISound(spawnedItem ? GUISoundType.PickItem : GUISoundType.PickItemFail);
}
}
}
@@ -4083,14 +4159,41 @@ namespace Barotrauma
}
}
}
List<MapEntity> placedEntities = itemInstance.Where(it => !it.Removed).Cast<MapEntity>().ToList();
if (placedEntities.Any())
{
BulkItemBufferInUse = true;
BulkItemBuffer.Add(new AddOrDeleteCommand(placedEntities, false));
}
}
}
GUI.PlayUISound(spawnedItems ? GUISoundType.PickItem : GUISoundType.PickItemFail);
SoundPlayer.PlayUISound(spawnedItems ? GUISoundType.PickItem : GUISoundType.PickItemFail);
break;
}
}
}
if (BulkItemBufferInUse && PlayerInput.PrimaryMouseButtonReleased() && BulkItemBuffer.Any())
{
AddOrDeleteCommand master = BulkItemBuffer[0];
for (int i = 1; i < BulkItemBuffer.Count; i++)
{
AddOrDeleteCommand command = BulkItemBuffer[i];
command.MergeInto(master);
}
StoreCommand(master);
BulkItemBuffer.Clear();
BulkItemBufferInUse = false;
}
if (SerializableEntityEditor.PropertyChangesActive && (SerializableEntityEditor.NextCommandPush < DateTime.Now || MapEntity.EditingHUD == null))
{
SerializableEntityEditor.CommitCommandBuffer();
}
// Update our mouse dragging state so we can easily slide thru slots while holding the mouse button down to place lots of items
if (PlayerInput.PrimaryMouseButtonHeld())
{