aeafa16...4d3cf73

This commit is contained in:
Joonas Rikkonen
2019-03-18 22:57:05 +02:00
parent 3301bed442
commit 23687fbf2f
77 changed files with 2275 additions and 717 deletions
@@ -87,52 +87,5 @@ namespace Barotrauma
// GUI.DrawLine(spriteBatch, pos, new Vector2(Character.CursorWorldPosition.X, -Character.CursorWorldPosition.Y), Color.Yellow, width: 4);
//}
}
//TODO: move this to the shared project, otherwise bots won't be able to report things in multiplayer
partial void ReportProblems()
{
if (GameMain.Client != null) return;
Order newOrder = null;
if (Character.CurrentHull != null)
{
if (Character.CurrentHull.FireSources.Count > 0)
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportfire");
newOrder = new Order(orderPrefab, Character.CurrentHull, null);
}
if (Character.CurrentHull.ConnectedGaps.Any(g => !g.IsRoomToRoom && g.ConnectedDoor == null && g.Open > 0.0f))
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportbreach");
newOrder = new Order(orderPrefab, Character.CurrentHull, null);
}
foreach (Character c in Character.CharacterList)
{
if (c.CurrentHull == Character.CurrentHull && !c.IsDead &&
(c.AIController is EnemyAIController || c.TeamID != Character.TeamID))
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "reportintruders");
newOrder = new Order(orderPrefab, Character.CurrentHull, null);
}
}
}
if (Character.CurrentHull != null && (Character.Bleeding > 1.0f || Character.Vitality < Character.MaxVitality * 0.1f))
{
var orderPrefab = Order.PrefabList.Find(o => o.AITag == "requestfirstaid");
newOrder = new Order(orderPrefab, Character.CurrentHull, null);
}
if (newOrder != null)
{
if (GameMain.GameSession?.CrewManager != null && GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime))
{
Character.Speak(
newOrder.GetChatMessage("", Character.CurrentHull?.RoomName, givingOrderToSelf: false), ChatMessageType.Order);
}
}
}
}
}
@@ -338,7 +338,7 @@ namespace Barotrauma
var entityList = Submarine.VisibleEntities ?? Item.ItemList;
Item closestItem = null;
float closestItemDistance = aimAssistAmount;
float closestItemDistance = Math.Max(aimAssistAmount, 2.0f);
foreach (MapEntity entity in entityList)
{
if (!(entity is Item item))
@@ -1,4 +1,5 @@
using Barotrauma.Items.Components;
using FarseerPhysics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
@@ -136,10 +137,14 @@ namespace Barotrauma
brokenItemsCheckTimer = 1.0f;
foreach (Item item in Item.ItemList)
{
if (item.CurrentHull == character.CurrentHull && item.Repairables.Any(r => item.Condition < r.ShowRepairUIThreshold))
if (!item.Repairables.Any(r => item.Condition < r.ShowRepairUIThreshold)) { continue; }
if (!Submarine.VisibleEntities.Contains(item)) { continue; }
Vector2 diff = item.WorldPosition - character.WorldPosition;
if (Submarine.CheckVisibility(character.SimPosition, character.SimPosition + ConvertUnits.ToSimUnits(diff)) == null)
{
brokenItems.Add(item);
}
brokenItems.Add(item);
}
}
}
}
@@ -123,10 +123,7 @@ namespace Barotrauma
for (int i = 0; i < inputCount; i++)
{
msg.WriteRangedInteger(0, (int)InputNetFlags.MaxVal, (int)memInput[i].states);
if (memInput[i].states.HasFlag(InputNetFlags.Aim))
{
msg.Write(memInput[i].intAim);
}
msg.Write(memInput[i].intAim);
if (memInput[i].states.HasFlag(InputNetFlags.Select) ||
memInput[i].states.HasFlag(InputNetFlags.Use) ||
memInput[i].states.HasFlag(InputNetFlags.Health) ||
@@ -436,13 +436,15 @@ namespace Barotrauma
AssignOnExecute("ambientlight", (string[] args) =>
{
if (Level.Loaded == null)
{
ThrowError("Could not set ambient light color (no level loaded).");
return;
}
Color color = XMLExtensions.ParseColor(string.Join("", args));
Level.Loaded.GenerationParams.AmbientLightColor = color;
if (Level.Loaded != null)
{
Level.Loaded.GenerationParams.AmbientLightColor = color;
}
else
{
GameMain.LightManager.AmbientLight = color;
}
NewMessage("Set ambient light color to " + color + ".", Color.White);
});
AssignRelayToServer("ambientlight", false);
@@ -1050,6 +1052,195 @@ namespace Barotrauma
TextManager.WriteToCSV();
NPCConversation.WriteToCSV();
}));
commands.Add(new Command("csvtoxml", "csvtoxml [language] -> Converts .csv localization files in Content/NPCConversations & Content/Texts to .xml for use in-game.", (string[] args) =>
{
if (args.Length == 0) return;
LocalizationCSVtoXML.Convert(args[0]);
}));
#endif
commands.Add(new Command("cleanbuild", "", (string[] args) =>
{
GameMain.Config.MusicVolume = 0.5f;
GameMain.Config.SoundVolume = 0.5f;
NewMessage("Music and sound volume set to 0.5", Color.Green);
commands.Add(new Command("camerasettings", "camerasettings [defaultzoom] [zoomsmoothness] [movesmoothness] [minzoom] [maxzoom]: debug command for testing camera settings. The values default to 1.1, 8.0, 8.0, 0.1 and 2.0.", (string[] args) =>
{
float defaultZoom = Screen.Selected.Cam.DefaultZoom;
if (args.Length > 0) float.TryParse(args[0], NumberStyles.Number, CultureInfo.InvariantCulture, out defaultZoom);
float zoomSmoothness = Screen.Selected.Cam.ZoomSmoothness;
if (args.Length > 1) float.TryParse(args[1], NumberStyles.Number, CultureInfo.InvariantCulture, out zoomSmoothness);
float moveSmoothness = Screen.Selected.Cam.MoveSmoothness;
if (args.Length > 2) float.TryParse(args[2], NumberStyles.Number, CultureInfo.InvariantCulture, out moveSmoothness);
float minZoom = Screen.Selected.Cam.MinZoom;
if (args.Length > 3) float.TryParse(args[3], NumberStyles.Number, CultureInfo.InvariantCulture, out minZoom);
float maxZoom = Screen.Selected.Cam.MaxZoom;
if (args.Length > 4) float.TryParse(args[4], NumberStyles.Number, CultureInfo.InvariantCulture, out maxZoom);
Screen.Selected.Cam.DefaultZoom = defaultZoom;
Screen.Selected.Cam.ZoomSmoothness = zoomSmoothness;
Screen.Selected.Cam.MoveSmoothness = moveSmoothness;
Screen.Selected.Cam.MinZoom = minZoom;
Screen.Selected.Cam.MaxZoom = maxZoom;
}));
commands.Add(new Command("waterparams", "waterparams [distortionscalex] [distortionscaley] [distortionstrengthx] [distortionstrengthy] [bluramount]: default 0.5 0.5 0.5 0.5 1", (string[] args) =>
{
float distortScaleX = 0.5f, distortScaleY = 0.5f;
float distortStrengthX = 0.5f, distortStrengthY = 0.5f;
float blurAmount = 0.0f;
if (args.Length > 0) float.TryParse(args[0], NumberStyles.Number, CultureInfo.InvariantCulture, out distortScaleX);
if (args.Length > 1) float.TryParse(args[1], NumberStyles.Number, CultureInfo.InvariantCulture, out distortScaleY);
if (args.Length > 2) float.TryParse(args[2], NumberStyles.Number, CultureInfo.InvariantCulture, out distortStrengthX);
if (args.Length > 3) float.TryParse(args[3], NumberStyles.Number, CultureInfo.InvariantCulture, out distortStrengthY);
if (args.Length > 4) float.TryParse(args[4], NumberStyles.Number, CultureInfo.InvariantCulture, out blurAmount);
WaterRenderer.DistortionScale = new Vector2(distortScaleX, distortScaleY);
WaterRenderer.DistortionStrength = new Vector2(distortStrengthX, distortStrengthY);
WaterRenderer.BlurAmount = blurAmount;
}));
commands.Add(new Command("refreshrect", "Updates the dimensions of the selected items to match the ones defined in the prefab. Applied only in the subeditor.", (string[] args) =>
{
//TODO: maybe do this automatically during loading when possible?
if (Screen.Selected == GameMain.SubEditorScreen)
{
if (!MapEntity.SelectedAny)
{
ThrowError("You have to select item(s) first!");
}
else
{
foreach (var mapEntity in MapEntity.SelectedList)
{
if (mapEntity is Item item)
{
item.Rect = new Rectangle(item.Rect.X, item.Rect.Y,
(int)(item.Prefab.sprite.size.X * item.Prefab.Scale),
(int)(item.Prefab.sprite.size.Y * item.Prefab.Scale));
}
else if (mapEntity is Structure structure)
{
if (!structure.ResizeHorizontal)
{
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
(int)structure.Prefab.ScaledSize.X,
structure.Rect.Height);
}
if (!structure.ResizeVertical)
{
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
structure.Rect.Width,
(int)structure.Prefab.ScaledSize.Y);
}
}
}
}
}
}, isCheat: false));
#endif
GameMain.Config.SaveNewPlayerConfig();
commands.Add(new Command("loadtexts", "loadtexts [sourcefile] [destinationfile]: Loads all lines of text from a given .txt file and inserts them sequientially into the elements of an xml file. If the file paths are omitted, EnglishVanilla.txt and EnglishVanilla.xml are used.", (string[] args) =>
{
string sourcePath = args.Length > 0 ? args[0] : "Content/Texts/EnglishVanilla.txt";
string destinationPath = args.Length > 1 ? args[1] : "Content/Texts/EnglishVanilla.xml";
string[] lines;
try
{
lines = File.ReadAllLines(sourcePath);
}
catch (Exception e)
{
ThrowError("Reading the file \"" + sourcePath + "\" failed.", e);
return;
}
var doc = XMLExtensions.TryLoadXml(destinationPath);
int i = 0;
foreach (XElement element in doc.Root.Elements())
{
if (i >= lines.Length)
{
ThrowError("Error while loading texts to the xml file. The xml has more elements than the number of lines in the text file.");
return;
}
element.Value = lines[i];
i++;
}
doc.Save(destinationPath);
},
() =>
{
var files = TextManager.GetTextFiles().Select(f => f.Replace("\\", "/"));
return new string[][]
{
files.Where(f => Path.GetExtension(f)==".txt").ToArray(),
files.Where(f => Path.GetExtension(f)==".xml").ToArray()
};
}));
commands.Add(new Command("updatetextfile", "updatetextfile [sourcefile] [destinationfile]: Inserts all the xml elements that are only present in the source file into the destination file. Can be used to update outdated translation files more easily.", (string[] args) =>
{
if (args.Length < 2) return;
string sourcePath = args[0];
string destinationPath = args[1];
var sourceDoc = XMLExtensions.TryLoadXml(sourcePath);
var destinationDoc = XMLExtensions.TryLoadXml(destinationPath);
XElement destinationElement = destinationDoc.Root.Elements().First();
foreach (XElement element in sourceDoc.Root.Elements())
{
if (destinationDoc.Root.Element(element.Name) == null)
{
element.Value = "!!!!!!!!!!!!!" + element.Value;
destinationElement.AddAfterSelf(element);
}
XNode nextNode = destinationElement.NextNode;
while ((!(nextNode is XElement) || nextNode == element) && nextNode != null) nextNode = nextNode.NextNode;
destinationElement = nextNode as XElement;
}
destinationDoc.Save(destinationPath);
},
() =>
{
var files = TextManager.GetTextFiles().Where(f => Path.GetExtension(f) == ".xml").Select(f => f.Replace("\\", "/")).ToArray();
return new string[][]
{
files,
files
};
}));
commands.Add(new Command("dumpentitytexts", "dumpentitytexts [filepath]: gets the names and descriptions of all entity prefabs and writes them into a file along with xml tags that can be used in translation files. If the filepath is omitted, the file is written to Content/Texts/EntityTexts.txt", (string[] args) =>
{
string filePath = args.Length > 0 ? args[0] : "Content/Texts/EntityTexts.txt";
List<string> lines = new List<string>();
foreach (MapEntityPrefab me in MapEntityPrefab.List)
{
lines.Add("<EntityName." + me.Identifier + ">" + me.Name + "</" + me.Identifier + ".Name>");
lines.Add("<EntityDescription." + me.Identifier + ">" + me.Description + "</" + me.Identifier + ".Description>");
}
File.WriteAllLines(filePath, lines);
}));
#if DEBUG
commands.Add(new Command("checkduplicates", "Checks the given language for duplicate translation keys and writes to file.", (string[] args) =>
{
if (args.Length != 1) return;
TextManager.CheckForDuplicates(args[0]);
}));
commands.Add(new Command("writetocsv", "Writes the default language (English) to a .csv file.", (string[] args) =>
{
TextManager.WriteToCSV();
NPCConversation.WriteToCSV();
}));
#endif
commands.Add(new Command("cleanbuild", "", (string[] args) =>
@@ -384,12 +384,12 @@ namespace Barotrauma
Cursor.Draw(spriteBatch, PlayerInput.LatestMousePosition);
}
public static void DrawBackgroundSprite(SpriteBatch spriteBatch, Sprite backgroundSprite)
public static void DrawBackgroundSprite(SpriteBatch spriteBatch, Sprite backgroundSprite, float blurAmount = 1.0f, float aberrationStrength = 1.0f)
{
double aberrationT = (Timing.TotalTime * 0.5f);
GameMain.GameScreen.PostProcessEffect.Parameters["blurDistance"].SetValue(0.001f);
GameMain.GameScreen.PostProcessEffect.Parameters["blurDistance"].SetValue(0.001f * aberrationStrength);
GameMain.GameScreen.PostProcessEffect.Parameters["chromaticAberrationStrength"].SetValue(new Vector3(-0.025f, -0.01f, -0.05f) *
(float)(PerlinNoise.CalculatePerlin(aberrationT, aberrationT, 0) + 0.5f));
(float)(PerlinNoise.CalculatePerlin(aberrationT, aberrationT, 0) + 0.5f) * aberrationStrength);
GameMain.GameScreen.PostProcessEffect.CurrentTechnique = GameMain.GameScreen.PostProcessEffect.Techniques["BlurChromaticAberration"];
GameMain.GameScreen.PostProcessEffect.CurrentTechnique.Passes[0].Apply();
@@ -107,14 +107,37 @@ namespace Barotrauma
};
scrollButtonDown.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipVertically);
var characterInfo = new CharacterInfo(subElement);
characterInfos.Add(characterInfo);
foreach (XElement invElement in subElement.Elements())
if (isSinglePlayer)
{
chatBox = new ChatBox(guiFrame, isSinglePlayer: true)
{
if (invElement.Name.ToString().ToLowerInvariant() != "inventory") continue;
characterInfo.InventoryData = invElement;
break;
}
OnEnterMessage = (textbox, text) =>
{
if (Character.Controlled == null) { return true; }
textbox.TextColor = ChatMessage.MessageColor[(int)ChatMessageType.Default];
if (!string.IsNullOrWhiteSpace(text))
{
string msgCommand = ChatMessage.GetChatMessageCommand(text, out string msg);
AddSinglePlayerChatMessage(
Character.Controlled.Info.Name,
msg,
((msgCommand == "r" || msgCommand == "radio") && ChatMessage.CanUseRadio(Character.Controlled)) ? ChatMessageType.Radio : ChatMessageType.Default,
Character.Controlled);
var headset = GetHeadset(Character.Controlled, true);
if (headset != null && headset.CanTransmit())
{
headset.TransmitSignal(stepsTaken: 0, signal: msg, source: headset.Item, sender: Character.Controlled, sendToChat: false);
}
}
textbox.Deselect();
textbox.Text = "";
return true;
}
};
chatBox.InputBox.OnTextChanged += chatBox.TypingChatMessage;
}
var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null);
@@ -136,6 +159,7 @@ namespace Barotrauma
{
if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false;
SetCharacterOrder(null, order, null, Character.Controlled);
HumanAIController.PropagateHullSafety(Character.Controlled, Character.Controlled.CurrentHull);
return true;
},
UserData = order,
@@ -152,12 +176,14 @@ namespace Barotrauma
Visible = false
};
var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true)
var characterInfo = new CharacterInfo(subElement);
characterInfos.Add(characterInfo);
foreach (XElement invElement in subElement.Elements())
{
Color = order.Color,
HoverColor = Color.Lerp(order.Color, Color.White, 0.5f),
ToolTip = order.Name
};
if (invElement.Name.ToString().ToLowerInvariant() != "inventory") continue;
characterInfo.InventoryData = invElement;
break;
}
}
screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
@@ -7,10 +7,6 @@ namespace Barotrauma
{
private InfoFrameTab selectedTab;
private GUIButton infoFrame;
/// <summary>
/// Determines whether the hotkey for the info button was held down in the previous frame.
/// </summary>
private bool prevInfoKey;
private GUIFrame infoFrameContent;
@@ -19,12 +15,7 @@ namespace Barotrauma
{
get { return roundSummary; }
}
partial void InitProjSpecific()
{
prevInfoKey = false;
}
private bool ToggleInfoFrame()
{
if (infoFrame == null)
@@ -45,8 +36,7 @@ namespace Barotrauma
int width = 600, height = 400;
infoFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas), style: "GUIBackgroundBlocker");
var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.35f), infoFrame.RectTransform, Anchor.Center) { MinSize = new Point(width,height) });
var paddedFrame = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.9f), innerFrame.RectTransform, Anchor.Center), style:null);
@@ -135,10 +125,17 @@ namespace Barotrauma
{
if (GUI.DisableHUD) return;
if (prevInfoKey != (PlayerInput.KeyDown(InputType.InfoTab) && GUI.KeyboardDispatcher.Subscriber == null))
if (PlayerInput.KeyDown(InputType.InfoTab) &&
(GUI.KeyboardDispatcher.Subscriber == null || GUI.KeyboardDispatcher.Subscriber is GUIListBox))
{
if (infoFrame == null)
{
ToggleInfoFrame();
}
}
else if (infoFrame != null)
{
ToggleInfoFrame();
prevInfoKey = PlayerInput.KeyDown(InputType.InfoTab);
}
infoFrame?.UpdateManually(deltaTime);
@@ -626,28 +626,6 @@ namespace Barotrauma
new GUIMessageBox(TextManager.Get("RestartRequiredLabel"), TextManager.Get("RestartRequiredLanguage"));
return true;
};
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null);
new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), buttonArea.RectTransform, Anchor.BottomLeft),
TextManager.Get("Cancel"))
{
IgnoreLayoutGroups = true,
OnClicked = (x, y) =>
{
if (UnsavedSettings)
{
LoadPlayerConfig();
}
if (Screen.Selected == GameMain.MainMenuScreen) GameMain.MainMenuScreen.ReturnToMainMenu(null, null);
GUI.SettingsMenuOpen = false;
return true;
}
};
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.02f), generalLayoutGroup.RectTransform), style: null);
@@ -184,63 +184,6 @@ namespace Barotrauma.Items.Components
}
}
}
public void ApplyTo(RectTransform target)
{
if (RelativeOffset.HasValue)
{
target.RelativeOffset = RelativeOffset.Value;
}
else if (AbsoluteOffset.HasValue)
{
target.AbsoluteOffset = AbsoluteOffset.Value;
}
if (RelativeSize.HasValue)
{
target.RelativeSize = RelativeSize.Value;
}
else if (AbsoluteSize.HasValue)
{
target.NonScaledSize = AbsoluteSize.Value;
}
if (Anchor.HasValue)
{
target.Anchor = Anchor.Value;
}
if (Pivot.HasValue)
{
target.Pivot = Pivot.Value;
}
else
{
target.Pivot = RectTransform.MatchPivotToAnchor(target.Anchor);
}
target.RecalculateChildren(true, true);
}
}
public GUIFrame GuiFrame { get; protected set; }
[Serialize(false, false)]
public bool AllowUIOverlap
{
get;
set;
}
private ItemComponent linkToUIComponent;
[Serialize("", false)]
public string LinkUIToComponent
{
get;
set;
}
[Serialize(0, false)]
public int HudPriority
{
get;
private set;
}
private bool shouldMuffleLooping;
@@ -598,7 +598,7 @@ namespace Barotrauma
if (selectedSlot == null)
{
draggingItem.Drop();
draggingItem.Drop(Character.Controlled);
GUI.PlayUISound(GUISoundType.DropItem);
}
else if (selectedSlot.ParentInventory.Items[selectedSlot.SlotIndex] != draggingItem)
@@ -954,7 +954,7 @@ namespace Barotrauma
{
if (receivedItemIDs[i] == 0 || (Entity.FindEntityByID(receivedItemIDs[i]) as Item != Items[i]))
{
if (Items[i] != null) Items[i].Drop();
if (Items[i] != null) Items[i].Drop(null);
System.Diagnostics.Debug.Assert(Items[i] == null);
}
}
@@ -849,6 +849,11 @@ namespace Barotrauma
{
if (GameMain.Client == null) { return; }
if (parentInventory != null || body == null || !body.Enabled || Removed)
{
return;
}
Vector2 newVelocity = body.LinearVelocity;
Vector2 newPosition = body.SimPosition;
float newAngularVelocity = body.AngularVelocity;
@@ -202,6 +202,12 @@ namespace Barotrauma.Networking
private void ConnectToServer(string hostIP)
{
chatBox.InputBox.Enabled = false;
if (GameMain.NetLobbyScreen?.TextBox != null)
{
GameMain.NetLobbyScreen.TextBox.Enabled = false;
}
string[] address = hostIP.Split(':');
if (address.Length == 1)
{
@@ -259,7 +265,11 @@ namespace Barotrauma.Networking
{
DebugConsole.ThrowError("Couldn't connect to " + hostIP + ". Error message: " + e.Message);
Disconnect();
chatBox.InputBox.Enabled = true;
if (GameMain.NetLobbyScreen?.TextBox != null)
{
GameMain.NetLobbyScreen.TextBox.Enabled = true;
}
GameMain.ServerListScreen.Select();
return;
}
@@ -530,6 +540,10 @@ namespace Barotrauma.Networking
GameMain.NetLobbyScreen.Select();
}
connected = true;
if (GameMain.NetLobbyScreen?.TextBox != null)
{
GameMain.NetLobbyScreen.TextBox.Enabled = true;
}
}
yield return CoroutineStatus.Success;
@@ -118,7 +118,18 @@ namespace Barotrauma
CanBeFocused = false
};
characterList = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.95f), tabs[(int)Tab.Crew].RectTransform, Anchor.Center))
var crewContent = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), tabs[(int)Tab.Crew].RectTransform, Anchor.Center))
{
Stretch = true,
RelativeSpacing = 0.02f
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), crewContent.RectTransform), "", font: GUI.LargeFont)
{
TextGetter = GetMoney
};
characterList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.9f), crewContent.RectTransform))
{
OnSelected = SelectCharacter
};
@@ -438,6 +438,43 @@ namespace Barotrauma
UpdateSourceRect(limb, newRect);
}
}
UpdateJointCreation();
if (PlayerInput.KeyHit(Keys.Left))
{
foreach (var limb in selectedLimbs)
{
var newRect = limb.ActiveSprite.SourceRect;
newRect.X--;
UpdateSourceRect(limb, newRect);
}
}
if (PlayerInput.KeyHit(Keys.Right))
{
foreach (var limb in selectedLimbs)
{
var newRect = limb.ActiveSprite.SourceRect;
newRect.X++;
UpdateSourceRect(limb, newRect);
}
}
if (PlayerInput.KeyHit(Keys.Down))
{
foreach (var limb in selectedLimbs)
{
var newRect = limb.ActiveSprite.SourceRect;
newRect.Y++;
UpdateSourceRect(limb, newRect);
}
}
if (PlayerInput.KeyHit(Keys.Up))
{
foreach (var limb in selectedLimbs)
{
var newRect = limb.ActiveSprite.SourceRect;
newRect.Y--;
UpdateSourceRect(limb, newRect);
}
}
}
if (!isFreezed)
{
@@ -38,9 +38,18 @@ namespace Barotrauma
#region Creation
public MainMenuScreen(GameMain game)
{
new GUIImage(new RectTransform(new Vector2(0.35f, 0.2f), Frame.RectTransform, Anchor.BottomRight)
{ RelativeOffset = new Vector2(0.05f, 0.05f), AbsoluteOffset = new Point(-5, -5) },
style: "TitleText")
{
Color = Color.Black * 0.5f,
CanBeFocused = false
};
new GUIImage(new RectTransform(new Vector2(0.35f, 0.2f), Frame.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.05f, 0.05f) },
style: "TitleText");
buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.BottomLeft, pivot: Pivot.BottomLeft)
{
RelativeOffset = new Vector2(0, 0),
AbsoluteOffset = new Point(50, 0)
})
{
@@ -66,7 +75,7 @@ namespace Barotrauma
var campaignButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: campaignNavigation.RectTransform), style: "MainMenuGUIFrame");
var campaignList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.15f), parent: campaignButtons.RectTransform))
var campaignList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: campaignButtons.RectTransform))
{
Stretch = false,
RelativeSpacing = 0.035f
@@ -112,7 +121,7 @@ namespace Barotrauma
var multiplayerButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: multiplayerNavigation.RectTransform), style: "MainMenuGUIFrame");
var multiplayerList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.15f), parent: multiplayerButtons.RectTransform))
var multiplayerList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: multiplayerButtons.RectTransform))
{
Stretch = false,
RelativeSpacing = 0.035f
@@ -157,7 +166,7 @@ namespace Barotrauma
var customizeButtons = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent: customizeNavigation.RectTransform), style: "MainMenuGUIFrame");
var customizeList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.15f), parent: customizeButtons.RectTransform))
var customizeList = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.2f), parent: customizeButtons.RectTransform))
{
Stretch = false,
RelativeSpacing = 0.035f
@@ -673,7 +682,12 @@ namespace Barotrauma
backgroundSprite = (LocationType.List.Where(l => l.UseInMainMenu).GetRandom()).GetPortrait(0);
}
if (backgroundSprite != null) { GUI.DrawBackgroundSprite(spriteBatch, backgroundSprite); }
if (backgroundSprite != null)
{
GUI.DrawBackgroundSprite(spriteBatch, backgroundSprite,
blurAmount: 0.0f,
aberrationStrength: 0.0f);
}
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
@@ -625,8 +625,7 @@ namespace Barotrauma
{
foreach (Item item in itemInventory.Items)
{
if (item == null) continue;
item.Drop();
item?.Drop(null);
}
}
else // If current screen is not subeditor, delete anyway to avoid lingering objects
@@ -671,8 +670,7 @@ namespace Barotrauma
{
foreach (Item item in itemInventory.Items)
{
if (item == null) continue;
item.Drop();
item?.Drop(null);
}
}
else // If current screen is not subeditor, delete anyway to avoid lingering objects
@@ -703,8 +701,7 @@ namespace Barotrauma
{
foreach (Item item in itemInventory.Items)
{
if (item == null) continue;
item.Drop();
item?.Drop(null);
}
}
else // If current screen is not subeditor, delete anyway to avoid lingering objects
@@ -1457,7 +1454,7 @@ namespace Barotrauma
Item existingWire = dummyCharacter.SelectedItems.FirstOrDefault(i => i != null && i.Prefab == userData as ItemPrefab);
if (existingWire != null)
{
existingWire.Drop();
existingWire.Drop(null);
existingWire.Remove();
return false;
}
@@ -1470,7 +1467,7 @@ namespace Barotrauma
existingWire = dummyCharacter.Inventory.Items[slotIndex];
if (existingWire != null && existingWire.Prefab != userData as ItemPrefab)
{
existingWire.Drop();
existingWire.Drop(null);
existingWire.Remove();
}
@@ -109,6 +109,12 @@ namespace Barotrauma.Sounds
{
get { return loadedSounds.Select(s => s.Filename).Distinct().Count(); }
}
public int UniqueLoadedSoundCount
{
get { return loadedSounds.Select(s => s.Filename).Distinct().Count(); }
}
private Dictionary<string, Pair<float, bool>> categoryModifiers;
private Dictionary<string, Pair<float, bool>> categoryModifiers;
@@ -418,6 +424,10 @@ namespace Barotrauma.Sounds
{
categoryModifiers[category].Second = muffle;
}
else
{
categoryModifiers[category].Second = muffle;
}
}
for (int i = 0; i < playingChannels.Length; i++)
@@ -0,0 +1,246 @@
#if DEBUG
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace Barotrauma
{
class LocalizationCSVtoXML
{
private static Regex csvSplit = new Regex("(?:^|,)(\"(?:[^\"])*\"|[^,]*)", RegexOptions.Compiled); // Handling commas inside data fields surrounded by ""
private static List<int> conversationClosingIndent = new List<int>();
private static char[] separator = new char[1] { ',' };
private const string conversationsPath = "Content/NPCConversations";
private const string infoTextPath = "Content/Texts";
private const string xmlHeader = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>";
public static void Convert(string language)
{
List<string> conversationFiles = new List<string>();
List<string> infoTextFiles = new List<string>();
language = language.CapitaliseFirstInvariant();
foreach (string filePath in Directory.GetFiles(conversationsPath, "*.csv", SearchOption.AllDirectories))
{
conversationFiles.Add(filePath);
}
foreach (string filePath in Directory.GetFiles(infoTextPath, "*.csv", SearchOption.AllDirectories))
{
infoTextFiles.Add(filePath);
}
for (int i = 0; i < conversationFiles.Count; i++)
{
List<string> xmlContent = ConvertConversationsToXML(File.ReadAllLines(conversationFiles[i], Encoding.UTF8), language);
string xmlFileFullPath = $"{conversationsPath}/NPCConversations_{language}_NEW.xml";
File.WriteAllLines(xmlFileFullPath, xmlContent);
DebugConsole.NewMessage("Conversation localization .xml file successfully created at: " + xmlFileFullPath);
}
for (int i = 0; i < infoTextFiles.Count; i++)
{
List<string> xmlContent = ConvertInfoTextToXML(File.ReadAllLines(infoTextFiles[i], Encoding.UTF8), language);
string xmlFileFullPath = $"{infoTextPath}/{language}Vanilla_NEW.xml";
File.WriteAllLines(xmlFileFullPath, xmlContent);
DebugConsole.NewMessage("InfoText localization .xml file successfully created at: " + xmlFileFullPath);
}
if (conversationFiles.Count == 0 && infoTextFiles.Count == 0)
{
DebugConsole.ThrowError("No .csv files found to convert.");
}
}
private static List<string> ConvertInfoTextToXML(string[] csvContent, string language)
{
List<string> xmlContent = new List<string>();
xmlContent.Add(xmlHeader);
xmlContent.Add($"<infotexts language=\"{language}\">");
xmlContent.Add(string.Empty);
for (int i = 0; i < csvContent.Length; i++)
{
csvContent[i] = csvContent[i].Trim(separator);
if (csvContent[i].Length == 0)
{
xmlContent.Add(string.Empty);
}
else
{
string[] split = csvContent[i].Split(separator, 2);
if (split.Length == 2)
{
split[1] = split[1].Replace("\"", ""); // Replaces quotation marks around data that are added when exporting via excel
xmlContent.Add($"<{split[0]}>{split[1]}</{split[0]}>");
}
else if (split[0].Contains(".")) // An empty field
{
xmlContent.Add($"<{split[0]}><!-- No data --></{split[0]}>");
}
else // A header
{
xmlContent.Add($"<!-- {split[0]} -->");
}
}
}
xmlContent.Add(string.Empty);
xmlContent.Add("</infotexts>");
return xmlContent;
}
private static List<string> ConvertConversationsToXML(string[] csvContent, string language)
{
List<string> xmlContent = new List<string>();
xmlContent.Add(xmlHeader);
xmlContent.Add($"<Conversations identifier=\"vanillaconversations\" Language=\"{language}\">");
xmlContent.Add(string.Empty);
for (int i = 0; i < csvContent.Length; i++)
{
string[] split = SplitCSV(csvContent[i]);
int emptyFields = 0;
for (int j = 0; j < split.Length; j++)
{
if (split[j] == string.Empty) emptyFields++;
}
if (emptyFields == split.Length) // Empty line with only commas, indicates the end of the previous conversation
{
HandleClosingElements(xmlContent, 0);
xmlContent.Add(string.Empty);
continue;
}
else if (emptyFields == split.Length - 1 && split[0] != string.Empty) // A header
{
xmlContent.Add($"<!-- {split[0]} -->");
continue;
}
string speaker = split[1];
int depthIndex = int.Parse(split[2]);
// 3 = original line
string line = split[4].Replace("\"", "");
string flags = split[5].Replace("\"", "");
string allowedJobs = split[6].Replace("\"", "");
string speakerTags = split[7].Replace("\"", "");
string minIntensity = split[8].Replace("\"", "");
string maxIntensity = split[9].Replace("\"", "");
string element =
$"{GetIndenting(depthIndex)}" +
$"<Conversation line=\"{line}\" " +
$"{GetVariable("speaker" ,speaker)}" +
$"{GetVariable("flags", flags)}" +
$"{GetVariable("allowedjobs", allowedJobs)}" +
$"{GetVariable("speakertags", speakerTags)}" +
$"{GetVariable("minintensity", minIntensity)}" +
$"{GetVariable("maxintensity", maxIntensity)}";
bool nextIsSubConvo = false;
int nextDepth = 999;
if (i < csvContent.Length - 1) // Not at the end of file
{
string[] nextConversationElement = csvContent[i + 1].Split(separator);
if (nextConversationElement[1] != string.Empty)
{
nextDepth = int.Parse(nextConversationElement[2]);
nextIsSubConvo = nextDepth > depthIndex;
}
if (!nextIsSubConvo)
{
xmlContent.Add(element.TrimEnd() + "/>");
if (nextDepth < depthIndex)
{
HandleClosingElements(xmlContent, nextDepth);
}
}
else
{
xmlContent.Add(element.TrimEnd() + ">");
conversationClosingIndent.Add(depthIndex);
}
}
else
{
xmlContent.Add(element.TrimEnd() + "/>");
}
}
xmlContent.Add(string.Empty);
xmlContent.Add("</Conversations>");
return xmlContent;
}
private static void HandleClosingElements(List<string> xmlContent, int targetDepth)
{
if (conversationClosingIndent.Count == 0) return;
for (int k = conversationClosingIndent.Count - 1; k >= 0; k--)
{
int currentIndent = conversationClosingIndent[k];
if (currentIndent < targetDepth) break;
xmlContent.Add($"{GetIndenting(currentIndent)}</Conversation>");
conversationClosingIndent.RemoveAt(k);
}
}
private static string[] SplitCSV(string input) // Splits the .csv with regex, leaving commas inside quotation marks intact
{
List<string> list = new List<string>();
string curr = null;
foreach (Match match in csvSplit.Matches(input))
{
curr = match.Value;
if (0 == curr.Length)
{
list.Add("");
}
list.Add(curr.TrimStart(','));
}
return list.ToArray();
}
private static string GetIndenting(int depthIndex)
{
string indenting = string.Empty;
for (int i = 0; i < depthIndex; i++)
{
indenting += "\t";
}
return indenting;
}
private static string GetVariable(string name, string value)
{
if (value == string.Empty)
{
return string.Empty;
}
else
{
return $"{name}=\"{value}\" ";
}
}
}
}
#endif