diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs index 8f9276859..bcf133b30 100644 --- a/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaClient/Source/Characters/Animation/Ragdoll.cs @@ -152,6 +152,32 @@ namespace Barotrauma } + if (character.MemLocalState.Count > 120) character.MemLocalState.RemoveRange(0, character.MemLocalState.Count - 120); + character.MemState.Clear(); + } + } + + partial void ImpactProjSpecific(float impact, Body body) + { + float volume = MathHelper.Clamp(impact - 3.0f, 0.5f, 1.0f); + + if (body.UserData is Limb limb && character.Stun <= 0f) + { + if (impact > 3.0f) { PlayImpactSound(limb); } + } + else if (body.UserData is Limb || body == Collider.FarseerBody) + { + if (!character.IsRemotePlayer && impact > ImpactTolerance) + { + SoundPlayer.PlayDamageSound("LimbBlunt", strongestImpact, Collider); + } + } + if (Character.Controlled == character) + { + GameMain.GameScreen.Cam.Shake = Math.Min(Math.Max(strongestImpact, GameMain.GameScreen.Cam.Shake), 3.0f); + } + } + if (character.MemState.Count < 1) return; overrideTargetMovement = Vector2.Zero; diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs index 134ac7f58..0c091c992 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/GUIMessageBox.cs @@ -9,11 +9,9 @@ namespace Barotrauma public class GUIMessageBox : GUIFrame { public static List MessageBoxes = new List(); - private static int DefaultWidth - { - get { return Math.Max(400, 400 * (GameMain.GraphicsWidth / 1920)); } - } + public const int DefaultWidth = 400, DefaultHeight = 250; + public List Buttons { get; private set; } = new List(); //public GUIFrame BackgroundFrame { get; private set; } public GUILayoutGroup Content { get; private set; } @@ -23,31 +21,23 @@ namespace Barotrauma public string Tag { get; private set; } public static GUIComponent VisibleBox => MessageBoxes.LastOrDefault(); - - public GUIMessageBox(string headerText, string text, Vector2? relativeSize = null, Point? minSize = null) - : this(headerText, text, new string[] { "OK" }, relativeSize, minSize) + + public GUIMessageBox(string headerText, string text) + : this(headerText, text, new string[] {"OK"}, DefaultWidth, 0) { this.Buttons[0].OnClicked = Close; } - public GUIMessageBox(string headerText, string text, string[] buttons, Vector2? relativeSize = null, Point? minSize = null, Alignment textAlignment = Alignment.TopLeft, string tag = "") + public GUIMessageBox(string headerText, string text, int width, int height) + : this(headerText, text, new string[] { "OK" }, width, height) + { + this.Buttons[0].OnClicked = Close; + } + + // TODO: allow to use a relative size. + public GUIMessageBox(string headerText, string text, string[] buttons, int width = DefaultWidth, int height = 0, Alignment textAlignment = Alignment.TopLeft, string tag = "") : base(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: "") { - int width = DefaultWidth, height = 0; - if (relativeSize.HasValue) - { - width = (int)(GameMain.GraphicsWidth * relativeSize.Value.X); - height = (int)(GameMain.GraphicsHeight * relativeSize.Value.Y); - } - if (minSize.HasValue) - { - width = Math.Max(width, minSize.Value.X); - if (height > 0) - { - height = Math.Max(height, minSize.Value.Y); - } - } - InnerFrame = new GUIFrame(new RectTransform(new Point(width, height), RectTransform, Anchor.Center) { IsFixedSize = false }, style: null); GUI.Style.Apply(InnerFrame, "", this); @@ -59,7 +49,7 @@ namespace Barotrauma GUI.Style.Apply(Header, "", this); Header.RectTransform.MinSize = new Point(0, Header.Rect.Height); - if (height == 0) + if (!string.IsNullOrWhiteSpace(text)) { Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true); @@ -84,11 +74,7 @@ namespace Barotrauma height += Header.Rect.Height + Content.AbsoluteSpacing; height += (Text == null ? 0 : Text.Rect.Height) + Content.AbsoluteSpacing; height += buttonContainer.Rect.Height; - if (minSize.HasValue) - { - height = Math.Max(height, minSize.Value.Y); - } - + InnerFrame.RectTransform.NonScaledSize = new Point(InnerFrame.Rect.Width, (int)Math.Max(height / Content.RectTransform.RelativeSize.Y, height + 50)); Content.RectTransform.NonScaledSize = diff --git a/Barotrauma/BarotraumaClient/Source/GUI/LoadingScreen.cs b/Barotrauma/BarotraumaClient/Source/GUI/LoadingScreen.cs index 3b65a519c..bcf14a287 100644 --- a/Barotrauma/BarotraumaClient/Source/GUI/LoadingScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/GUI/LoadingScreen.cs @@ -18,38 +18,21 @@ namespace Barotrauma private Sprite languageSelectionCursor; private ScalableFont languageSelectionFont; - private Video currSplashScreen; - private DateTime videoStartTime; - - private Queue> pendingSplashScreens = new Queue>(); - /// - /// Pair.first = filepath, Pair.second = resolution - /// - public Queue> PendingSplashScreens + private Video splashScreen; + public Video SplashScreen { get { lock (loadMutex) { - return pendingSplashScreens; + return splashScreen; } } set { lock (loadMutex) { - pendingSplashScreens = value; - } - } - } - - public bool PlayingSplashScreen - { - get - { - lock (loadMutex) - { - return currSplashScreen != null; + splashScreen = value; } } } @@ -117,8 +100,8 @@ namespace Barotrauma { try { - DrawSplashScreen(spriteBatch, graphics); - if (currSplashScreen != null || PendingSplashScreens.Count > 0) { return; } + DrawSplashScreen(spriteBatch); + if (SplashScreen != null && SplashScreen.IsPlaying) return; } catch (Exception e) { @@ -218,77 +201,46 @@ namespace Barotrauma { if (languageSelectionFont == null) { - languageSelectionFont = new ScalableFont("Content/Fonts/BebasNeue-Regular.otf", (uint)(30 * (GameMain.GraphicsHeight / 1080.0f)), graphicsDevice); + languageSelectionFont = new ScalableFont("Content/Fonts/BebasNeue-Regular.otf", 28, graphicsDevice); } if (languageSelectionCursor == null) { languageSelectionCursor = new Sprite("Content/UI/cursor.png", Vector2.Zero); } - Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight * 0.3f); + Vector2 textPos = new Vector2(GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight * 0.25f); Vector2 textSpacing = new Vector2(0.0f, (GameMain.GraphicsHeight * 0.5f) / TextManager.AvailableLanguages.Count()); foreach (string language in TextManager.AvailableLanguages) { - Vector2 textSize = languageSelectionFont.MeasureString(language); - bool hover = - Math.Abs(PlayerInput.MousePosition.X - textPos.X) < textSize.X / 2 && - Math.Abs(PlayerInput.MousePosition.Y - textPos.Y) < textSpacing.Y / 2; - - //TODO: display the name of the language in the target language? - languageSelectionFont.DrawString(spriteBatch, language, textPos - textSize / 2, - hover ? Color.White : Color.White * 0.6f); - if (hover && PlayerInput.LeftButtonClicked()) - { - GameMain.Config.Language = language; - WaitForLanguageSelection = false; - } - + languageSelectionFont.DrawString(spriteBatch, language, textPos - languageSelectionFont.MeasureString(language) / 2, Color.White * 0.8f); textPos += textSpacing; } languageSelectionCursor.Draw(spriteBatch, PlayerInput.LatestMousePosition); } - private void DrawSplashScreen(SpriteBatch spriteBatch, GraphicsDevice graphics) + private void DrawSplashScreen(SpriteBatch spriteBatch) { - if (currSplashScreen == null && PendingSplashScreens.Count == 0) { return; } - - if (currSplashScreen == null) + if (SplashScreen != null) { - var newSplashScreen = PendingSplashScreens.Dequeue(); - string fileName = newSplashScreen.First; - Point resolution = newSplashScreen.Second; - try + if (SplashScreen.IsPlaying) { - currSplashScreen = new Video(graphics, GameMain.SoundManager, fileName, (uint)resolution.X, (uint)resolution.Y); - videoStartTime = DateTime.Now; - } - catch (Exception e) - { - GameMain.Config.EnableSplashScreen = false; - DebugConsole.ThrowError("Playing the splash screen \"" + fileName + "\" failed.", e); - PendingSplashScreens.Clear(); - currSplashScreen = null; - } - } + spriteBatch.Begin(); + spriteBatch.Draw(SplashScreen.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); + spriteBatch.End(); - if (currSplashScreen.IsPlaying) - { - spriteBatch.Begin(); - spriteBatch.Draw(currSplashScreen.GetTexture(), new Rectangle(0, 0, GameMain.GraphicsWidth, GameMain.GraphicsHeight), Color.White); - spriteBatch.End(); - - if (PlayerInput.KeyHit(Keys.Space) || PlayerInput.KeyHit(Keys.Enter) || PlayerInput.LeftButtonDown()) - { - currSplashScreen.Dispose(); currSplashScreen = null; + if (PlayerInput.KeyHit(Keys.Space) || PlayerInput.KeyHit(Keys.Enter) || PlayerInput.LeftButtonDown()) + { + SplashScreen.Dispose(); SplashScreen = null; + } } - } - else if (DateTime.Now > videoStartTime + new TimeSpan(0, 0, 0, 0, milliseconds: 500)) - { - currSplashScreen.Dispose(); currSplashScreen = null; - } + else + { + SplashScreen.Dispose(); SplashScreen = null; + } + } } - + bool drawn; public IEnumerable DoLoading(IEnumerable loader) { diff --git a/Barotrauma/BarotraumaClient/Source/GameMain.cs b/Barotrauma/BarotraumaClient/Source/GameMain.cs index c0568afb4..39011a6bd 100644 --- a/Barotrauma/BarotraumaClient/Source/GameMain.cs +++ b/Barotrauma/BarotraumaClient/Source/GameMain.cs @@ -270,17 +270,15 @@ namespace Barotrauma WaterRenderer.Instance = new WaterRenderer(base.GraphicsDevice, Content); loadingScreenOpen = true; - TitleScreen = new LoadingScreen(GraphicsDevice) - { - WaitForLanguageSelection = Config.ShowLanguageSelectionPrompt - }; + TitleScreen = new LoadingScreen(GraphicsDevice); + TitleScreen.WaitForLanguageSelection = Config.ShowLanguageSelectionPrompt; bool canLoadInSeparateThread = false; #if WINDOWS canLoadInSeparateThread = true; #endif - loadingCoroutine = CoroutineManager.StartCoroutine(Load(canLoadInSeparateThread), "", canLoadInSeparateThread); + loadingCoroutine = CoroutineManager.StartCoroutine(Load(), "", canLoadInSeparateThread); } private void InitUserStats() @@ -337,21 +335,16 @@ namespace Barotrauma SoundManager.SetCategoryGainMultiplier("voip", Config.VoiceChatVolume); if (Config.EnableSplashScreen) { - var pendingSplashScreens = TitleScreen.PendingSplashScreens; - pendingSplashScreens?.Enqueue(new Pair("Content/Splash_UTG.mp4", new Point(1280, 720))); - pendingSplashScreens?.Enqueue(new Pair("Content/Splash_FF.mp4", new Point(1280, 720))); - pendingSplashScreens?.Enqueue(new Pair("Content/Splash_Daedalic.mp4", new Point(1920, 1080))); - } - - //if not loading in a separate thread, wait for the splash screens to finish before continuing the loading - //otherwise the videos will look extremely choppy - if (!isSeparateThread) - { - while (TitleScreen.PlayingSplashScreen || TitleScreen.PendingSplashScreens.Count > 0) + try { - yield return CoroutineStatus.Running; + (TitleScreen as LoadingScreen).SplashScreen = new Video(base.GraphicsDevice, SoundManager, "Content/splashscreen.mp4", 1280, 720); } - } + catch (Exception e) + { + Config.EnableSplashScreen = false; + DebugConsole.ThrowError("Playing the splash screen failed.", e); + } + } GUI.Init(Window, Config.SelectedContentPackages, GraphicsDevice); DebugConsole.Init(); diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs index 8b52b1fd9..e9bd2ba83 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/CrewManager.cs @@ -74,17 +74,12 @@ namespace Barotrauma public CrewManager(XElement element, bool isSinglePlayer) : this(isSinglePlayer) { - if (GameMain.Client != null) + if (!isSinglePlayer) { - //let the server create random conversations in MP + DebugConsole.ThrowError("Cannot add messages to single player chat box in multiplayer mode!\n" + Environment.StackTrace); return; } - List availableSpeakers = Character.CharacterList.FindAll(c => - c.AIController is HumanAIController && - !c.IsDead && - c.SpeechImpediment <= 100.0f); - pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers)); - } + if (string.IsNullOrEmpty(text)) { return; } var characterInfo = new CharacterInfo(subElement); characterInfos.Add(characterInfo); @@ -95,6 +90,7 @@ namespace Barotrauma break; } } + ChatBox.AddMessage(ChatMessage.Create(senderName, text, messageType, sender)); } partial void InitProjectSpecific() @@ -243,24 +239,27 @@ namespace Barotrauma public IEnumerable GetCharacters() { - if (characterInfos.Contains(characterInfo)) - { - DebugConsole.ThrowError("Tried to add the same character info to CrewManager twice.\n" + Environment.StackTrace); - return; - } + if (character?.Inventory == null) return null; - characterInfos.Add(characterInfo); + var radioItem = character.Inventory.Items.FirstOrDefault(it => it != null && it.GetComponent() != null); + if (radioItem == null) return null; + if (requireEquipped && !character.HasEquippedItem(radioItem)) return null; + + return radioItem.GetComponent(); } public IEnumerable GetCharacterInfos() { - if (character == null) + if (GameMain.Client != null) { - DebugConsole.ThrowError("Tried to remove a null character from CrewManager.\n" + Environment.StackTrace); + //let the server create random conversations in MP return; } - characters.Remove(character); - if (removeInfo) characterInfos.Remove(character.Info); + List availableSpeakers = Character.CharacterList.FindAll(c => + c.AIController is HumanAIController && + !c.IsDead && + c.SpeechImpediment <= 100.0f); + pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers)); } public void AddCharacter(Character character) @@ -634,183 +633,9 @@ namespace Barotrauma { characterListBox.BarScroll = roundedPos; } - var characterArea = new GUIButton(new RectTransform(new Point(characterInfoWidth, frame.Rect.Height), frame.RectTransform, Anchor.CenterLeft), style: "GUITextBox") - { - UserData = character, - Color = frame.Color, - SelectedColor = frame.SelectedColor, - HoverColor = frame.HoverColor, - ToolTip = characterToolTip - }; - - var soundIcon = new GUIImage(new RectTransform(new Point((int)(characterArea.Rect.Height * 0.5f)), characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(5, 0) }, - "GUISoundIcon") - { - UserData = "soundicon", - CanBeFocused = false, - Visible = true - }; - soundIcon.Color = new Color(soundIcon.Color, 0.0f); - new GUIImage(new RectTransform(new Point((int)(characterArea.Rect.Height * 0.5f)), characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(5, 0) }, - "GUISoundIconDisabled") - { - UserData = "soundicondisabled", - CanBeFocused = true, - Visible = false - }; - - if (isSinglePlayer) - { - characterArea.OnClicked = CharacterClicked; - } - else - { - characterArea.CanBeFocused = false; - characterArea.CanBeSelected = false; - } - - var characterImage = new GUICustomComponent(new RectTransform(new Point(characterArea.Rect.Height), characterArea.RectTransform, Anchor.CenterLeft), - onDraw: (sb, component) => character.Info.DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2())) - { - CanBeFocused = false, - HoverColor = Color.White, - SelectedColor = Color.White, - ToolTip = characterToolTip - }; - - var characterName = new GUITextBlock(new RectTransform(new Point(characterArea.Rect.Width - characterImage.Rect.Width - soundIcon.Rect.Width - 10, characterArea.Rect.Height), - characterArea.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(soundIcon.Rect.Width + 10, 0) }, - character.Name, textColor: frame.Color, font: GUI.SmallFont, wrap: true) - { - Color = frame.Color, - HoverColor = Color.Transparent, - SelectedColor = Color.Transparent, - CanBeFocused = false, - ToolTip = characterToolTip, - AutoScale = true - }; - - //---------------- order buttons ---------------- - - var orderButtonFrame = new GUILayoutGroup(new RectTransform(new Point(100, frame.Rect.Height), frame.RectTransform) - { AbsoluteOffset = new Point(characterInfoWidth + spacing, 0) }, - isHorizontal: true, childAnchor: Anchor.CenterLeft) - { - AbsoluteSpacing = (int)(10 * GUI.Scale), - UserData = "orderbuttons", - CanBeFocused = false - }; - - //listbox for holding the orders inappropriate for this character - //(so we can easily toggle their visibility) - var wrongOrderList = new GUIListBox(new RectTransform(new Point(50, orderButtonFrame.Rect.Height), orderButtonFrame.RectTransform), isHorizontal: true, style: null) - { - ScrollBarEnabled = false, - ScrollBarVisible = false, - Enabled = false, - Spacing = spacing, - ClampMouseRectToParent = false - }; - wrongOrderList.Content.ClampMouseRectToParent = false; - - for (int i = 0; i < orders.Count; i++) - { - var order = orders[i]; - if (order.TargetAllCharacters) continue; - - RectTransform btnParent = (i >= correctOrderCount + neutralOrderCount) ? - wrongOrderList.Content.RectTransform : - orderButtonFrame.RectTransform; - - var btn = new GUIButton(new RectTransform(new Point(iconSize, iconSize), btnParent, Anchor.CenterLeft), - style: null) - { - UserData = order - }; - - new GUIFrame(new RectTransform(new Vector2(1.5f), btn.RectTransform, Anchor.Center), "OuterGlow") - { - Color = Color.Lerp(order.Color, frame.Color, 0.5f) * 0.8f, - HoverColor = Color.Lerp(order.Color, frame.Color, 0.5f) * 1.0f, - PressedColor = Color.Lerp(order.Color, frame.Color, 0.5f) * 0.6f, - UserData = "selected", - CanBeFocused = false, - Visible = false - }; - - var img = new GUIImage(new RectTransform(Vector2.One, btn.RectTransform), order.Prefab.SymbolSprite); - img.Scale = iconSize / (float)img.SourceRect.Width; - img.Color = Color.Lerp(order.Color, frame.Color, 0.5f); - img.ToolTip = order.Name; - img.HoverColor = Color.Lerp(img.Color, Color.White, 0.5f); - - btn.OnClicked += (GUIButton button, object userData) => - { - if (Character.Controlled == null || Character.Controlled.SpeechImpediment >= 100.0f) return false; - - if (btn.GetChildByUserData("selected").Visible) - { - SetCharacterOrder(character, Order.PrefabList.Find(o => o.AITag == "dismissed"), null, Character.Controlled); - } - else - { - if (order.ItemComponentType != null || order.ItemIdentifiers.Length > 0 || order.Options.Length > 1) - { - CreateOrderTargetFrame(button, character, order); - } - else - { - SetCharacterOrder(character, order, null, Character.Controlled); - } - } - return true; - }; - btn.UserData = order; - btn.ToolTip = order.Name; - - //divider between different groups of orders - if (i == correctOrderCount - 1 || i == correctOrderCount + neutralOrderCount - 1) - { - //TODO: divider sprite - new GUIFrame(new RectTransform(new Point(8, iconSize), orderButtonFrame.RectTransform), style: "GUIButton"); - } - } - - var toggleWrongOrderBtn = new GUIButton(new RectTransform(new Point((int)(30 * GUI.Scale), wrongOrderList.Rect.Height), wrongOrderList.Content.RectTransform), - "", style: "UIToggleButton") - { - UserData = "togglewrongorder", - CanBeFocused = false - }; - - wrongOrderList.RectTransform.NonScaledSize = new Point( - wrongOrderList.Content.Children.Sum(c => c.Rect.Width + wrongOrderList.Spacing), - wrongOrderList.RectTransform.NonScaledSize.Y); - wrongOrderList.RectTransform.SetAsLastChild(); - - new GUIFrame(new RectTransform(new Point( - wrongOrderList.Rect.Width - toggleWrongOrderBtn.Rect.Width - wrongOrderList.Spacing * 2, - wrongOrderList.Rect.Height), wrongOrderList.Content.RectTransform), - style: null) - { - CanBeFocused = false - }; - - //scale to fit the content - orderButtonFrame.RectTransform.NonScaledSize = new Point( - orderButtonFrame.Children.Sum(c => c.Rect.Width + orderButtonFrame.AbsoluteSpacing), - orderButtonFrame.RectTransform.NonScaledSize.Y); - - frame.RectTransform.NonScaledSize = new Point( - characterInfoWidth + spacing + (orderButtonFrame.Rect.Width - wrongOrderList.Rect.Width), - frame.RectTransform.NonScaledSize.Y); - - characterListBox.RectTransform.NonScaledSize = new Point( - characterListBox.Content.Children.Max(c => c.Rect.Width) + wrongOrderList.Rect.Width, - characterListBox.RectTransform.NonScaledSize.Y); - characterListBox.Content.RectTransform.NonScaledSize = characterListBox.RectTransform.NonScaledSize; - characterListBox.UpdateScrollBarSize(); - return frame; + soundIcon.Visible = !muted && !mutedLocally; + soundIconDisabled.Visible = muted || mutedLocally; + soundIconDisabled.ToolTip = TextManager.Get(mutedLocally ? "MutedLocally" : "MutedGlobally"); } private IEnumerable KillCharacterAnim(GUIComponent component) @@ -954,12 +779,6 @@ namespace Barotrauma } return; } - List availableSpeakers = Character.CharacterList.FindAll(c => - c.AIController is HumanAIController && - !c.IsDead && - c.SpeechImpediment <= 100.0f); - pendingConversationLines.AddRange(NPCConversation.CreateRandom(availableSpeakers)); - } character.SetOrder(order, option, orderGiver, speak: orderGiver != character); if (IsSinglePlayer) @@ -1017,23 +836,19 @@ namespace Barotrauma } } } - - character.SetOrder(order, option, orderGiver, speak: orderGiver != character); - if (IsSinglePlayer) + //only one target (or an order with no particular targets), just show options + else { - orderGiver?.Speak( - order.GetChatMessage(character.Name, orderGiver.CurrentHull?.DisplayName, givingOrderToSelf: character == orderGiver, orderOption: option), null); - } - else if (orderGiver != null) - { - OrderChatMessage msg = new OrderChatMessage(order, option, order.TargetItemComponent?.Item, character, orderGiver); - if (GameMain.Client != null) + orderTargetFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.2f + order.Options.Length * 0.1f, 0.18f), GUI.Canvas) + { AbsoluteOffset = new Point(orderButton.Rect.Center.X, orderButton.Rect.Bottom) }, + isHorizontal: true, childAnchor: Anchor.BottomLeft) { - GameMain.Client.SendChatMessage(msg); - } - } - DisplayCharacterOrder(character, order); - } + UserData = character, + Stretch = true + }; + //line connecting the order button to the option buttons + //TODO: sprite + new GUIFrame(new RectTransform(new Vector2(0.5f, 1.0f), orderTargetFrame.RectTransform), style: null); /// /// Create the UI panel that's used to select the target and options for a given order diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/CaptainTutorial.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/CaptainTutorial.cs index 18512989d..00ae9403c 100644 --- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/CaptainTutorial.cs +++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/CaptainTutorial.cs @@ -201,7 +201,7 @@ namespace Barotrauma.Tutorials SetHighlight(captain_statusMonitor, true); do { - //captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f); + captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f); yield return new WaitForSeconds(1.0f); } while (Submarine.MainSub.DockedTo.Count > 0); RemoveCompletedObjective(segments[4]); @@ -225,7 +225,7 @@ namespace Barotrauma.Tutorials TriggerTutorialSegment(6); // Docking do { - //captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f); + captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f); yield return new WaitForSeconds(1.0f); } while (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0); RemoveCompletedObjective(segments[6]); diff --git a/Barotrauma/BarotraumaClient/Source/Map/Levels/Level.cs b/Barotrauma/BarotraumaClient/Source/Map/Levels/Level.cs index aea1e2ea7..4f94c4362 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Levels/Level.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Levels/Level.cs @@ -25,21 +25,17 @@ namespace Barotrauma var allLevelObjects = levelObjectManager.GetAllObjects(); foreach (var levelObj in allLevelObjects) { - foreach (Sprite sprite in levelObj.Prefab.Sprites) + if (levelObj.Prefab.Sprite != null && + !uniqueTextures.Contains(levelObj.Prefab.Sprite.Texture)) { - if (!uniqueTextures.Contains(sprite.Texture)) - { - uniqueTextures.Add(sprite.Texture); - uniqueSprites.Add(sprite); - } + uniqueTextures.Add(levelObj.Prefab.Sprite.Texture); + uniqueSprites.Add(levelObj.Prefab.Sprite); } - foreach (Sprite specularSprite in levelObj.Prefab.SpecularSprites) + if (levelObj.Prefab.SpecularSprite != null && + !uniqueTextures.Contains(levelObj.Prefab.SpecularSprite.Texture)) { - if (!uniqueTextures.Contains(specularSprite.Texture)) - { - uniqueTextures.Add(specularSprite.Texture); - uniqueSprites.Add(specularSprite); - } + uniqueTextures.Add(levelObj.Prefab.SpecularSprite.Texture); + uniqueSprites.Add(levelObj.Prefab.SpecularSprite); } } diff --git a/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObject.cs b/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObject.cs index 7637d0ecb..181e555c8 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObject.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObject.cs @@ -76,8 +76,8 @@ namespace Barotrauma partial void InitProjSpecific() { - Sprite?.EnsureLazyLoaded(); - SpecularSprite?.EnsureLazyLoaded(); + Prefab.Sprite?.EnsureLazyLoaded(); + Prefab.SpecularSprite?.EnsureLazyLoaded(); Prefab.DeformableSprite?.EnsureLazyLoaded(); CurrentSwingAmount = Prefab.SwingAmountRad; diff --git a/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObjectManager.cs b/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObjectManager.cs index 4bf6eee6a..772178ac7 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObjectManager.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Levels/LevelObjects/LevelObjectManager.cs @@ -109,7 +109,7 @@ namespace Barotrauma Vector2 camDiff = new Vector2(obj.Position.X, obj.Position.Y) - cam.WorldViewCenter; camDiff.Y = -camDiff.Y; - Sprite activeSprite = specular ? obj.SpecularSprite : obj.Sprite; + Sprite activeSprite = specular ? obj.ActivePrefab.SpecularSprite : obj.ActivePrefab.Sprite; activeSprite?.Draw( spriteBatch, new Vector2(obj.Position.X, -obj.Position.Y) - camDiff * obj.Position.Z / 10000.0f, diff --git a/Barotrauma/BarotraumaClient/Source/Map/Submarine.cs b/Barotrauma/BarotraumaClient/Source/Map/Submarine.cs index 7e9d2051b..786cb5329 100644 --- a/Barotrauma/BarotraumaClient/Source/Map/Submarine.cs +++ b/Barotrauma/BarotraumaClient/Source/Map/Submarine.cs @@ -491,6 +491,18 @@ namespace Barotrauma } } + foreach (MapEntity e in MapEntity.mapEntityList) + { + if (Vector2.Distance(e.Position, HiddenSubPosition) > 20000) + { + //move disabled items (wires, items inside containers) inside the sub + if (e is Item item && item.body != null && !item.body.Enabled) + { + item.SetTransform(ConvertUnits.ToSimUnits(HiddenSubPosition), 0.0f); + } + } + } + foreach (MapEntity e in MapEntity.mapEntityList) { if (Vector2.Distance(e.Position, HiddenSubPosition) > 20000) diff --git a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs index 5807af85a..3cbe63212 100644 --- a/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs +++ b/Barotrauma/BarotraumaClient/Source/Networking/GameClient.cs @@ -1012,7 +1012,7 @@ namespace Barotrauma.Networking } } - GUIMessageBox msgBox = new GUIMessageBox(TextManager.Get("PermissionsChanged"), msg) + GUIMessageBox msgBox = new GUIMessageBox(TextManager.Get("PermissionsChanged"), msg, GUIMessageBox.DefaultWidth, 0) { UserData = "permissions" }; @@ -1707,7 +1707,7 @@ namespace Barotrauma.Networking infoButton.UserData = newSub; infoButton.OnClicked = (component, userdata) => { - ((Submarine)userdata).CreatePreviewWindow(new GUIMessageBox("", "", new Vector2(0.25f, 0.25f), new Point(500, 400))); + ((Submarine)userdata).CreatePreviewWindow(new GUIMessageBox("", "", 550, 400)); return true; }; } @@ -2401,7 +2401,7 @@ namespace Barotrauma.Networking { var banReasonPrompt = new GUIMessageBox( TextManager.Get(ban ? "BanReasonPrompt" : "KickReasonPrompt"), - "", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") }, new Vector2(0.25f, 0.2f), new Point(400, 200)); + "", new string[] { TextManager.Get("OK"), TextManager.Get("Cancel") }, 400, 300); var content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.6f), banReasonPrompt.InnerFrame.RectTransform, Anchor.Center)); var banReasonBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.3f), content.RectTransform)) diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs index 78097897d..3d3147674 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs @@ -330,6 +330,8 @@ namespace Barotrauma private GUILayoutGroup subPreviewContainer; + private GUILayoutGroup subPreviewContainer; + private GUIButton loadGameButton; public Action StartNewGame; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs index 32d12fc66..93c47bb39 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CharacterEditorScreen.cs @@ -2043,13 +2043,12 @@ namespace Barotrauma GUI.AddMessage(GetCharacterEditorTranslation("RagdollReset"), Color.WhiteSmoke, font: GUI.Font); return true; }; - Vector2 messageBoxRelSize = new Vector2(0.5f, 0.5f); int messageBoxWidth = GameMain.GraphicsWidth / 2; int messageBoxHeight = GameMain.GraphicsHeight / 2; var saveRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("SaveRagdoll")); saveRagdollButton.OnClicked += (button, userData) => { - var box = new GUIMessageBox(GetCharacterEditorTranslation("SaveRagdoll"), $"{GetCharacterEditorTranslation("ProvideFileName")}: ", new string[] { TextManager.Get("Cancel"), TextManager.Get("Save") }, messageBoxRelSize); + var box = new GUIMessageBox(GetCharacterEditorTranslation("SaveRagdoll"), $"{GetCharacterEditorTranslation("ProvideFileName")}: ", new string[] { TextManager.Get("Cancel"), TextManager.Get("Save") }, messageBoxWidth, messageBoxHeight); var inputField = new GUITextBox(new RectTransform(new Point(box.Content.Rect.Width, 30), box.Content.RectTransform, Anchor.Center), RagdollParams.Name); box.Buttons[0].OnClicked += (b, d) => { @@ -2077,7 +2076,7 @@ namespace Barotrauma var loadRagdollButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("LoadRagdoll")); loadRagdollButton.OnClicked += (button, userData) => { - var loadBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadRagdoll"), "", new string[] { TextManager.Get("Cancel"), TextManager.Get("Load"), TextManager.Get("Delete") }, messageBoxRelSize); + var loadBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadRagdoll"), "", new string[] { TextManager.Get("Cancel"), TextManager.Get("Load"), TextManager.Get("Delete") }, messageBoxWidth, messageBoxHeight); loadBox.Buttons[0].OnClicked += loadBox.Close; var listBox = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.6f), loadBox.Content.RectTransform, Anchor.TopCenter)); var deleteButton = loadBox.Buttons[2]; @@ -2123,7 +2122,7 @@ namespace Barotrauma var msgBox = new GUIMessageBox( TextManager.Get("DeleteDialogLabel"), TextManager.Get("DeleteDialogQuestion").Replace("[file]", selectedFile), - new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") }); + new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") }, messageBoxWidth - 100, messageBoxHeight - 100); msgBox.Buttons[0].OnClicked += (b, d) => { try @@ -2164,7 +2163,7 @@ namespace Barotrauma var saveAnimationButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("SaveAnimation")); saveAnimationButton.OnClicked += (button, userData) => { - var box = new GUIMessageBox(GetCharacterEditorTranslation("SaveAnimation"), string.Empty, new string[] { TextManager.Get("Cancel"), TextManager.Get("Save") }, messageBoxRelSize); + var box = new GUIMessageBox(GetCharacterEditorTranslation("SaveAnimation"), string.Empty, new string[] { TextManager.Get("Cancel"), TextManager.Get("Save") }, messageBoxWidth, messageBoxHeight); var textArea = new GUIFrame(new RectTransform(new Vector2(1, 0.1f), box.Content.RectTransform) { MinSize = new Point(350, 30) }, style: null); var inputLabel = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), textArea.RectTransform) { MinSize = new Point(250, 30) }, $"{GetCharacterEditorTranslation("ProvideFileName")}: "); var inputField = new GUITextBox(new RectTransform(new Vector2(0.5f, 1), textArea.RectTransform, Anchor.TopRight) { MinSize = new Point(100, 30) }, CurrentAnimation.Name); @@ -2212,7 +2211,7 @@ namespace Barotrauma var loadAnimationButton = new GUIButton(new RectTransform(buttonSize, layoutGroup.RectTransform), GetCharacterEditorTranslation("LoadAnimation")); loadAnimationButton.OnClicked += (button, userData) => { - var loadBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadAnimation"), "", new string[] { TextManager.Get("Cancel"), TextManager.Get("Load"), TextManager.Get("Delete") }, messageBoxRelSize); + var loadBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadAnimation"), "", new string[] { TextManager.Get("Cancel"), TextManager.Get("Load"), TextManager.Get("Delete") }, messageBoxWidth, messageBoxHeight); loadBox.Buttons[0].OnClicked += loadBox.Close; var listBox = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.6f), loadBox.Content.RectTransform)); var deleteButton = loadBox.Buttons[2]; @@ -2274,7 +2273,7 @@ namespace Barotrauma var msgBox = new GUIMessageBox( TextManager.Get("DeleteDialogLabel"), TextManager.Get("DeleteDialogQuestion").Replace("[file]", selectedFile), - new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") }); + new string[] { TextManager.Get("Yes"), TextManager.Get("Cancel") }, messageBoxWidth - 100, messageBoxHeight - 100); msgBox.Buttons[0].OnClicked += (b, d) => { try @@ -4426,7 +4425,7 @@ namespace Barotrauma protected override GUIMessageBox Create() { - var box = new GUIMessageBox(GetCharacterEditorTranslation("CreateNewCharacter"), string.Empty, new string[] { TextManager.Get("Cancel"), TextManager.Get("Next") }, new Vector2(0.5f, 1.0f)); + var box = new GUIMessageBox(GetCharacterEditorTranslation("CreateNewCharacter"), string.Empty, new string[] { TextManager.Get("Cancel"), TextManager.Get("Next") }, GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight); box.Content.ChildAnchor = Anchor.TopCenter; box.Content.AbsoluteSpacing = 20; int elementSize = 30; @@ -4542,7 +4541,7 @@ namespace Barotrauma protected override GUIMessageBox Create() { - var box = new GUIMessageBox(GetCharacterEditorTranslation("DefineRagdoll"), string.Empty, new string[] { TextManager.Get("Previous"), TextManager.Get("Create") }, new Vector2(0.5f, 1.0f)); + var box = new GUIMessageBox(GetCharacterEditorTranslation("DefineRagdoll"), string.Empty, new string[] { TextManager.Get("Previous"), TextManager.Get("Create") }, GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight); box.Content.ChildAnchor = Anchor.TopCenter; box.Content.AbsoluteSpacing = 20; int elementSize = 30; @@ -4622,7 +4621,7 @@ namespace Barotrauma { if (htmlBox == null) { - htmlBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadHTML"), string.Empty, new string[] { TextManager.Get("Close"), TextManager.Get("Load") }, new Vector2(0.5f, 1.0f)); + htmlBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadHTML"), string.Empty, new string[] { TextManager.Get("Close"), TextManager.Get("Load") }, GameMain.GraphicsWidth / 2, GameMain.GraphicsHeight); var element = new GUIFrame(new RectTransform(new Vector2(0.8f, 0.05f), htmlBox.Content.RectTransform), style: null, color: Color.Gray * 0.25f); new GUITextBlock(new RectTransform(new Vector2(0.5f, 1), element.RectTransform), GetCharacterEditorTranslation("HTMLPath")); var htmlPathElement = new GUITextBox(new RectTransform(new Vector2(0.5f, 1), element.RectTransform, Anchor.TopRight), $"Content/Characters/{Name}/{Name}.html"); diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CreditsPlayer.cs b/Barotrauma/BarotraumaClient/Source/Screens/CreditsPlayer.cs index 2406d8970..663a85eb9 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/CreditsPlayer.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/CreditsPlayer.cs @@ -1,5 +1,8 @@ using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; using System; +using System.Collections.Generic; +using System.Text; using System.Xml.Linq; namespace Barotrauma @@ -8,7 +11,7 @@ namespace Barotrauma { private GUIListBox listBox; - private readonly float scrollSpeed; + private float scrollSpeed; public CreditsPlayer(RectTransform rectT, string configFile) : base(null, rectT) { diff --git a/Barotrauma/BarotraumaClient/Source/Screens/LevelEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/LevelEditorScreen.cs index 14dd89537..ba8a40c79 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/LevelEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/LevelEditorScreen.cs @@ -174,10 +174,7 @@ namespace Barotrauma foreach (LevelObjectPrefab levelObjPrefab in LevelObjectPrefab.List) { - foreach (Sprite sprite in levelObjPrefab.Sprites) - { - sprite?.EnsureLazyLoaded(); - } + levelObjPrefab.Sprite?.EnsureLazyLoaded(); } pointerLightSource = new LightSource(Vector2.Zero, 1000.0f, Color.White, submarine: null); @@ -254,7 +251,7 @@ namespace Barotrauma CanBeFocused = false, }; - Sprite sprite = levelObjPrefab.Sprites.FirstOrDefault() ?? levelObjPrefab.DeformableSprite?.Sprite; + Sprite sprite = levelObjPrefab.Sprite ?? levelObjPrefab.DeformableSprite?.Sprite; GUIImage img = new GUIImage(new RectTransform(new Point(paddedFrame.Rect.Height, paddedFrame.Rect.Height - textBlock.Rect.Height), paddedFrame.RectTransform, Anchor.TopCenter), sprite, scaleToFit: true) { @@ -292,7 +289,7 @@ namespace Barotrauma editor.AddCustomContent(commonnessContainer, 1); } - Sprite sprite = levelObjectPrefab.Sprites.FirstOrDefault() ?? levelObjectPrefab.DeformableSprite?.Sprite; + Sprite sprite = levelObjectPrefab.Sprite ?? levelObjectPrefab.DeformableSprite?.Sprite; if (sprite != null) { editor.AddCustomContent(new GUIButton(new RectTransform(new Point(editor.Rect.Width / 2, 20)), @@ -300,6 +297,7 @@ namespace Barotrauma { OnClicked = (btn, userdata) => { + GameMain.SpriteEditorScreen.RefreshLists(); editingSprite = sprite; GameMain.SpriteEditorScreen.SelectSprite(editingSprite); return true; @@ -604,7 +602,7 @@ namespace Barotrauma public GUIMessageBox Create() { var box = new GUIMessageBox(TextManager.Get("LevelEditorCreateLevelObj"), string.Empty, - new string[] { TextManager.Get("Cancel"), TextManager.Get("Done") }, new Vector2(0.5f, 0.8f)); + new string[] { TextManager.Get("Cancel"), TextManager.Get("Done") }, GameMain.GraphicsWidth / 2, (int)(GameMain.GraphicsHeight * 0.8f)); box.Content.ChildAnchor = Anchor.TopCenter; box.Content.AbsoluteSpacing = 20; @@ -620,8 +618,8 @@ namespace Barotrauma var texturePathBox = new GUITextBox(new RectTransform(new Point(listBox.Content.Rect.Width, elementSize), listBox.Content.RectTransform)); foreach (LevelObjectPrefab prefab in LevelObjectPrefab.List) { - if (prefab.Sprites.FirstOrDefault() == null) continue; - texturePathBox.Text = Path.GetDirectoryName(prefab.Sprites.FirstOrDefault().FilePath); + if (prefab.Sprite == null) continue; + texturePathBox.Text = Path.GetDirectoryName(prefab.Sprite.FilePath); break; } @@ -678,8 +676,6 @@ namespace Barotrauma doc.WriteTo(writer); writer.Flush(); } - // Recreate the prefab so that the sprite loads correctly: TODO: consider a better way to do this - newPrefab = new LevelObjectPrefab(newElement); break; } diff --git a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs index 96c441896..09d48fdbc 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/MainMenuScreen.cs @@ -44,15 +44,15 @@ namespace Barotrauma { backgroundVignette = new Sprite("Content/UI/MainMenuVignette.png", Vector2.Zero); - new GUIImage(new RectTransform(new Vector2(0.4f, 0.25f), Frame.RectTransform, Anchor.BottomRight) - { RelativeOffset = new Vector2(0.08f, 0.05f), AbsoluteOffset = new Point(-8, -8) }, + new GUIImage(new RectTransform(new Vector2(0.35f, 0.2f), Frame.RectTransform, Anchor.BottomRight) + { RelativeOffset = new Vector2(0.05f, 0.1f), AbsoluteOffset = new Point(-8, -8) }, style: "TitleText") { Color = Color.Black * 0.5f, CanBeFocused = false }; - titleText = new GUIImage(new RectTransform(new Vector2(0.4f, 0.25f), Frame.RectTransform, Anchor.BottomRight) - { RelativeOffset = new Vector2(0.08f, 0.05f) }, + titleText = new GUIImage(new RectTransform(new Vector2(0.35f, 0.2f), Frame.RectTransform, Anchor.BottomRight) + { RelativeOffset = new Vector2(0.05f, 0.1f) }, style: "TitleText"); buttonsParent = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 0.85f), parent: Frame.RectTransform, anchor: Anchor.CenterLeft) @@ -354,12 +354,6 @@ namespace Barotrauma }; var creditsContainer = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.5f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.CenterRight), style: "OuterGlow", color: Color.Black * 0.8f); creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml"); - - new GUIButton(new RectTransform(new Vector2(0.1f, 0.05f), menuTabs[(int)Tab.Credits].RectTransform, Anchor.BottomLeft) { RelativeOffset = new Vector2(0.25f, 0.02f) }, - TextManager.Get("Back"), style: "GUIButtonLarge") - { - OnClicked = SelectTab - }; } #endregion @@ -389,9 +383,10 @@ namespace Barotrauma private bool SelectTab(GUIButton button, object obj) { - titleText.Visible = true; if (obj is Tab) { + titleText.Visible = true; + if (GameMain.Config.UnsavedSettings) { var applyBox = new GUIMessageBox( @@ -789,10 +784,6 @@ namespace Barotrauma GUI.Draw(Cam, spriteBatch); - spriteBatch.Begin(SpriteSortMode.Deferred, null, null, null, GameMain.ScissorTestEnable); - - GUI.Draw(Cam, spriteBatch); - GUI.Draw(Cam, spriteBatch); #if DEBUG diff --git a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs index 76acba2cd..fd5dfbfd0 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/NetLobbyScreen.cs @@ -1212,7 +1212,7 @@ namespace Barotrauma }; infoButton.OnClicked += (component, userdata) => { - ((Submarine)userdata).CreatePreviewWindow(new GUIMessageBox("", "", new Vector2(0.25f, 0.25f), new Point(500, 400))); + ((Submarine)userdata).CreatePreviewWindow(new GUIMessageBox("", "", 550, 600)); return true; }; } @@ -2005,8 +2005,7 @@ namespace Barotrauma return false; } - var requestFileBox = new GUIMessageBox(TextManager.Get("DownloadSubLabel"), errorMsg, - new string[] { TextManager.Get("Yes"), TextManager.Get("No") }) + var requestFileBox = new GUIMessageBox(TextManager.Get("DownloadSubLabel"), errorMsg, new string[] { TextManager.Get("Yes"), TextManager.Get("No") }, 400, 300) { UserData = "request" + subName }; diff --git a/Barotrauma/BarotraumaClient/Source/Screens/SpriteEditorScreen.cs b/Barotrauma/BarotraumaClient/Source/Screens/SpriteEditorScreen.cs index 38946e9ec..f924e04a8 100644 --- a/Barotrauma/BarotraumaClient/Source/Screens/SpriteEditorScreen.cs +++ b/Barotrauma/BarotraumaClient/Source/Screens/SpriteEditorScreen.cs @@ -193,7 +193,50 @@ namespace Barotrauma { Sprite sprite = userData as Sprite; if (sprite == null) return false; - SelectSprite(sprite); + if (selectedSprites.Any(s => s.Texture != selectedTexture)) + { + ResetWidgets(); + } + if (Widget.EnableMultiSelect) + { + if (selectedSprites.Contains(sprite)) + { + selectedSprites.Remove(sprite); + } + else + { + selectedSprites.Add(sprite); + dirtySprites.Add(sprite); + lastSelected = sprite; + } + } + else + { + selectedSprites.Clear(); + selectedSprites.Add(sprite); + dirtySprites.Add(sprite); + lastSelected = sprite; + } + if (selectedTexture != sprite.Texture) + { + textureList.Select(sprite.Texture, autoScroll: false); + UpdateScrollBar(textureList); + } + xmlPathText.Text = string.Empty; + foreach (var s in selectedSprites) + { + texturePathText.Text = s.FilePath; + var element = s.SourceElement; + if (element != null) + { + string xmlPath = element.ParseContentPathFromUri(); + if (!xmlPathText.Text.Contains(xmlPath)) + { + xmlPathText.Text += "\n" + xmlPath; + } + } + } + xmlPathText.TextColor = Color.LightGray; return true; } }; @@ -567,56 +610,11 @@ namespace Barotrauma public void SelectSprite(Sprite sprite) { - if (!loadedSprites.Contains(sprite)) - { - loadedSprites.Add(sprite); - RefreshLists(); - } - - if (selectedSprites.Any(s => s.Texture != selectedTexture)) - { - ResetWidgets(); - } - if (Widget.EnableMultiSelect) - { - if (selectedSprites.Contains(sprite)) - { - selectedSprites.Remove(sprite); - } - else - { - selectedSprites.Add(sprite); - dirtySprites.Add(sprite); - lastSelected = sprite; - } - } - else - { - selectedSprites.Clear(); - selectedSprites.Add(sprite); - dirtySprites.Add(sprite); - lastSelected = sprite; - } - if (selectedTexture != sprite.Texture) - { - textureList.Select(sprite.Texture, autoScroll: false); - UpdateScrollBar(textureList); - } - xmlPathText.Text = string.Empty; - foreach (var s in selectedSprites) - { - texturePathText.Text = s.FilePath; - var element = s.SourceElement; - if (element != null) - { - string xmlPath = element.ParseContentPathFromUri(); - if (!xmlPathText.Text.Contains(xmlPath)) - { - xmlPathText.Text += "\n" + xmlPath; - } - } - } - xmlPathText.TextColor = Color.LightGray; + ResetWidgets(); + textureList.Select(sprite.Texture); + ResetZoom(); + selectedSprites.Clear(); + selectedSprites.Add(sprite); } public void RefreshLists() @@ -661,7 +659,6 @@ namespace Barotrauma public void ResetZoom() { - if (selectedTexture == null) { return; } var viewArea = GetViewArea; float width = viewArea.Width / (float)selectedTexture.Width; float height = viewArea.Height / (float)selectedTexture.Height; diff --git a/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs b/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs index d7570deb8..fb6a86f1e 100644 --- a/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs +++ b/Barotrauma/BarotraumaClient/Source/Serialization/SerializableEntityEditor.cs @@ -906,7 +906,7 @@ namespace Barotrauma public void CreateTextPicker(string textTag, ISerializableEntity entity, SerializableProperty property, GUITextBox textBox) { - var msgBox = new GUIMessageBox("", "", new string[] { TextManager.Get("Cancel") }, new Vector2(0.2f, 0.5f), new Point(300, 400)); + var msgBox = new GUIMessageBox("", "", new string[] { TextManager.Get("Cancel") }, width: 300, height: 400); msgBox.Buttons[0].OnClicked = msgBox.Close; var textList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.8f), msgBox.Content.RectTransform, Anchor.TopCenter)) diff --git a/Barotrauma/BarotraumaShared/SharedContent.projitems b/Barotrauma/BarotraumaShared/SharedContent.projitems index 6313bfa09..f9667893d 100644 --- a/Barotrauma/BarotraumaShared/SharedContent.projitems +++ b/Barotrauma/BarotraumaShared/SharedContent.projitems @@ -454,12 +454,24 @@ PreserveNewest + + PreserveNewest + PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest + + PreserveNewest + PreserveNewest @@ -493,66 +505,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -575,15 +527,6 @@ PreserveNewest - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -614,9 +557,6 @@ PreserveNewest - - PreserveNewest - PreserveNewest @@ -1691,6 +1631,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -3203,6 +3146,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs index b991f524f..9f23a116a 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjective.cs @@ -106,6 +106,18 @@ namespace Barotrauma subObjectives.Add(objective); } + public void RemoveSubObjective(ref T objective) where T : AIObjective + { + if (objective != null) + { + if (subObjectives.Contains(objective)) + { + subObjectives.Remove(objective); + } + objective = null; + } + } + public void SortSubObjectives() { if (subObjectives.None()) { return; } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs index ce7122b63..047d55861 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs @@ -11,9 +11,10 @@ namespace Barotrauma class AIObjectiveCombat : AIObjective { public override string DebugTag => "combat"; - public bool useCoolDown = true; - const float CoolDown = 10.0f; + private readonly CombatMode initialMode; + + const float coolDown = 10.0f; public Character Enemy { get; private set; } @@ -25,14 +26,7 @@ namespace Barotrauma { _weapon = value; _weaponComponent = null; - if (reloadWeaponObjective != null) - { - if (subObjectives.Contains(reloadWeaponObjective)) - { - subObjectives.Remove(reloadWeaponObjective); - } - reloadWeaponObjective = null; - } + RemoveSubObjective(ref reloadWeaponObjective); } } private ItemComponent _weaponComponent; @@ -40,6 +34,7 @@ namespace Barotrauma { get { + if (Weapon == null) { return null; } if (_weaponComponent == null) { _weaponComponent = @@ -64,6 +59,8 @@ namespace Barotrauma private Hull retreatTarget; private float coolDownTimer; + private IEnumerable myBodies; + private float aimTimer; public enum CombatMode { @@ -78,7 +75,7 @@ namespace Barotrauma : base(character, objectiveManager, priorityModifier) { Enemy = enemy; - coolDownTimer = CoolDown; + coolDownTimer = coolDown; findSafety = objectiveManager.GetObjective(); if (findSafety != null) { @@ -86,6 +83,7 @@ namespace Barotrauma findSafety.unreachable.Clear(); } Mode = mode; + initialMode = Mode; if (Enemy == null) { Mode = CombatMode.Retreat; @@ -104,7 +102,7 @@ namespace Barotrauma public override bool IsCompleted() { - bool completed = (Enemy != null && (Enemy.Removed || Enemy.IsDead)) || (useCoolDown && coolDownTimer <= 0); + bool completed = (Enemy != null && (Enemy.Removed || Enemy.IsDead)) || (initialMode != CombatMode.Offensive && coolDownTimer <= 0); if (completed) { if (objectiveManager.CurrentOrder == this && Enemy != null && Enemy.IsDead) @@ -121,58 +119,73 @@ namespace Barotrauma protected override void Act(float deltaTime) { - if (useCoolDown) + if (initialMode != CombatMode.Offensive) { coolDownTimer -= deltaTime; } if (abandon) { return; } - Arm(deltaTime); - Move(deltaTime); + TryArm(); + if (reloadWeaponObjective == null || !subObjectives.Contains(reloadWeaponObjective)) + { + Move(); + OperateWeapon(deltaTime); + } } - private void Arm(float deltaTime) + private void Move() { switch (Mode) { case CombatMode.Offensive: - case CombatMode.Defensive: - if (Weapon != null && !character.Inventory.Items.Contains(_weapon) || _weaponComponent != null && !_weaponComponent.HasRequiredContainedItems(false)) - { - Weapon = null; - } - if (Weapon == null) - { - Weapon = GetWeapon(); - } - if (Weapon == null) - { - Mode = CombatMode.Retreat; - } - if (Equip()) - { - if (Reload(deltaTime)) - { - Attack(deltaTime); - } - } + Engage(); break; + case CombatMode.Defensive: case CombatMode.Retreat: + Retreat(); break; default: throw new NotImplementedException(); } } - private void Move(float deltaTime) + private void TryArm() + { + if (Weapon != null) + { + if (!character.Inventory.Items.Contains(Weapon) || WeaponComponent == null) + { + Weapon = null; + } + else if (!WeaponComponent.HasRequiredContainedItems(false)) + { + //if (!Reload()) + //{ + // Weapon = null; + // Mode = CombatMode.Retreat; + //} + //return; + Weapon = null; + } + } + if (Weapon == null) + { + Weapon = GetWeapon(); + } + Mode = Weapon == null ? CombatMode.Retreat : initialMode; + } + + private void OperateWeapon(float deltaTime) { switch (Mode) { case CombatMode.Offensive: - Engage(deltaTime); - break; case CombatMode.Defensive: + if (Equip()) + { + Attack(deltaTime); + } + break; case CombatMode.Retreat: - Retreat(deltaTime); break; default: throw new NotImplementedException(); @@ -253,6 +266,7 @@ namespace Barotrauma Weapon.Drop(character); } } + return true; } private bool Equip() @@ -263,9 +277,11 @@ namespace Barotrauma if (character.Inventory.TryPutItem(Weapon, character, slots)) { Weapon.Equip(character); + aimTimer = Rand.Range(0.5f, 1f); } else { + Weapon = null; Mode = CombatMode.Retreat; return false; } @@ -273,16 +289,10 @@ namespace Barotrauma return true; } - private void Retreat(float deltaTime) + private void Retreat() { - if (followTargetObjective != null) - { - if (subObjectives.Contains(followTargetObjective)) - { - subObjectives.Remove(followTargetObjective); - } - followTargetObjective = null; - } + RemoveSubObjective(ref followTargetObjective); + RemoveSubObjective(ref reloadWeaponObjective); if (retreatObjective != null && retreatObjective.Target != retreatTarget) { retreatObjective = null; @@ -294,16 +304,14 @@ namespace Barotrauma TryAddSubObjective(ref retreatObjective, () => new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true)); } - private void Engage(float deltaTime) + private void Engage() { retreatTarget = null; - if (retreatObjective != null) + RemoveSubObjective(ref retreatObjective); + RemoveSubObjective(ref reloadWeaponObjective); + if (followTargetObjective != null && followTargetObjective.Target != Enemy) { - if (subObjectives.Contains(retreatObjective)) - { - subObjectives.Remove(retreatObjective); - } - retreatObjective = null; + followTargetObjective = null; } TryAddSubObjective(ref followTargetObjective, constructor: () => new AIObjectiveGoTo(Enemy, character, objectiveManager, repeat: true, getDivingGearIfNeeded: true) @@ -318,35 +326,44 @@ namespace Barotrauma }, onAbandon: () => { - SteeringManager.Reset(); Mode = CombatMode.Retreat; + SteeringManager.Reset(); }); } - private bool Reload(float deltaTime) + private bool Reload() { - if (WeaponComponent != null && WeaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained)) + // TODO: reload all ammunition + if (WeaponComponent == null) { return false; } + if (WeaponComponent.requiredItems.ContainsKey(RelatedItem.RelationType.Contained)) { var containedItems = Weapon.ContainedItems; + RelatedItem item = null; + Item ammunition = null; foreach (RelatedItem requiredItem in WeaponComponent.requiredItems[RelatedItem.RelationType.Contained]) { - Item containedItem = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it)); - if (containedItem == null) - { - TryAddSubObjective(ref reloadWeaponObjective, - constructor: () => new AIObjectiveContainItem(character, requiredItem.Identifiers, Weapon.GetComponent(), objectiveManager), - onAbandon: () => - { - SteeringManager.Reset(); - Mode = CombatMode.Retreat; - }); - } + item = requiredItem; + ammunition = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it)); + if (ammunition != null) { return true; } + } + if (ammunition == null) + { + retreatTarget = null; + RemoveSubObjective(ref retreatObjective); + RemoveSubObjective(ref followTargetObjective); + TryAddSubObjective(ref reloadWeaponObjective, + constructor: () => new AIObjectiveContainItem(character, item.Identifiers, Weapon.GetComponent(), objectiveManager), + onAbandon: () => + { + Weapon = null; + Mode = CombatMode.Retreat; + SteeringManager.Reset(); + }); } } - return reloadWeaponObjective == null || reloadWeaponObjective.IsCompleted(); + return true; } - private IEnumerable myBodies; private void Attack(float deltaTime) { float squaredDistance = Vector2.DistanceSquared(character.Position, Enemy.Position); @@ -371,6 +388,16 @@ namespace Barotrauma character.SetInput(InputType.Aim, false, true); } } + bool isFacing = character.AnimController.Dir > 0 && Enemy.WorldPosition.X > character.WorldPosition.X || character.AnimController.Dir < 0 && Enemy.WorldPosition.X < character.WorldPosition.X; + if (!isFacing) + { + aimTimer = Rand.Range(1f, 1.5f); + } + if (aimTimer > 0) + { + aimTimer -= deltaTime; + return; + } if (WeaponComponent is MeleeWeapon meleeWeapon) { if (squaredDistance <= meleeWeapon.Range * meleeWeapon.Range) @@ -385,14 +412,14 @@ namespace Barotrauma { if (squaredDistance > repairTool.Range * repairTool.Range) { return; } } - if (VectorExtensions.Angle(VectorExtensions.Forward(Weapon.body.TransformedRotation), Enemy.Position - character.Position) < MathHelper.PiOver4) + if (VectorExtensions.Angle(VectorExtensions.Forward(Weapon.body.TransformedRotation), Enemy.Position - Weapon.Position) < MathHelper.PiOver4) { if (myBodies == null) { myBodies = character.AnimController.Limbs.Select(l => l.body.FarseerBody); } var collisionCategories = Physics.CollisionCharacter | Physics.CollisionWall; - var pickedBody = Submarine.PickBody(character.SimPosition, Enemy.SimPosition, myBodies, collisionCategories); + var pickedBody = Submarine.PickBody(Weapon.SimPosition, Enemy.SimPosition, myBodies, collisionCategories); if (pickedBody != null) { Character target = null; @@ -404,10 +431,11 @@ namespace Barotrauma { target = limb.character; } - if (target != null && target == Enemy) + if (target != null && (target == Enemy || !HumanAIController.IsFriendly(target))) { character.SetInput(InputType.Shoot, false, true); Weapon.Use(deltaTime, character); + aimTimer = Rand.Range(0.25f, 0.5f); } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFightIntruders.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFightIntruders.cs index 91ebb94f6..9039a5011 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFightIntruders.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFightIntruders.cs @@ -29,7 +29,7 @@ namespace Barotrauma protected override IEnumerable GetList() => Character.CharacterList; - protected override AIObjective ObjectiveConstructor(Character target) => new AIObjectiveCombat(character, target, AIObjectiveCombat.CombatMode.Offensive, objectiveManager, PriorityModifier) { useCoolDown = false }; + protected override AIObjective ObjectiveConstructor(Character target) => new AIObjectiveCombat(character, target, AIObjectiveCombat.CombatMode.Offensive, objectiveManager, PriorityModifier); protected override float TargetEvaluation() { diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs index 73a53f052..e6d61f690 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveFixLeak.cs @@ -725,6 +725,31 @@ namespace Barotrauma { #if DEBUG DebugConsole.ThrowError("AIObjectiveFixLeak failed - the item \"" + weldingTool + "\" has no RepairTool component but is tagged as a welding tool"); +#endif + abandon = true; + return; + } + Vector2 gapDiff = Leak.WorldPosition - character.WorldPosition; + // TODO: use the collider size/reach? + if (!character.AnimController.InWater && Math.Abs(gapDiff.X) < 100 && gapDiff.Y < 0.0f && gapDiff.Y > -150) + { + HumanAIController.AnimController.Crouching = true; + } + float reach = ConvertUnits.ToSimUnits(repairTool.Range); + bool canOperate = ConvertUnits.ToSimUnits(gapDiff.Length()) < reach; + if (canOperate) + { + TryAddSubObjective(ref operateObjective, () => new AIObjectiveOperateItem(repairTool, character, objectiveManager, option: "", requireEquip: true, operateTarget: Leak)); + } + else + { + TryAddSubObjective(ref gotoObjective, () => new AIObjectiveGoTo(ConvertUnits.ToSimUnits(GetStandPosition()), character, objectiveManager) { CloseEnough = reach * 0.75f }); + } + var repairTool = weldingTool.GetComponent(); + if (repairTool == null) + { +#if DEBUG + DebugConsole.ThrowError("AIObjectiveFixLeak failed - the item \"" + weldingTool + "\" has no RepairTool component but is tagged as a welding tool"); #endif abandon = true; return; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs index 1e1e961f6..eeef8131c 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveIdle.cs @@ -73,21 +73,6 @@ namespace Barotrauma } } - public override void Update(float deltaTime) - { - if (objectiveManager.CurrentObjective == this) - { - if (randomTimer > 0) - { - randomTimer -= deltaTime; - } - else - { - SetRandom(); - } - } - } - public override bool IsCompleted() => false; public override bool CanBeCompleted => true; diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs index e81e8b4c5..2d0f8298a 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs @@ -174,6 +174,10 @@ namespace Barotrauma { isCompleted = true; } + if (component.AIOperate(deltaTime, character, this)) + { + isCompleted = true; + } } else { diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs index b64af04a5..010c5f5ee 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRepairItem.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using Barotrauma.Extensions; using FarseerPhysics; +using Barotrauma.Items.Components; namespace Barotrauma { @@ -14,6 +15,7 @@ namespace Barotrauma public Item Item { get; private set; } private AIObjectiveGoTo goToObjective; + private AIObjectiveContainItem refuelObjective; private float previousCondition = -1; private RepairTool repairTool; @@ -71,11 +73,46 @@ namespace Barotrauma } } // Only continue when the get item sub objectives have been completed. - if (subObjectives.Any(so => so is AIObjectiveGetItem)) { return; } + if (subObjectives.Any()) { return; } if (repairTool == null) { FindRepairTool(); } + if (repairTool != null) + { + var containedItems = repairTool.Item.ContainedItems; + if (containedItems == null) + { +#if DEBUG + DebugConsole.ThrowError("AIObjectiveRepairItem failed - the item \"" + repairTool + "\" has no proper inventory"); +#endif + abandon = true; + return; + } + // Drop empty tanks + foreach (Item containedItem in containedItems) + { + if (containedItem == null) { continue; } + if (containedItem.Condition <= 0.0f) + { + containedItem.Drop(character); + } + } + RelatedItem item = null; + Item fuel = null; + foreach (RelatedItem requiredItem in repairTool.requiredItems[RelatedItem.RelationType.Contained]) + { + item = requiredItem; + fuel = containedItems.FirstOrDefault(it => it.Condition > 0.0f && requiredItem.MatchesItem(it)); + if (fuel != null) { break; } + } + if (fuel == null) + { + RemoveSubObjective(ref goToObjective); + TryAddSubObjective(ref refuelObjective, () => new AIObjectiveContainItem(character, item.Identifiers, repairTool.Item.GetComponent(), objectiveManager)); + return; + } + } if (character.CurrentHull == Item.CurrentHull && character.CanInteractWith(Item)) { if (repairTool != null) @@ -112,6 +149,7 @@ namespace Barotrauma } else { + RemoveSubObjective(ref refuelObjective); // If cannot reach the item, approach it. TryAddSubObjective(ref goToObjective, constructor: () => diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs index a014a6137..8e822ac4f 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/PathFinder.cs @@ -203,7 +203,9 @@ namespace Barotrauma if (startNode == null) { +#if DEBUG DebugConsole.NewMessage("Pathfinding error, couldn't find a start node. "+ errorMsgStr, Color.DarkRed); +#endif return new SteeringPath(true); } @@ -253,7 +255,9 @@ namespace Barotrauma if (endNode == null) { +#if DEBUG DebugConsole.NewMessage("Pathfinding error, couldn't find an end node. " + errorMsgStr, Color.DarkRed); +#endif return new SteeringPath(true); } @@ -281,7 +285,9 @@ namespace Barotrauma if (startNode == null || endNode == null) { +#if DEBUG DebugConsole.NewMessage("Pathfinding error, couldn't find matching pathnodes to waypoints.", Color.DarkRed); +#endif return new SteeringPath(true); } diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs index f89fdd9eb..151100514 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Deconstructor.cs @@ -924,6 +924,25 @@ namespace Barotrauma.Items.Components } } + if (targetItem.Prefab.DeconstructItems.Any()) + { + inputContainer.Inventory.RemoveItem(targetItem); + Entity.Spawner.AddToRemoveQueue(targetItem); + MoveInputQueue(); + PutItemsToLinkedContainer(); + } + else + { + if (outputContainer.Inventory.Items.All(i => i != null)) + { + targetItem.Drop(dropper: null); + } + else + { + outputContainer.Inventory.TryPutItem(targetItem, user: null, createNetworkEvent: true); + } + } + if (targetItem.Prefab.DeconstructItems.Any()) { inputContainer.Inventory.RemoveItem(targetItem); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs index 2aafee648..a251165ce 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Machines/Steering.cs @@ -212,6 +212,33 @@ namespace Barotrauma.Items.Components } } + public Vector2? PosToMaintain + { + get { return posToMaintain; } + set { posToMaintain = value; } + } + + struct ObstacleDebugInfo + { + public Vector2 Point1; + public Vector2 Point2; + + public Vector2? Intersection; + + public float Dot; + + public Vector2 AvoidStrength; + + public ObstacleDebugInfo(GraphEdge edge, Vector2? intersection, float dot, Vector2 avoidStrength) + { + Point1 = edge.Point1; + Point2 = edge.Point2; + Intersection = intersection; + Dot = dot; + AvoidStrength = avoidStrength; + } + } + //edge point 1, edge point 2, avoid strength private List debugDrawObstacles = new List(); diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs index 9015e1159..09d4e740a 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/LightComponent.cs @@ -152,8 +152,7 @@ namespace Barotrauma.Items.Components ParentSub = item.CurrentHull?.Submarine, Position = item.Position, CastShadows = castShadows, - IsBackground = drawBehindSubs, - SpriteScale = Vector2.One * item.Scale + IsBackground = drawBehindSubs }; #endif diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs index bc184c1c3..033af2726 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs @@ -1820,6 +1820,10 @@ namespace Barotrauma { ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); } + if (!broken) + { + ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); + } ApplyStatusEffects(!waterProof && inWater ? ActionType.InWater : ActionType.NotInWater, deltaTime); if (body == null || !body.Enabled || !inWater || ParentInventory != null || Removed) { return; } diff --git a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs index c533a8f74..ae59b864c 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Hull.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Hull.cs @@ -455,6 +455,25 @@ namespace Barotrauma } } + public string DisplayName + { + get; + private set; + } + + private string roomName; + [Editable, Serialize("", true, translationTextTag: "RoomName.")] + public string RoomName + { + get { return roomName; } + set + { + if (roomName == value) { return; } + roomName = value; + DisplayName = TextManager.Get(roomName, returnNull: true) ?? roomName; + } + } + public override Rectangle Rect { get diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObject.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObject.cs index 723dcdd31..3874415b6 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObject.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObject.cs @@ -20,8 +20,6 @@ namespace Barotrauma public float Rotation; - private int spriteIndex; - public LevelObjectPrefab ActivePrefab; public PhysicsBody PhysicsBody @@ -42,15 +40,6 @@ namespace Barotrauma set { Triggers.ForEach(t => t.NeedsNetworkSyncing = false); } } - public Sprite Sprite - { - get { return spriteIndex < 0 || Prefab.Sprites.Count == 0 ? null : Prefab.Sprites[spriteIndex % Prefab.Sprites.Count]; } - } - public Sprite SpecularSprite - { - get { return spriteIndex < 0 || Prefab.SpecularSprites.Count == 0 ? null : Prefab.SpecularSprites[spriteIndex % Prefab.SpecularSprites.Count]; } - } - public LevelObject(LevelObjectPrefab prefab, Vector3 position, float scale, float rotation = 0.0f) { Triggers = new List(); @@ -60,8 +49,6 @@ namespace Barotrauma Scale = scale; Rotation = rotation; - spriteIndex = ActivePrefab.Sprites.Any() ? Rand.Int(ActivePrefab.Sprites.Count, Rand.RandSync.Server) : -1; - if (prefab.PhysicsBodyElement != null) { PhysicsBody = new PhysicsBody(prefab.PhysicsBodyElement, ConvertUnits.ToSimUnits(new Vector2(position.X, position.Y)), Scale); diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectManager.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectManager.cs index 19f6b09e5..b75965a40 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectManager.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectManager.cs @@ -166,7 +166,7 @@ namespace Barotrauma Vector2.Zero, Vector2.Zero, Vector2.Zero, Vector2.Zero }; - Sprite sprite = newObject.Sprite ?? newObject.Prefab.DeformableSprite?.Sprite; + Sprite sprite = newObject.Prefab.Sprite ?? newObject.Prefab.DeformableSprite?.Sprite; //calculate the positions of the corners of the rotated sprite if (sprite != null) diff --git a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectPrefab.cs b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectPrefab.cs index 04eda0a0a..34d0f2991 100644 --- a/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectPrefab.cs +++ b/Barotrauma/BarotraumaShared/Source/Map/Levels/LevelObjects/LevelObjectPrefab.cs @@ -43,18 +43,18 @@ namespace Barotrauma SeaFloor = 4, MainPath = 8 } - - public List Sprites + + public Sprite Sprite { get; private set; - } = new List(); + } - public List SpecularSprites + public Sprite SpecularSprite { get; private set; - } = new List(); + } public DeformableSprite DeformableSprite { @@ -319,7 +319,7 @@ namespace Barotrauma //use the maximum width of the sprite as the minimum surface width if no value is given if (element != null && !element.Attributes("minsurfacewidth").Any()) { - if (Sprites.Any()) MinSurfaceWidth = Sprites[0].size.X * MaxSize; + if (Sprite != null) MinSurfaceWidth = Sprite.size.X * MaxSize; if (DeformableSprite != null) MinSurfaceWidth = Math.Max(MinSurfaceWidth, DeformableSprite.Size.X * MaxSize); } } @@ -331,10 +331,10 @@ namespace Barotrauma switch (subElement.Name.ToString().ToLowerInvariant()) { case "sprite": - Sprites.Add( new Sprite(subElement, lazyLoad: true)); + Sprite = new Sprite(subElement, lazyLoad: true); break; case "specularsprite": - SpecularSprites.Add(new Sprite(subElement, lazyLoad: true)); + SpecularSprite = new Sprite(subElement, lazyLoad: true); break; case "deformablesprite": DeformableSprite = new DeformableSprite(subElement, lazyLoad: true); @@ -358,9 +358,9 @@ namespace Barotrauma case "overrideproperties": var propertyOverride = new LevelObjectPrefab(subElement); OverrideProperties[OverrideProperties.Count - 1] = propertyOverride; - if (!propertyOverride.Sprites.Any() && propertyOverride.DeformableSprite == null) + if (propertyOverride.Sprite == null && propertyOverride.DeformableSprite == null) { - propertyOverride.Sprites = Sprites; + propertyOverride.Sprite = Sprite; propertyOverride.DeformableSprite = DeformableSprite; } break; diff --git a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub index f3c656388..1faf47a55 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub and b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Humpback.sub b/Barotrauma/BarotraumaShared/Submarines/Humpback.sub index 77b32bf89..751bb85a9 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Humpback.sub and b/Barotrauma/BarotraumaShared/Submarines/Humpback.sub differ diff --git a/Barotrauma/BarotraumaShared/Submarines/Remora.sub b/Barotrauma/BarotraumaShared/Submarines/Remora.sub index 8dd2e2953..b11988da2 100644 Binary files a/Barotrauma/BarotraumaShared/Submarines/Remora.sub and b/Barotrauma/BarotraumaShared/Submarines/Remora.sub differ