diff --git a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs index 0e7a33e97..1e124efe2 100644 --- a/Barotrauma/BarotraumaClient/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaClient/Source/DebugConsole.cs @@ -1965,6 +1965,555 @@ namespace Barotrauma TextManager.WriteToCSV(); NPCConversation.WriteToCSV(); })); +#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 lines = new List(); + foreach (MapEntityPrefab me in MapEntityPrefab.List) + { + lines.Add("" + me.Name + ""); + lines.Add("" + me.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) => + { + 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 lines = new List(); + foreach (MapEntityPrefab me in MapEntityPrefab.List) + { + lines.Add("" + me.Name + ""); + lines.Add("" + me.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) => + { + 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 lines = new List(); + foreach (MapEntityPrefab me in MapEntityPrefab.List) + { + lines.Add("" + me.Name + ""); + lines.Add("" + me.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(); + })); 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) => { diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIButton.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIButton.cs index 7b7a37b98..eec9c180b 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIButton.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIButton.cs @@ -117,6 +117,12 @@ namespace Barotrauma set { textBlock.Text = value; } } + public bool ForceUpperCase + { + get { return textBlock.ForceUpperCase; } + set { textBlock.ForceUpperCase = value; } + } + public override string ToolTip { get diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs index e1063b2da..6cdba8652 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIDropDown.cs @@ -112,11 +112,12 @@ namespace Barotrauma GUI.Style.Apply(button, "", this); listBox = new GUIListBox(new RectTransform(new Point(Rect.Width, Rect.Height * MathHelper.Clamp(elementCount, 2, 10)), rectT, Anchor.BottomLeft, Pivot.TopLeft) - { IsFixedSize = false }, style: style) + { IsFixedSize = false }, style: null) { Enabled = !selectMultiple, OnSelected = SelectItem }; + GUI.Style.Apply(listBox.Content, "GUIListBox", this); currentListBoxParent = FindListBoxParent(); currentListBoxParent.GUIComponent.OnAddedToGUIUpdateList += AddListBoxToGUIUpdateList; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs index f55e4b318..e90fed400 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUITextBlock.cs @@ -61,13 +61,15 @@ namespace Barotrauma get { return text; } set { - if (Text == value) return; + string newText = forceUpperCase ? value?.ToUpper() : value; + + if (Text == newText) return; //reset scale, it gets recalculated in SetTextPos - if (autoScale) textScale = 1.0f; + if (autoScale) textScale = 1.0f; - text = value; - wrappedText = value; + text = newText; + wrappedText = newText; SetTextPos(); } } @@ -120,6 +122,22 @@ namespace Barotrauma } } + private bool forceUpperCase; + public bool ForceUpperCase + { + get { return forceUpperCase; } + set + { + if (forceUpperCase == value) { return; } + + forceUpperCase = value; + if (forceUpperCase) + { + Text = text?.ToUpper(); + } + } + } + public Vector2 Origin { get { return origin; } diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index 96c9396bf..870f3d553 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -66,6 +66,25 @@ namespace Barotrauma CanBeFocused = false }; + Point scrollButtonSize = new Point((int)(200 * GUI.Scale), (int)(30 * GUI.Scale)); + + crewArea = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.CrewArea, guiFrame.RectTransform), "", Color.Transparent) + { + CanBeFocused = false + }; + toggleCrewButton = new GUIButton(new RectTransform(new Point((int)(30 * GUI.Scale), HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform) + { AbsoluteOffset = HUDLayoutSettings.CrewArea.Location }, + "", style: "UIToggleButton"); + toggleCrewButton.OnClicked += (GUIButton btn, object userdata) => + { + toggleCrewAreaOpen = !toggleCrewAreaOpen; + foreach (GUIComponent child in btn.Children) + { + child.SpriteEffects = toggleCrewAreaOpen ? SpriteEffects.None : SpriteEffects.FlipHorizontally; + } + return true; + }; + var characterInfo = new CharacterInfo(subElement); characterInfos.Add(characterInfo); foreach (XElement invElement in subElement.Elements()) @@ -76,54 +95,21 @@ namespace Barotrauma } } - var reports = Order.PrefabList.FindAll(o => o.TargetAllCharacters && o.SymbolSprite != null); - reportButtonFrame = new GUILayoutGroup(new RectTransform( - new Point((HUDLayoutSettings.CrewArea.Height - (int)((reports.Count - 1) * 5 * GUI.Scale)) / reports.Count, HUDLayoutSettings.CrewArea.Height), guiFrame.RectTransform)) - { - AbsoluteSpacing = (int)(5 * GUI.Scale), - UserData = "reportbuttons", - CanBeFocused = false - }; - - //report buttons - foreach (Order order in reports) - { - if (!order.TargetAllCharacters || order.SymbolSprite == null) continue; - var btn = new GUIButton(new RectTransform(new Point(reportButtonFrame.Rect.Width), reportButtonFrame.RectTransform), style: null) - { - OnClicked = (GUIButton button, object userData) => - { - if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false; - SetCharacterOrder(null, order, null, Character.Controlled); - return true; - }, - UserData = order, - ToolTip = order.Name - }; - - new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow") - { - Color = Color.Red * 0.8f, - HoverColor = Color.Red * 1.0f, - PressedColor = Color.Red * 0.6f, - UserData = "highlighted", - CanBeFocused = false, - Visible = false - }; - - var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite, scaleToFit: true) - { - Color = order.Color, - HoverColor = Color.Lerp(order.Color, Color.White, 0.5f), - ToolTip = order.Name - }; - } - screenResolution = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight); prevUIScale = GUI.Scale; } + + #endregion + + #region Character list management + + public Rectangle GetCharacterListArea() + { + return characterListBox.Rect; + } + partial void InitProjectSpecific() { guiFrame = new GUIFrame(new RectTransform(Vector2.One, GUICanvas.Instance), null, Color.Transparent) @@ -1310,35 +1296,6 @@ namespace Barotrauma if (GameMain.NetworkMember != null) GameMain.Client.SelectCrewCharacter(character, previewPlayer); - bool hasIntruders = Character.CharacterList.Any(c => - c.CurrentHull == Character.Controlled.CurrentHull && !c.IsDead && - (c.AIController is EnemyAIController || (c.TeamID != Character.Controlled.TeamID && c.TeamID != Character.TeamType.FriendlyNPC))); - - ToggleReportButton("reportintruders", hasIntruders); - - foreach (GUIComponent reportButton in reportButtonFrame.Children) - { - var highlight = reportButton.GetChildByUserData("highlighted"); - if (highlight.Visible) - { - highlight.RectTransform.LocalScale = new Vector2(1.25f + (float)Math.Sin(Timing.TotalTime * 5.0f) * 0.25f); - } - } - } - else - { - reportButtonFrame.Visible = false; - } - } - - /// - /// Should report buttons be visible on the screen atm? - /// - private bool ReportButtonsVisible() - { - return CharacterHealth.OpenHealthWindow == null; - } - private bool ReportButtonClicked(GUIButton button, object userData) { //order targeted to all characters diff --git a/Barotrauma/BarotraumaClient/Source/GameSettings.cs b/Barotrauma/BarotraumaClient/Source/GameSettings.cs index 00085898f..a111ddc03 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSettings.cs @@ -626,6 +626,28 @@ 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); diff --git a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs index 72589ccf5..94a9eee32 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Components/ItemComponent.cs @@ -184,6 +184,63 @@ 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; diff --git a/Barotrauma/BarotraumaClient/Source/Items/Item.cs b/Barotrauma/BarotraumaClient/Source/Items/Item.cs index d167d6c12..52860e886 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Item.cs @@ -164,25 +164,25 @@ namespace Barotrauma Sprite activeSprite = prefab.sprite; BrokenItemSprite fadeInBrokenSprite = null; float fadeInBrokenSpriteAlpha = 0.0f; - if (condition < 100.0f) + if (condition < Prefab.Health) { for (int i = 0; i < Prefab.BrokenSprites.Count; i++) { - if (condition <= Prefab.BrokenSprites[i].MaxCondition) - { - activeSprite = Prefab.BrokenSprites[i].Sprite; - break; - } - if (Prefab.BrokenSprites[i].FadeIn) { - float min = i > 0 ? Prefab.BrokenSprites[i].MaxCondition : 0.0f; - float max = i < Prefab.BrokenSprites.Count - 1 ? Prefab.BrokenSprites[i + 1].MaxCondition : 100.0f; + float min = i > 0 ? Prefab.BrokenSprites[i - i].MaxCondition : 0.0f; + float max = Prefab.BrokenSprites[i].MaxCondition; fadeInBrokenSpriteAlpha = 1.0f - ((condition - min) / (max - min)); if (fadeInBrokenSpriteAlpha > 0.0f && fadeInBrokenSpriteAlpha < 1.0f) { fadeInBrokenSprite = Prefab.BrokenSprites[i]; } + continue; + } + if (condition <= Prefab.BrokenSprites[i].MaxCondition) + { + activeSprite = Prefab.BrokenSprites[i].Sprite; + break; } } } @@ -349,7 +349,6 @@ namespace Barotrauma GUI.DrawLine(spriteBatch, from, to, lineColor, width: 1); //GUI.DrawString(spriteBatch, from, $"Linked to {e.Name}", lineColor, Color.Black * 0.5f); } - } public void UpdateSpriteStates(float deltaTime) diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 4d50e8e6a..06a90d84c 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -1918,10 +1918,13 @@ namespace Barotrauma.Networking /// /// Tell the server to select a submarine (permission required) /// - public void RequestSelectSub(int subIndex) + public void RequestSelectSub(int subIndex, bool isShuttle) { if (!HasPermission(ClientPermissions.SelectSub)) return; - if (subIndex < 0 || subIndex >= GameMain.NetLobbyScreen.SubList.Content.CountChildren) + + var subList = isShuttle ? GameMain.NetLobbyScreen.ShuttleList.ListBox : GameMain.NetLobbyScreen.SubList; + + if (subIndex < 0 || subIndex >= subList.Content.CountChildren) { DebugConsole.ThrowError("Submarine index out of bounds (" + subIndex + ")\n" + Environment.StackTrace); return; @@ -1930,6 +1933,7 @@ namespace Barotrauma.Networking NetOutgoingMessage msg = client.CreateMessage(); msg.Write((byte)ClientPacketHeader.SERVER_COMMAND); msg.Write((UInt16)ClientPermissions.SelectSub); + msg.Write(isShuttle); msg.WritePadBits(); msg.Write((UInt16)subIndex); msg.Write((byte)ServerNetObject.END_OF_MESSAGE); @@ -2203,8 +2207,11 @@ namespace Barotrauma.Networking if (EndVoteCount > 0) { - GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 180.0f, 40), - TextManager.Get("EndRoundVotes").Replace("[y]", EndVoteCount.ToString()).Replace("[n]", (EndVoteMax - EndVoteCount).ToString()), + string endVoteText = TextManager.Get("EndRoundVotes") + .Replace("[y]", EndVoteCount.ToString()) + .Replace("[n]", (EndVoteMax - EndVoteCount).ToString()); + GUI.DrawString(spriteBatch, new Vector2(GameMain.GraphicsWidth - 10.0f - GUI.SmallFont.MeasureString(endVoteText).X, 40), + endVoteText, Color.White, font: GUI.SmallFont); } diff --git a/Barotrauma/BarotraumaClient/Source/Networking/ServerSettings.cs b/Barotrauma/BarotraumaClient/Source/Networking/ServerSettings.cs index e04e92461..335964b17 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/ServerSettings.cs @@ -142,7 +142,7 @@ namespace Barotrauma.Networking } } - public void ClientAdminWrite(NetFlags dataToSend, int missionType = 0, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0) + public void ClientAdminWrite(NetFlags dataToSend, int missionType = 0, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? useRespawnShuttle = null) { if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return; @@ -202,6 +202,8 @@ namespace Barotrauma.Networking outMsg.Write(levelDifficulty ?? -1000.0f); + outMsg.Write(useRespawnShuttle ?? UseRespawnShuttle); + outMsg.Write(autoRestart != null); outMsg.Write(autoRestart ?? false); outMsg.WritePadBits(); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs index 316dd5656..f75d58b4d 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs @@ -438,43 +438,6 @@ 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) { diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs index 463ed3365..3dabc833a 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs @@ -238,6 +238,12 @@ namespace Barotrauma GameAnalyticsManager.SetCustomDimension01(""); } + public override void Deselect() + { + base.Deselect(); + SelectTab(null, 0); + } + private bool SelectTab(GUIButton button, object obj) { if (obj is Tab) diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs index 7fa6c23aa..d965fd46a 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs @@ -132,11 +132,6 @@ namespace Barotrauma get { return shuttleList; } } - public GUITickBox ShuttleTickBox - { - get { return shuttleTickBox; } - } - public GUIListBox ModeList { get { return modeList; } @@ -190,7 +185,7 @@ namespace Barotrauma public bool UsingShuttle { get { return shuttleTickBox.Selected; } - set { shuttleTickBox.Selected = value; if (GameMain.Client != null) shuttleTickBox.Enabled = false; } + set { shuttleTickBox.Selected = value; } } public GameModePreset SelectedMode @@ -338,7 +333,7 @@ namespace Barotrauma var midInfoColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.35f, 1.0f), infoColumnContainer.RectTransform, Anchor.BottomLeft)) { RelativeSpacing = 0.02f, Stretch = true }; - var rightInfoColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.85f), infoFrameContent.RectTransform, Anchor.TopRight)) + var rightInfoColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.9f), infoFrameContent.RectTransform, Anchor.TopRight)) { RelativeSpacing = 0.02f, Stretch = true }; var topButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.07f), rightInfoColumn.RectTransform), isHorizontal: true, childAnchor: Anchor.TopRight) @@ -424,7 +419,15 @@ namespace Barotrauma OnSelected = (GUITickBox box) => { shuttleList.Enabled = box.Selected; - //if (GameMain.Server != null) lastUpdateID++; + GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, useRespawnShuttle: box.Selected); + return true; + } + }; + shuttleList = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), midInfoColumn.RectTransform), elementCount: 10) + { + OnSelected = (component, obj) => + { + GameMain.Client.RequestSelectSub(component.Parent.GetChildIndex(component), isShuttle: true); return true; } }; @@ -622,7 +625,6 @@ namespace Barotrauma OnSelected = (tickBox) => { GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, autoRestart: tickBox.Selected); - return true; } }; @@ -633,6 +635,12 @@ namespace Barotrauma TextGetter = AutoRestartText }; + ReadyToStartBox = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.06f), rightInfoColumn.RectTransform), + TextManager.Get("ReadyToStartTickBox")) + { + Visible = false + }; + StartButton = new GUIButton(new RectTransform(new Vector2(0.3f, 0.1f), infoFrameContent.RectTransform, Anchor.BottomRight), TextManager.Get("StartGameButton"), style: "GUIButtonLarge") { @@ -645,12 +653,6 @@ namespace Barotrauma }; clientHiddenElements.Add(StartButton); - ReadyToStartBox = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.06f), infoFrameContent.RectTransform, Anchor.BottomRight), - TextManager.Get("ReadyToStartTickBox"), GUI.SmallFont) - { - Visible = false - }; - campaignViewButton = new GUIButton(new RectTransform(new Vector2(0.3f, 0.1f), infoFrameContent.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.0f, 0.06f) }, TextManager.Get("CampaignView"), style: "GUIButtonLarge") { @@ -731,7 +733,7 @@ namespace Barotrauma if (GameMain.Client != null) { spectateButton.Visible = GameMain.Client.GameStarted; - ReadyToStartBox.Visible = !GameMain.Client.GameStarted && !GameMain.Client.HasPermission(ClientPermissions.ManageRound); + ReadyToStartBox.Visible = !GameMain.Client.GameStarted; ReadyToStartBox.Selected = false; GameMain.Client.SetReadyToStart(ReadyToStartBox); } @@ -841,10 +843,10 @@ namespace Barotrauma SettingsButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); SettingsButton.OnClicked = GameMain.Client.ServerSettings.ToggleSettingsFrame; - ReadyToStartBox.Visible = !GameMain.Client.HasPermission(ClientPermissions.ManageRound); StartButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageRound) && !campaignContainer.Visible; ServerName.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); ServerMessage.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); + shuttleTickBox.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings); SubList.Enabled = GameMain.Client.ServerSettings.Voting.AllowSubVoting || GameMain.Client.HasPermission(ClientPermissions.SelectSub); ModeList.Enabled = GameMain.Client.ServerSettings.Voting.AllowModeVoting || GameMain.Client.HasPermission(ClientPermissions.SelectMode); ShowLogButton.Visible = GameMain.Client.HasPermission(ClientPermissions.ServerLog); @@ -1229,7 +1231,7 @@ namespace Barotrauma { if (GameMain.Client.HasPermission(ClientPermissions.SelectSub)) { - GameMain.Client.RequestSelectSub(component.Parent.GetChildIndex(component)); + GameMain.Client.RequestSelectSub(component.Parent.GetChildIndex(component), isShuttle: false); return true; } return false; @@ -1931,6 +1933,11 @@ namespace Barotrauma if (sub == null) sub = Submarine.SavedSubmarines.FirstOrDefault(m => m.Name == subName); var matchingListSub = subList.Content.GetChildByUserData(sub); + if (sub != null && subList.SelectedData as Submarine == sub) + { + return true; + } + if (matchingListSub != null) { if (subList.Parent is GUIDropDown subDropDown) diff --git a/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs b/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs index 9cd259906..46d79ca01 100644 --- a/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs +++ b/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs @@ -164,7 +164,7 @@ namespace Barotrauma if (i < words.Length - 1) wrappedText.Append(" "); } - return wrappedText.ToString(); + return wrappedText.ToString().Replace(" \n ", "\n"); } } } diff --git a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs index dd114fd65..7e8ed91bd 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/GameServer.cs @@ -1005,6 +1005,8 @@ namespace Barotrauma.Networking } break; case ClientPermissions.SelectSub: + bool isShuttle = inc.ReadBoolean(); + inc.ReadPadBits(); UInt16 subIndex = inc.ReadUInt16(); var subList = GameMain.NetLobbyScreen.GetSubList(); if (subIndex >= subList.Count) @@ -1013,7 +1015,14 @@ namespace Barotrauma.Networking } else { - GameMain.NetLobbyScreen.SelectedSub = subList[subIndex]; + if (isShuttle) + { + GameMain.NetLobbyScreen.SelectedShuttle = subList[subIndex]; + } + else + { + GameMain.NetLobbyScreen.SelectedSub = subList[subIndex]; + } } break; case ClientPermissions.SelectMode: @@ -1360,7 +1369,7 @@ namespace Barotrauma.Networking } outmsg.Write(GameMain.NetLobbyScreen.SelectedSub.Name); outmsg.Write(GameMain.NetLobbyScreen.SelectedSub.MD5Hash.ToString()); - outmsg.Write(GameMain.NetLobbyScreen.UsingShuttle); + outmsg.Write(serverSettings.UseRespawnShuttle); outmsg.Write(GameMain.NetLobbyScreen.SelectedShuttle.Name); outmsg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.ToString()); @@ -1462,7 +1471,6 @@ namespace Barotrauma.Networking Submarine selectedSub = null; Submarine selectedShuttle = GameMain.NetLobbyScreen.SelectedShuttle; - bool usingShuttle = GameMain.NetLobbyScreen.UsingShuttle; if (serverSettings.Voting.AllowSubVoting) { @@ -1493,7 +1501,7 @@ namespace Barotrauma.Networking } initiatedStartGame = true; - startGameCoroutine = CoroutineManager.StartCoroutine(InitiateStartGame(selectedSub, selectedShuttle, usingShuttle, selectedMode), "InitiateStartGame"); + startGameCoroutine = CoroutineManager.StartCoroutine(InitiateStartGame(selectedSub, selectedShuttle, serverSettings.UseRespawnShuttle, selectedMode), "InitiateStartGame"); return true; } @@ -1758,7 +1766,7 @@ namespace Barotrauma.Networking msg.Write(selectedSub.Name); msg.Write(selectedSub.MD5Hash.Hash); - msg.Write(GameMain.NetLobbyScreen.UsingShuttle); + msg.Write(serverSettings.UseRespawnShuttle); msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.Name); msg.Write(GameMain.NetLobbyScreen.SelectedShuttle.MD5Hash.Hash); diff --git a/Barotrauma/BarotraumaServer/Source/Networking/ServerSettings.cs b/Barotrauma/BarotraumaServer/Source/Networking/ServerSettings.cs index 4b6418fb6..a9a354d94 100644 --- a/Barotrauma/BarotraumaServer/Source/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaServer/Source/Networking/ServerSettings.cs @@ -145,6 +145,8 @@ namespace Barotrauma.Networking float levelDifficulty = incMsg.ReadFloat(); if (levelDifficulty >= 0.0f) SelectedLevelDifficulty = levelDifficulty; + UseRespawnShuttle = incMsg.ReadBoolean(); + bool changedAutoRestart = incMsg.ReadBoolean(); bool autoRestart = incMsg.ReadBoolean(); if (changedAutoRestart) diff --git a/Barotrauma/BarotraumaServer/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaServer/Source/Screens/NetLobbyScreen.cs index 17072a56e..6cea05941 100644 --- a/Barotrauma/BarotraumaServer/Source/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaServer/Source/Screens/NetLobbyScreen.cs @@ -10,7 +10,6 @@ namespace Barotrauma { private Submarine selectedSub; private Submarine selectedShuttle; - private bool usingShuttle = true; public Submarine SelectedSub { @@ -22,17 +21,8 @@ namespace Barotrauma get { return selectedShuttle; } set { selectedShuttle = value; lastUpdateID++; } } - public bool UsingShuttle - { - get { return usingShuttle; } - set { usingShuttle = value; lastUpdateID++; } - } - private GameModePreset[] gameModes; - public GameModePreset[] GameModes - { - get { return gameModes; } - } + public GameModePreset[] GameModes { get; } private int selectedModeIndex; public int SelectedModeIndex @@ -41,18 +31,18 @@ namespace Barotrauma set { lastUpdateID++; - selectedModeIndex = MathHelper.Clamp(value, 0, gameModes.Length - 1); + selectedModeIndex = MathHelper.Clamp(value, 0, GameModes.Length - 1); } } public string SelectedModeIdentifier { - get { return gameModes[SelectedModeIndex].Identifier; } + get { return GameModes[SelectedModeIndex].Identifier; } set { - for (int i = 0; i < gameModes.Length; i++) + for (int i = 0; i < GameModes.Length; i++) { - if (gameModes[i].Identifier.ToLower() == value.ToLower()) + if (GameModes[i].Identifier.ToLower() == value.ToLower()) { SelectedModeIndex = i; break; @@ -63,7 +53,7 @@ namespace Barotrauma public GameModePreset SelectedMode { - get { return gameModes[SelectedModeIndex]; } + get { return GameModes[SelectedModeIndex]; } } private int missionTypeIndex; @@ -118,13 +108,26 @@ namespace Barotrauma throw new Exception("No submarines are available."); } - selectedSub = subs.First(s => !s.HasTag(SubmarineTag.Shuttle)); + selectedSub = subs.FirstOrDefault(s => !s.HasTag(SubmarineTag.Shuttle)); + if (selectedSub == null) + { + //no subs available, use a shuttle + DebugConsole.ThrowError("No full-size submarines available - choosing a shuttle as the main submarine."); + selectedSub = subs[0]; + } + selectedShuttle = subs.First(s => s.HasTag(SubmarineTag.Shuttle)); + if (selectedShuttle == null) + { + //no shuttles available, use a sub + DebugConsole.ThrowError("No shuttles available - choosing a full-size submarine as the shuttle."); + selectedShuttle = subs[0]; + } DebugConsole.NewMessage("Selected sub: " + SelectedSub.Name, Color.White); DebugConsole.NewMessage("Selected shuttle: " + SelectedShuttle.Name, Color.White); - gameModes = GameModePreset.List.ToArray(); + GameModes = GameModePreset.List.ToArray(); } private List subs; @@ -180,7 +183,7 @@ namespace Barotrauma } if (GameMain.Server.ServerSettings.ModeSelectionMode == SelectionMode.Random) { - var allowedGameModes = Array.FindAll(gameModes, m => !m.IsSinglePlayer && m.Identifier != "multiplayercampaign"); + var allowedGameModes = Array.FindAll(GameModes, m => !m.IsSinglePlayer && m.Identifier != "multiplayercampaign"); SelectedModeIdentifier = allowedGameModes[Rand.Range(0, allowedGameModes.Length)].Identifier; } } diff --git a/Barotrauma/BarotraumaShared/Icon.ico b/Barotrauma/BarotraumaShared/Icon.ico index 5b40528ea..a31034fcd 100644 Binary files a/Barotrauma/BarotraumaShared/Icon.ico and b/Barotrauma/BarotraumaShared/Icon.ico differ diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs index 20ab94f66..fbb961699 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs @@ -136,11 +136,16 @@ namespace Barotrauma public override bool IsCompleted() { - return enemy.IsDead || coolDownTimer <= 0.0f; + return enemy == null || enemy.Removed || enemy.IsDead || coolDownTimer <= 0.0f; } public override float GetPriority(AIObjectiveManager objectiveManager) { + if (enemy == null || enemy.Removed) + { + return 0.0f; + } + if (objectiveManager.CurrentOrder == this) { return AIObjectiveManager.OrderPriority; @@ -151,8 +156,7 @@ namespace Barotrauma float enemyDanger = Math.Min(Math.Max(CalculateEnemyStrength(), MaxEnemyDamage), character.Health) + enemy.Health / 10.0f; - EnemyAIController enemyAI = enemy.AIController as EnemyAIController; - if (enemyAI != null) + if (enemy.AIController is EnemyAIController enemyAI) { if (enemyAI.SelectedAiTarget == character.AiTarget) enemyDanger *= 2.0f; } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs index 73b334282..c66933f65 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs @@ -176,7 +176,7 @@ namespace Barotrauma //prefer nodes that are closer to the end position dist += (Math.Abs(end.X - nodePos.X) + Math.Abs(end.Y - nodePos.Y)) / 2.0f; //much higher cost to waypoints that are outside - if (node.Waypoint.CurrentHull == null) dist *= 10.0f; + if (node.Waypoint.CurrentHull == null && insideSubmarine) dist *= 10.0f; if (dist < closestDist || startNode == null) { //if searching for a path inside the sub, make sure the waypoint is visible @@ -213,10 +213,13 @@ namespace Barotrauma Vector2 nodePos = node.Position; float dist = Vector2.Distance(end, nodePos); - //much higher cost to waypoints that are outside - if (node.Waypoint.CurrentHull == null) dist *= 10.0f; - //avoid stopping at a doorway - if (node.Waypoint.ConnectedDoor != null) dist *= 10.0f; + if (insideSubmarine) + { + //much higher cost to waypoints that are outside + if (node.Waypoint.CurrentHull == null) dist *= 10.0f; + //avoid stopping at a doorway + if (node.Waypoint.ConnectedDoor != null) dist *= 10.0f; + } if (dist < closestDist || endNode == null) { //if searching for a path inside the sub, make sure the waypoint is visible @@ -233,13 +236,13 @@ namespace Barotrauma if (endNode == null) { - DebugConsole.NewMessage("Pathfinding error, couldn't find an end node. "+ errorMsgStr, Color.DarkRed); + DebugConsole.NewMessage("Pathfinding error, couldn't find an end node. " + errorMsgStr, Color.DarkRed); return new SteeringPath(); } - var path = FindPath(startNode,endNode); - + var path = FindPath(startNode, endNode); + return path; } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs index 468bc6397..7ec344357 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs @@ -123,7 +123,7 @@ namespace Barotrauma set { FishSwimFastParams = value as FishSwimFastParams; } } - private float flipTimer; + private float flipTimer, flipCooldown; public FishAnimController(Character character, string seed, FishRagdollParams ragdollParams = null) : base(character, seed, ragdollParams) { } @@ -250,11 +250,12 @@ namespace Barotrauma if (!CurrentFishAnimation.Flip || IsStuck) return; if (character.AIController != null && !character.AIController.CanFlip) return; - flipTimer += deltaTime; + flipCooldown -= deltaTime; if (TargetDir != Direction.None && TargetDir != dir) { - if (flipTimer > 1.0f || character.IsRemotePlayer) + flipTimer += deltaTime; + if ((flipTimer > 0.5f && flipCooldown <= 0.0f) || character.IsRemotePlayer) { Flip(); if (!inWater || (CurrentSwimParams != null && CurrentSwimParams.Mirror)) @@ -262,8 +263,13 @@ namespace Barotrauma Mirror(); } flipTimer = 0.0f; + flipCooldown = 1.0f; } } + else + { + flipTimer = 0.0f; + } } private bool CanDrag(Character target) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Health/DamageModifier.cs b/Barotrauma/BarotraumaShared/Source/Characters/Health/DamageModifier.cs index de9be0c49..c10c55bdb 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Health/DamageModifier.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Health/DamageModifier.cs @@ -69,7 +69,8 @@ namespace Barotrauma public bool MatchesAffliction(Affliction affliction) { - if (AfflictionIdentifiers.Length == 0) { return true; } + //if no identifiers or types have been defined, the damage modifier affects all afflictions + if (AfflictionIdentifiers.Length == 0 && AfflictionTypes.Length == 0) { return true; } foreach (string afflictionName in AfflictionIdentifiers) { diff --git a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs index 961fe4333..ef55fe457 100644 --- a/Barotrauma/BarotraumaShared/Source/DebugConsole.cs +++ b/Barotrauma/BarotraumaShared/Source/DebugConsole.cs @@ -149,7 +149,7 @@ namespace Barotrauma commands.SelectMany(c => c.names).ToArray(), new string[0] }; - }, isCheat: true)); + })); commands.Add(new Command("items|itemlist", "itemlist: List all the item prefabs available for spawning.", (string[] args) => @@ -382,9 +382,8 @@ namespace Barotrauma banDuration = parsedBanDuration; } - ShowQuestionPrompt("Reason for kicking \"" + client.Name + "\"?", (reason) => - { - GameMain.NetworkMember.KickPlayer(client.Name, reason); + GameMain.NetworkMember.BanPlayer(client.Name, reason, false, banDuration); + }); }); })); diff --git a/Barotrauma/BarotraumaShared/Source/GameSettings.cs b/Barotrauma/BarotraumaShared/Source/GameSettings.cs index 076edcd71..56a40ffce 100644 --- a/Barotrauma/BarotraumaShared/Source/GameSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/GameSettings.cs @@ -69,6 +69,8 @@ namespace Barotrauma public int ParticleLimit { get; set; } + public int ParticleLimit { get; set; } + public float LightMapScale { get; set; } public bool SpecularityEnabled { get; set; } public bool ChromaticAberrationEnabled { get; set; } @@ -401,6 +403,8 @@ namespace Barotrauma AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", 0.5f); + AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", 0.5f); + AimAssistAmount = doc.Root.GetAttributeFloat("aimassistamount", 0.5f); keyMapping = new KeyOrMouse[Enum.GetNames(typeof(InputType)).Length]; @@ -1252,6 +1256,84 @@ namespace Barotrauma NewLineOnAttributes = true }; +#if CLIENT + if (Tutorial.Tutorials != null) + { + foreach (Tutorial tutorial in Tutorial.Tutorials) + { + if (tutorial.Completed && !CompletedTutorialNames.Contains(tutorial.Name)) + { + CompletedTutorialNames.Add(tutorial.Name); + } + } + } +#endif + var tutorialElement = new XElement("tutorials"); + foreach (string tutorialName in CompletedTutorialNames) + { + tutorialElement.Add(new XElement("Tutorial", new XAttribute("name", tutorialName))); + } + doc.Root.Add(tutorialElement); + + XmlWriterSettings settings = new XmlWriterSettings + { + Indent = true, + OmitXmlDeclaration = true, + NewLineOnAttributes = true + }; + +#if CLIENT + if (Tutorial.Tutorials != null) + { + foreach (Tutorial tutorial in Tutorial.Tutorials) + { + if (tutorial.Completed && !CompletedTutorialNames.Contains(tutorial.Name)) + { + CompletedTutorialNames.Add(tutorial.Name); + } + } + } +#endif + var tutorialElement = new XElement("tutorials"); + foreach (string tutorialName in CompletedTutorialNames) + { + tutorialElement.Add(new XElement("Tutorial", new XAttribute("name", tutorialName))); + } + doc.Root.Add(tutorialElement); + + XmlWriterSettings settings = new XmlWriterSettings + { + Indent = true, + OmitXmlDeclaration = true, + NewLineOnAttributes = true + }; + +#if CLIENT + if (Tutorial.Tutorials != null) + { + foreach (Tutorial tutorial in Tutorial.Tutorials) + { + if (tutorial.Completed && !CompletedTutorialNames.Contains(tutorial.Name)) + { + CompletedTutorialNames.Add(tutorial.Name); + } + } + } +#endif + var tutorialElement = new XElement("tutorials"); + foreach (string tutorialName in CompletedTutorialNames) + { + tutorialElement.Add(new XElement("Tutorial", new XAttribute("name", tutorialName))); + } + doc.Root.Add(tutorialElement); + + XmlWriterSettings settings = new XmlWriterSettings + { + Indent = true, + OmitXmlDeclaration = true, + NewLineOnAttributes = true + }; + #if CLIENT if (Tutorial.Tutorials != null) { diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs index 7d71b7d36..53317666a 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs @@ -13,7 +13,7 @@ namespace Barotrauma.Items.Components partial class Steering : Powered, IServerSerializable, IClientSerializable { private const float AutopilotRayCastInterval = 0.5f; - private const float RecalculatePathInterval = 10.0f; + private const float RecalculatePathInterval = 5.0f; private Vector2 currVelocity; private Vector2 targetVelocity; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs index c3d5d2926..5e0b5c4dc 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Map/Map.cs @@ -430,6 +430,13 @@ namespace Barotrauma } CurrentLocation.SelectedMissionIndex = missionIndex; + //the destination must be the same as the destination of the mission + if (CurrentLocation.SelectedMission != null && + CurrentLocation.SelectedMission.Locations[1] != SelectedLocation) + { + SelectLocation(CurrentLocation.SelectedMission.Locations[1]); + } + SelectedLocation = location; SelectedConnection = connections.Find(c => c.Locations.Contains(CurrentLocation) && c.Locations.Contains(SelectedLocation)); OnLocationSelected?.Invoke(SelectedLocation, SelectedConnection); diff --git a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs index 09ac31d59..763b0b250 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Structure.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Structure.cs @@ -992,14 +992,14 @@ namespace Barotrauma if (IsHorizontal) { diffFromCenter = (rect.Center.X - this.rect.Center.X) / (float)this.rect.Width * BodyWidth; - if (BodyWidth > 0.0f) rect.Width = (int)(BodyWidth * (rect.Width / (float)this.rect.Width)); + if (BodyWidth > 0.0f) rect.Width = Math.Max((int)Math.Round(BodyWidth * (rect.Width / (float)this.rect.Width)), 1); if (BodyHeight > 0.0f) rect.Height = (int)BodyHeight; } else { diffFromCenter = ((rect.Y - rect.Height / 2) - (this.rect.Y - this.rect.Height / 2)) / (float)this.rect.Height * BodyHeight; if (BodyWidth > 0.0f) rect.Width = (int)BodyWidth; - if (BodyHeight > 0.0f) rect.Height = (int)(BodyHeight * (rect.Height / (float)this.rect.Height)); + if (BodyHeight > 0.0f) rect.Height = Math.Max((int)Math.Round(BodyHeight * (rect.Height / (float)this.rect.Height)), 1); } if (FlippedX) diffFromCenter = -diffFromCenter; diff --git a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs index 64f4ddb79..4d39310f9 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Submarine.cs @@ -304,7 +304,7 @@ namespace Barotrauma this.filePath = filePath; try { - name = System.IO.Path.GetFileNameWithoutExtension(filePath); + name = displayName = Path.GetFileNameWithoutExtension(filePath); } catch (Exception e) { diff --git a/Barotrauma/BarotraumaShared/Source/Networking/ServerSettings.cs b/Barotrauma/BarotraumaShared/Source/Networking/ServerSettings.cs index 253713f65..5732a9955 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/ServerSettings.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/ServerSettings.cs @@ -321,6 +321,13 @@ namespace Barotrauma.Networking set; } + [Serialize(true, true)] + public bool UseRespawnShuttle + { + get; + private set; + } + [Serialize(300.0f, true)] public float RespawnInterval { @@ -342,7 +349,6 @@ namespace Barotrauma.Networking private set; } - [Serialize(60.0f, true)] public float AutoRestartInterval { diff --git a/Barotrauma/BarotraumaShared/Source/Networking/Voting.cs b/Barotrauma/BarotraumaShared/Source/Networking/Voting.cs index a179bfe57..8ae558c4d 100644 --- a/Barotrauma/BarotraumaShared/Source/Networking/Voting.cs +++ b/Barotrauma/BarotraumaShared/Source/Networking/Voting.cs @@ -1,8 +1,5 @@ using Barotrauma.Networking; -using Lidgren.Network; -using System; using System.Collections.Generic; -using System.Linq; namespace Barotrauma { @@ -41,7 +38,7 @@ namespace Barotrauma if (voteType == VoteType.Sub && !AllowSubVoting) return default(T); if (voteType == VoteType.Mode && !AllowModeVoting) return default(T); - List> voteList = GetVoteList(voteType,voters); + List> voteList = GetVoteList(voteType, voters); T selected = default(T); int highestVotes = 0; diff --git a/Barotrauma/BarotraumaShared/Source/PlayerInput.cs b/Barotrauma/BarotraumaShared/Source/PlayerInput.cs index dac0e7d44..fc56c8fc7 100644 --- a/Barotrauma/BarotraumaShared/Source/PlayerInput.cs +++ b/Barotrauma/BarotraumaShared/Source/PlayerInput.cs @@ -160,6 +160,16 @@ namespace Barotrauma } #endif + public void SetState() + { + hit = binding.IsHit(); + if (hit) hitQueue = true; + + held = binding.IsDown(); + if (held) heldQueue = true; + } +#endif + public bool Hit { get diff --git a/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs b/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs index a267c2344..dd1fbb2e8 100644 --- a/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs +++ b/Barotrauma/BarotraumaShared/Source/StatusEffects/StatusEffect.cs @@ -693,7 +693,10 @@ namespace Barotrauma if (target is Character character) { character.LastDamageSource = entity; - character.AddDamage(entity.WorldPosition, new List() { multipliedAffliction }, stun: 0.0f, playSound: false); + foreach (Limb limb in character.AnimController.Limbs) + { + limb.character.DamageLimb(entity.WorldPosition, limb, new List() { multipliedAffliction }, stun: 0.0f, playSound: false, attackImpulse: 0.0f); + } } else if (target is Limb limb) { @@ -704,9 +707,9 @@ namespace Barotrauma foreach (Pair reduceAffliction in ReduceAffliction) { float reduceAmount = disableDeltaTime ? reduceAffliction.Second : reduceAffliction.Second * deltaTime; - if (target is Character) + if (target is Character character) { - ((Character)target).CharacterHealth.ReduceAffliction(null, reduceAffliction.First, reduceAmount); + character.CharacterHealth.ReduceAffliction(null, reduceAffliction.First, reduceAmount); } else if (target is Limb limb) {