diff --git a/Barotrauma/BarotraumaClient/LinuxClient.csproj b/Barotrauma/BarotraumaClient/LinuxClient.csproj
index 56b243537..c3c50da75 100644
--- a/Barotrauma/BarotraumaClient/LinuxClient.csproj
+++ b/Barotrauma/BarotraumaClient/LinuxClient.csproj
@@ -274,6 +274,63 @@
PreserveNewest
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
+
@@ -304,6 +361,6 @@
-
+
\ No newline at end of file
diff --git a/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs b/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs
index 598c5e10d..d93ecf6e3 100644
--- a/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs
+++ b/Barotrauma/BarotraumaClient/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.9.0.1")]
-[assembly: AssemblyFileVersion("0.9.0.1")]
+[assembly: AssemblyVersion("0.9.0.2")]
+[assembly: AssemblyFileVersion("0.9.0.2")]
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
index 4c029c726..633916804 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/Character.cs
@@ -504,7 +504,7 @@ namespace Barotrauma
foreach (Character c in CharacterList)
{
- if (!CanInteractWith(c)) continue;
+ if (!CanInteractWith(c, checkVisibility: false)) continue;
float dist = Vector2.DistanceSquared(mouseSimPos, c.SimPosition);
if (dist < maxDist * maxDist && (closestCharacter == null || dist < closestDist))
diff --git a/Barotrauma/BarotraumaClient/Source/Characters/Health/CharacterHealth.cs b/Barotrauma/BarotraumaClient/Source/Characters/Health/CharacterHealth.cs
index 86f4895d3..afa1d3daf 100644
--- a/Barotrauma/BarotraumaClient/Source/Characters/Health/CharacterHealth.cs
+++ b/Barotrauma/BarotraumaClient/Source/Characters/Health/CharacterHealth.cs
@@ -121,8 +121,8 @@ namespace Barotrauma
if (value == null &&
Character.Controlled?.SelectedCharacter?.CharacterHealth != null &&
- Character.Controlled.SelectedCharacter.CharacterHealth == prevOpenHealthWindow &&
- !Character.Controlled.SelectedCharacter.CanInventoryBeAccessed)
+ Character.Controlled.SelectedCharacter.CharacterHealth == prevOpenHealthWindow/* &&
+ !Character.Controlled.SelectedCharacter.CanInventoryBeAccessed*/)
{
Character.Controlled.DeselectCharacter();
}
@@ -188,14 +188,9 @@ namespace Barotrauma
afflictionInfoContainer = new GUIListBox(new RectTransform(new Vector2(0.7f, 0.85f), paddedInfoFrame.RectTransform, Anchor.BottomLeft));
- lowSkillIndicator = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), paddedInfoFrame.RectTransform, Anchor.TopRight),
- TextManager.Get("LowMedicalSkillWarning"), Color.Orange, textAlignment: Alignment.TopRight, font: GUI.SmallFont, wrap: true)
- {
- Visible = false
- };
- new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), paddedInfoFrame.RectTransform) { RelativeOffset = new Vector2(0.0f, 0.05f) }, TextManager.Get("SuitableTreatments"), textAlignment: Alignment.BottomRight);
+ new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.05f), paddedInfoFrame.RectTransform, Anchor.TopRight), TextManager.Get("SuitableTreatments"), textAlignment: Alignment.TopRight);
- recommendedTreatmentContainer = new GUIListBox(new RectTransform(new Vector2(0.28f, 0.5f), paddedInfoFrame.RectTransform, Anchor.TopRight) { RelativeOffset = new Vector2(0.0f, 0.12f) });
+ recommendedTreatmentContainer = new GUIListBox(new RectTransform(new Vector2(0.28f, 0.47f), paddedInfoFrame.RectTransform, Anchor.TopRight) { RelativeOffset = new Vector2(0.0f, 0.15f) });
dropItemArea = new GUIFrame(new RectTransform(new Vector2(0.28f, 0.3f), paddedInfoFrame.RectTransform, Anchor.BottomRight)
{ RelativeOffset = new Vector2(0.02f, 0.0f) }, style: null)
{
@@ -203,6 +198,17 @@ namespace Barotrauma
};
dropItemArea.RectTransform.NonScaledSize = new Point(dropItemArea.Rect.Width);
+ lowSkillIndicator = new GUIImage(new RectTransform(new Vector2(0.5f, 0.22f), paddedInfoFrame.RectTransform, Anchor.TopRight, Pivot.Center) { RelativeOffset = new Vector2(0.16f, 0.12f) },
+ style: "GUINotificationButton")
+ {
+ ToolTip = TextManager.Get("lowmedicalskillwarning"),
+ Color = Color.OrangeRed,
+ HoverColor = Color.Orange,
+ PressedColor = Color.Orange,
+ Visible = false
+ };
+ lowSkillIndicator.RectTransform.MaxSize = new Point(lowSkillIndicator.Rect.Height);
+
string[] healthCircleStyles = new string[] { "HealthCircleInner", "HealthCircleMid", "HealthCircleOuter" };
foreach (string healthCircleStyle in healthCircleStyles)
{
@@ -657,7 +663,8 @@ namespace Barotrauma
openHealthWindow = null;
}
- lowSkillIndicator.Visible = Timing.TotalTime % 1.0f < 0.8f && Character.Controlled != null && Character.Controlled.GetSkillLevel("medical") < 50.0f;
+ lowSkillIndicator.Visible = Character.Controlled != null && Character.Controlled.GetSkillLevel("medical") < 50.0f;
+ lowSkillIndicator.Color = new Color(lowSkillIndicator.Color, MathHelper.Lerp(0.1f, 1.0f, (float)(Math.Sin(Timing.TotalTime * 5.0f) + 1.0f) / 2.0f));
float rotationSpeed = 0.25f;
int i = 0;
@@ -1053,10 +1060,10 @@ namespace Barotrauma
var itemSlot = new GUIFrame(new RectTransform(new Point(recommendedTreatmentContainer.Content.Rect.Width, slotSize), recommendedTreatmentContainer.Content.RectTransform, Anchor.TopCenter),
style: "InnerGlow")
{
- UserData = item,
- CanBeFocused = false
+ UserData = item
};
itemSlot.Color = ToolBox.GradientLerp(treatment.Value, Color.Red, Color.Orange, Color.LightGreen);
+ itemSlot.SelectedColor = itemSlot.HoverColor = itemSlot.Color;
Sprite itemSprite = item.InventoryIcon ?? item.sprite;
Color itemColor = itemSprite == item.sprite ? item.SpriteColor : item.InventoryIconColor;
@@ -1068,7 +1075,7 @@ namespace Barotrauma
HoverColor = itemColor,
SelectedColor = itemColor
};
- itemSlot.ToolTip = item.Name + "\n" + item.Description;
+ itemSlot.ToolTip = item.Name;
}
afflictionInfoContainer.Content.RectTransform.SortChildren((r1, r2) =>
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
index 18093e0ed..be2740daa 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/GUI.cs
@@ -1439,23 +1439,22 @@ namespace Barotrauma
{
PauseMenu = new GUIFrame(new RectTransform(Vector2.One, Canvas), style: null, color: Color.Black * 0.5f);
- var pauseMenuInner = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.3f), PauseMenu.RectTransform, Anchor.Center) { MinSize = new Point(200, 300) });
+ var pauseMenuInner = new GUIFrame(new RectTransform(new Vector2(0.13f, 0.35f), PauseMenu.RectTransform, Anchor.Center) { MinSize = new Point(200, 300) });
- var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.85f, 0.85f), pauseMenuInner.RectTransform, Anchor.Center))
+ var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.85f, 0.8f), pauseMenuInner.RectTransform, Anchor.Center) { RelativeOffset = new Vector2(0.0f, 0.05f) })
{
Stretch = true,
RelativeSpacing = 0.05f
};
- var button = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform), TextManager.Get("bugreportbutton"), style: "GUIButtonLarge")
+ var button = new GUIButton(new RectTransform(new Vector2(0.12f, 0.12f), buttonContainer.RectTransform, Anchor.TopRight) { RelativeOffset = new Vector2(-0.05f, -0.13f) },
+ "", style: "GUIBugButton")
{
- Color = Color.Red,
- HoverColor = Color.DarkRed,
- PressedColor = Color.White,
+ IgnoreLayoutGroups = true,
+ ToolTip = TextManager.Get("bugreportbutton"),
OnClicked = (btn, userdata) => { GameMain.Instance.ShowBugReporter(); return true; }
};
-
button = new GUIButton(new RectTransform(new Vector2(1.0f, 0.1f), buttonContainer.RectTransform), TextManager.Get("PauseMenuResume"), style: "GUIButtonLarge")
{
OnClicked = TogglePauseMenu
diff --git a/Barotrauma/BarotraumaClient/Source/GUI/LoadingScreen.cs b/Barotrauma/BarotraumaClient/Source/GUI/LoadingScreen.cs
index 4c352fbac..ef928a8ac 100644
--- a/Barotrauma/BarotraumaClient/Source/GUI/LoadingScreen.cs
+++ b/Barotrauma/BarotraumaClient/Source/GUI/LoadingScreen.cs
@@ -16,7 +16,7 @@ namespace Barotrauma
private RenderTarget2D renderTarget;
private Sprite languageSelectionCursor;
- private ScalableFont languageSelectionFont;
+ private ScalableFont languageSelectionFont, languageSelectionFontCJK;
private Video currSplashScreen;
private DateTime videoStartTime;
@@ -220,7 +220,13 @@ 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/NotoSans/NotoSans-Bold.ttf",
+ (uint)(30 * (GameMain.GraphicsHeight / 1080.0f)), graphicsDevice);
+ }
+ if (languageSelectionFontCJK == null)
+ {
+ languageSelectionFontCJK = new ScalableFont("Content/Fonts/NotoSans/NotoSansCJKsc-Bold.otf",
+ (uint)(30 * (GameMain.GraphicsHeight / 1080.0f)), graphicsDevice, dynamicLoading: true);
}
if (languageSelectionCursor == null)
{
@@ -231,13 +237,15 @@ namespace Barotrauma
Vector2 textSpacing = new Vector2(0.0f, (GameMain.GraphicsHeight * 0.5f) / TextManager.AvailableLanguages.Count());
foreach (string language in TextManager.AvailableLanguages)
{
- Vector2 textSize = languageSelectionFont.MeasureString(language);
+ string localizedLanguageName = TextManager.GetTranslatedLanguageName(language);
+ var font = TextManager.IsCJK(localizedLanguageName) ? languageSelectionFontCJK : languageSelectionFont;
+
+ Vector2 textSize = font.MeasureString(localizedLanguageName);
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,
+ font.DrawString(spriteBatch, localizedLanguageName, textPos - textSize / 2,
hover ? Color.White : Color.White * 0.6f);
if (hover && PlayerInput.LeftButtonClicked())
{
@@ -247,12 +255,15 @@ namespace Barotrauma
GameMain.Config.SetDefaultBindings(legacy: false);
GameMain.Config.CheckBindings(useDefaults: true);
WaitForLanguageSelection = false;
+ languageSelectionFont?.Dispose(); languageSelectionFont = null;
+ languageSelectionFontCJK?.Dispose(); languageSelectionFontCJK = null;
+ break;
}
textPos += textSpacing;
}
- languageSelectionCursor.Draw(spriteBatch, PlayerInput.LatestMousePosition);
+ languageSelectionCursor.Draw(spriteBatch, PlayerInput.LatestMousePosition, scale: 0.5f);
}
private void DrawSplashScreen(SpriteBatch spriteBatch, GraphicsDevice graphics)
diff --git a/Barotrauma/BarotraumaClient/Source/GameMain.cs b/Barotrauma/BarotraumaClient/Source/GameMain.cs
index 35a63376e..a7e1de746 100644
--- a/Barotrauma/BarotraumaClient/Source/GameMain.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameMain.cs
@@ -287,13 +287,7 @@ namespace Barotrauma
{
if (GameSettings.ShowUserStatisticsPrompt)
{
- //TODO: translate
- var userStatsPrompt = new GUIMessageBox(
- "Do you want to help us make Barotrauma better?",
- "Do you allow Barotrauma to send usage statistics and error reports to the developers? The data is anonymous, " +
- "does not contain any personal information and is only used to help us diagnose issues and improve Barotrauma.",
- new string[] { "Yes", "No" });
- userStatsPrompt.Buttons[0].OnClicked += (btn, userdata) =>
+ if (TextManager.ContainsTag("statisticspromptheader") && TextManager.ContainsTag("statisticsprompttext"))
{
var userStatsPrompt = new GUIMessageBox(
TextManager.Get("statisticspromptheader"),
@@ -324,17 +318,7 @@ namespace Barotrauma
GameSettings.SendUserStatistics = true;
GameAnalyticsManager.Init();
Config.SaveNewPlayerConfig();
- return true;
- };
- userStatsPrompt.Buttons[0].OnClicked += userStatsPrompt.Close;
- userStatsPrompt.Buttons[1].OnClicked += (btn, userdata) =>
- {
- GameSettings.ShowUserStatisticsPrompt = false;
- GameSettings.SendUserStatistics = false;
- Config.SaveNewPlayerConfig();
- return true;
- };
- userStatsPrompt.Buttons[1].OnClicked += userStatsPrompt.Close;
+ }
}
else if (GameSettings.SendUserStatistics)
{
@@ -399,10 +383,10 @@ namespace Barotrauma
DebugConsole.Log("Selected content packages: " + string.Join(", ", SelectedPackages.Select(cp => cp.Name)));
}
-#if DEBUG
+/*#if DEBUG
GameSettings.ShowUserStatisticsPrompt = false;
GameSettings.SendUserStatistics = false;
-#endif
+#endif*/
InitUserStats();
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/CaptainTutorial.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/CaptainTutorial.cs
index 18512989d..0e329d0f2 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/CaptainTutorial.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/CaptainTutorial.cs
@@ -132,7 +132,7 @@ namespace Barotrauma.Tutorials
{
shakeTimer -= 0.1f;
GameMain.GameScreen.Cam.Shake = shakeAmount;
- yield return new WaitForSeconds(0.1f);
+ yield return new WaitForSeconds(0.1f, false);
}
// Room 2
@@ -142,7 +142,7 @@ namespace Barotrauma.Tutorials
// Room 3
do { yield return null; } while (!captain_medicObjectiveSensor.MotionDetected);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(captain_medic.Info.DisplayName, TextManager.Get("Captain.Radio.Medic"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(2f);
+ yield return new WaitForSeconds(2f, false);
GameMain.GameSession.CrewManager.ToggleCrewAreaOpen = true;
GameMain.GameSession.CrewManager.AddCharacter(captain_medic);
TriggerTutorialSegment(0);
@@ -157,7 +157,7 @@ namespace Barotrauma.Tutorials
// Submarine
do { yield return null; } while (!captain_enteredSubmarineSensor.MotionDetected);
- yield return new WaitForSeconds(3f);
+ yield return new WaitForSeconds(3f, false);
captain_mechanic.AIController.Enabled = captain_security.AIController.Enabled = captain_engineer.AIController.Enabled = true;
TriggerTutorialSegment(1);
GameMain.GameSession.CrewManager.AddCharacter(captain_mechanic);
@@ -169,7 +169,7 @@ namespace Barotrauma.Tutorials
}
while (!HasOrder(captain_mechanic, "repairsystems", "jobspecific"));
RemoveCompletedObjective(segments[1]);
- yield return new WaitForSeconds(2f);
+ yield return new WaitForSeconds(2f, false);
TriggerTutorialSegment(2);
GameMain.GameSession.CrewManager.AddCharacter(captain_security);
do
@@ -180,7 +180,7 @@ namespace Barotrauma.Tutorials
}
while (!HasOrder(captain_security, "operateweapons", "fireatwill"));
RemoveCompletedObjective(segments[2]);
- yield return new WaitForSeconds(4f);
+ yield return new WaitForSeconds(4f, false);
TriggerTutorialSegment(3);
GameMain.GameSession.CrewManager.AddCharacter(captain_engineer);
do
@@ -202,10 +202,10 @@ namespace Barotrauma.Tutorials
do
{
//captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f);
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
} while (Submarine.MainSub.DockedTo.Count > 0);
RemoveCompletedObjective(segments[4]);
- yield return new WaitForSeconds(2f);
+ yield return new WaitForSeconds(2f, false);
TriggerTutorialSegment(5); // Navigate to destination
do
{
@@ -221,15 +221,15 @@ namespace Barotrauma.Tutorials
} while (!captain_sonar.IsActive);
do { yield return null; } while (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 4000f);
RemoveCompletedObjective(segments[5]);
- yield return new WaitForSeconds(4f);
+ yield return new WaitForSeconds(4f, false);
TriggerTutorialSegment(6); // Docking
do
{
//captain_navConsoleCustomInterface.HighlightElement(0, uiHighlightColor, duration: 1.0f, pulsateAmount: 0.0f);
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
} while (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0);
RemoveCompletedObjective(segments[6]);
- yield return new WaitForSeconds(3f);
+ yield return new WaitForSeconds(3f, false);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Captain.Radio.Complete").Replace("[OUTPOSTNAME]", GameMain.GameSession.EndLocation.Name), ChatMessageType.Radio, null);
SetHighlight(captain_navConsole.Item, false);
SetHighlight(captain_sonar.Item, false);
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/DoctorTutorial.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/DoctorTutorial.cs
index f5259472d..ef9a5000c 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/DoctorTutorial.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/DoctorTutorial.cs
@@ -21,7 +21,7 @@ namespace Barotrauma.Tutorials
private ItemContainer doctor_suppliesCabinet;
private ItemContainer doctor_medBayCabinet;
private Character patient1, patient2;
- private List subPatients = new List();
+ private List subPatients;
private Hull startRoom;
private Hull medBay;
@@ -38,7 +38,8 @@ namespace Barotrauma.Tutorials
private LightComponent tutorial_submarineDoorLight;
// Variables
- private Color doctor_iconColor = new Color(178, 118, 139);
+ private Sprite doctor_firstAidIcon;
+ private Color doctor_firstAidIconColor;
public DoctorTutorial(XElement element) : base(element)
{
@@ -47,6 +48,11 @@ namespace Barotrauma.Tutorials
{
base.Start();
+ var firstAidOrder = Order.PrefabList.Find(order => order.AITag == "requestfirstaid");
+ doctor_firstAidIcon = firstAidOrder.SymbolSprite;
+ doctor_firstAidIconColor = firstAidOrder.Color;
+
+ subPatients = new List();
radioSpeakerName = TextManager.Get("Tutorial.Radio.Speaker");
doctor = Character.Controlled;
@@ -119,7 +125,7 @@ namespace Barotrauma.Tutorials
// explosions and radio messages ------------------------------------------------------
- yield return new WaitForSeconds(3.0f);
+ yield return new WaitForSeconds(3.0f, false);
//SoundPlayer.PlayDamageSound("StructureBlunt", 10, Character.Controlled.WorldPosition);
//// Room 1
@@ -141,7 +147,7 @@ namespace Barotrauma.Tutorials
explosion.Explode(Character.Controlled.WorldPosition - Vector2.UnitX * 25, null);
SoundPlayer.PlayDamageSound("StructureBlunt", 10, Character.Controlled.WorldPosition - Vector2.UnitX * 25);
- yield return new WaitForSeconds(0.5f);
+ yield return new WaitForSeconds(0.5f, false);
doctor.DamageLimb(
Character.Controlled.WorldPosition,
@@ -154,15 +160,15 @@ namespace Barotrauma.Tutorials
{
shakeTimer -= 0.1f;
GameMain.GameScreen.Cam.Shake = shakeAmount;
- yield return new WaitForSeconds(0.1f);
+ yield return new WaitForSeconds(0.1f, false);
}
- yield return new WaitForSeconds(3.0f);
+ yield return new WaitForSeconds(3.0f, false);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Doctor.Radio.KnockedDown"), ChatMessageType.Radio, null);
// first tutorial segment, get medical supplies ------------------------------------------------------
- yield return new WaitForSeconds(1.5f);
+ yield return new WaitForSeconds(1.5f, false);
SetHighlight(doctor_suppliesCabinet.Item, true);
/*while (doctor.CurrentHull != doctor_suppliesCabinet.Item.CurrentHull)
@@ -190,22 +196,24 @@ namespace Barotrauma.Tutorials
}
yield return null;
} while (doctor.Inventory.FindItemByIdentifier("antidama1") == null); // Wait until looted
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
SetHighlight(doctor_suppliesCabinet.Item, false);
RemoveCompletedObjective(segments[0]);
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
// 2nd tutorial segment, treat self -------------------------------------------------------------------------
TriggerTutorialSegment(1, GameMain.Config.KeyBind(InputType.Health)); // Open health interface
while (CharacterHealth.OpenHealthWindow == null)
{
- yield return new WaitForSeconds(1.0f);
+ doctor.CharacterHealth.HealthBarPulsateTimer = 1.0f;
+ yield return null;
}
+ yield return null;
RemoveCompletedObjective(segments[1]);
-
+ yield return new WaitForSeconds(1.0f, false);
TriggerTutorialSegment(2); //Treat self
while (doctor.CharacterHealth.GetAfflictionStrength("damage") > 0.01f)
{
@@ -226,23 +234,22 @@ namespace Barotrauma.Tutorials
while (CharacterHealth.OpenHealthWindow != null)
{
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
}
// treat patient --------------------------------------------------------------------------------------------
//patient 1 requests first aid
- patient1.CanSpeak = true;
var newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), patient1.CurrentHull, null, orderGiver: patient1);
- GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
- patient1.Speak(newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order);
- patient1.AIController.Enabled = true;
+ doctor.AddActiveObjectiveEntity(patient1, doctor_firstAidIcon, doctor_firstAidIconColor);
+ //GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
+ GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(patient1.Name, newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order, null);
while (doctor.CurrentHull != patient1.CurrentHull)
{
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
}
- yield return new WaitForSeconds(0.0f);
+ yield return new WaitForSeconds(0.0f, false);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Doctor.Radio.AssistantBurns"), ChatMessageType.Radio, null);
GameMain.GameSession.CrewManager.AllowCharacterSwitch = false;
@@ -250,7 +257,9 @@ namespace Barotrauma.Tutorials
GameMain.GameSession.CrewManager.AddCharacter(patient1);
GameMain.GameSession.CrewManager.ToggleCrewAreaOpen = true;
- yield return new WaitForSeconds(3.0f);
+ yield return new WaitForSeconds(3.0f, false);
+ patient1.AIController.Enabled = true;
+ doctor.RemoveActiveObjectiveEntity(patient1);
TriggerTutorialSegment(3); // Get the patient to medbay
while (patient1.CurrentOrder == null || patient1.CurrentOrder.AITag != "follow")
@@ -263,13 +272,13 @@ namespace Barotrauma.Tutorials
while (patient1.CurrentHull != medBay)
{
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
}
RemoveCompletedObjective(segments[3]);
SetHighlight(doctor_medBayCabinet.Item, true);
SetDoorAccess(doctor_thirdDoor, doctor_thirdDoorLight, true);
- yield return new WaitForSeconds(2.0f);
+ yield return new WaitForSeconds(2.0f, false);
TriggerTutorialSegment(4, GameMain.Config.KeyBind(InputType.Health)); // treat burns
@@ -309,17 +318,19 @@ namespace Barotrauma.Tutorials
}
RemoveCompletedObjective(segments[4]);
SetHighlight(patient1, false);
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Doctor.Radio.AssistantBurnsHealed"), ChatMessageType.Radio, null);
// treat unconscious patient ------------------------------------------------------
//patient calls for help
- patient2.CanSpeak = true;
+ //patient2.CanSpeak = true;
+ yield return new WaitForSeconds(2.0f, false);
newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), patient2.CurrentHull, null, orderGiver: patient2);
- GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
- patient2.Speak(newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order);
+ doctor.AddActiveObjectiveEntity(patient2, doctor_firstAidIcon, doctor_firstAidIconColor);
+ //GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
+ GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(patient2.Name, newOrder.GetChatMessage("", patient1.CurrentHull?.DisplayName, givingOrderToSelf: false), ChatMessageType.Order, null);
patient2.AIController.Enabled = true;
patient2.Oxygen = -50;
CoroutineManager.StartCoroutine(KeepPatientAlive(patient2), "KeepPatient2Alive");
@@ -329,7 +340,7 @@ namespace Barotrauma.Tutorials
yield return new WaitForSeconds(1.0f);
}*/
do { yield return null; } while (!tutorial_upperFinalDoor.IsOpen);
- yield return new WaitForSeconds(2.0f);
+ yield return new WaitForSeconds(2.0f, false);
TriggerTutorialSegment(5, GameMain.Config.KeyBind(InputType.Health)); // perform CPR
SetHighlight(patient2, true);
@@ -344,23 +355,24 @@ namespace Barotrauma.Tutorials
}
RemoveCompletedObjective(segments[5]);
SetHighlight(patient2, false);
+ doctor.RemoveActiveObjectiveEntity(patient2);
CoroutineManager.StopCoroutines("KeepPatient2Alive");
SetDoorAccess(tutorial_submarineDoor, tutorial_submarineDoorLight, true);
while (doctor.Submarine != Submarine.MainSub)
{
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
}
- yield return new WaitForSeconds(5.0f);
+ yield return new WaitForSeconds(5.0f, false);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Doctor.Radio.EnteredSub"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(3.0f);
+ yield return new WaitForSeconds(3.0f, false);
TriggerTutorialSegment(6, GameMain.Config.KeyBind(InputType.Health)); // give treatment to anyone in need
foreach (var patient in subPatients)
{
- patient.CanSpeak = true;
+ //patient.CanSpeak = true;
patient.AIController.Enabled = true;
SetHighlight(patient, true);
}
@@ -369,7 +381,8 @@ namespace Barotrauma.Tutorials
double subEnterTime = Timing.TotalTime;
- bool[] patientCalledHelp = new bool[] { false, false, false, false, false, false };
+ bool[] patientCalledHelp = new bool[] { false, false, false };
+
while (subPatients.Any(p => p.Vitality < p.MaxVitality * 0.9f && !p.IsDead))
{
for (int i = 0; i < subPatients.Count; i++)
@@ -378,32 +391,26 @@ namespace Barotrauma.Tutorials
//(within 1 minute intervals of entering the sub)
if (!patientCalledHelp[i] && Timing.TotalTime > subEnterTime + 60 * (i + 1))
{
+ doctor.AddActiveObjectiveEntity(subPatients[i], doctor_firstAidIcon, doctor_firstAidIconColor);
newOrder = new Order(Order.PrefabList.Find(o => o.AITag == "requestfirstaid"), subPatients[i].CurrentHull, null, orderGiver: subPatients[i]);
- GameMain.GameSession.CrewManager.AddOrder(newOrder, newOrder.FadeOutTime);
-
string message = newOrder.GetChatMessage("", subPatients[i].CurrentHull?.DisplayName, givingOrderToSelf: false);
- if (subPatients[i].CanSpeak)
- {
- subPatients[i].Speak(message, ChatMessageType.Order);
- }
- else
- {
- GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, message, ChatMessageType.Radio, null);
- }
+ GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(subPatients[i].Name, message, ChatMessageType.Order, null);
patientCalledHelp[i] = true;
}
if (subPatients[i].ExternalHighlight && subPatients[i].Vitality >= subPatients[i].MaxVitality * 0.9f)
{
+ doctor.RemoveActiveObjectiveEntity(subPatients[i]);
SetHighlight(subPatients[i], false);
}
}
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
}
RemoveCompletedObjective(segments[6]);
foreach (var patient in subPatients)
{
SetHighlight(patient, false);
+ doctor.RemoveActiveObjectiveEntity(patient);
}
// END TUTORIAL
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/EngineerTutorial.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/EngineerTutorial.cs
index f230542a1..12f6bcf47 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/EngineerTutorial.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/EngineerTutorial.cs
@@ -213,7 +213,7 @@ namespace Barotrauma.Tutorials
{
shakeTimer -= 0.1f;
GameMain.GameScreen.Cam.Shake = shakeAmount;
- yield return new WaitForSeconds(0.1f);
+ yield return new WaitForSeconds(0.1f, false);
}
//// Remove
@@ -231,7 +231,7 @@ namespace Barotrauma.Tutorials
// Room 2
do { yield return null; } while (!engineer_equipmentObjectiveSensor.MotionDetected);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Equipment"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(0.5f);
+ yield return new WaitForSeconds(0.5f, false);
TriggerTutorialSegment(0, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Deselect)); // Retrieve equipment
bool firstSlotRemoved = false;
bool secondSlotRemoved = false;
@@ -280,7 +280,7 @@ namespace Barotrauma.Tutorials
// Room 3
do { yield return null; } while (!IsSelectedItem(engineer_reactor.Item));
- yield return new WaitForSeconds(0.5f);
+ yield return new WaitForSeconds(0.5f, false);
TriggerTutorialSegment(1);
do
{
@@ -326,7 +326,7 @@ namespace Barotrauma.Tutorials
}
yield return null;
} while (!reactorOperatedProperly);
- yield return new WaitForSeconds(2f);
+ yield return new WaitForSeconds(2f, false);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.ReactorStable"), ChatMessageType.Radio, null);
do
{
@@ -343,7 +343,7 @@ namespace Barotrauma.Tutorials
float wait = 1.5f;
do
{
- yield return new WaitForSeconds(0.1f);
+ yield return new WaitForSeconds(0.1f, false);
wait -= 0.1f;
engineer_reactor.AutoTempSlider.BarScrollValue = 0.0f;
} while (wait > 0.0f);
@@ -356,9 +356,24 @@ namespace Barotrauma.Tutorials
// Room 4
do { yield return null; } while (!engineer_secondDoor.IsOpen);
- yield return new WaitForSeconds(1f);
+ yield return new WaitForSeconds(1f, false);
+ Repairable repairableJunctionBoxComponent = engineer_brokenJunctionBox.GetComponent();
TriggerTutorialSegment(2, GameMain.Config.KeyBind(InputType.Select)); // Repair the junction box
- do { yield return null; } while (!engineer_brokenJunctionBox.IsFullCondition); // Wait until repaired
+ do
+ {
+ if (!engineer.HasEquippedItem("screwdriver"))
+ {
+ HighlightInventorySlot(engineer.Inventory, "screwdriver", highlightColor, .5f, .5f, 0f);
+ }
+ else if (IsSelectedItem(engineer_brokenJunctionBox) && repairableJunctionBoxComponent.CurrentFixer == null)
+ {
+ if (repairableJunctionBoxComponent.RepairButton.Frame.FlashTimer <= 0)
+ {
+ repairableJunctionBoxComponent.RepairButton.Frame.Flash();
+ }
+ }
+ yield return null;
+ } while (!engineer_brokenJunctionBox.IsFullCondition); // Wait until repaired
SetHighlight(engineer_brokenJunctionBox, false);
RemoveCompletedObjective(segments[2]);
SetDoorAccess(engineer_thirdDoor, engineer_thirdDoorLight, true);
@@ -370,7 +385,7 @@ namespace Barotrauma.Tutorials
// Room 5
do { yield return null; } while (!engineer_thirdDoor.IsOpen);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.FaultyWiring"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(2f);
+ yield return new WaitForSeconds(2f, false);
TriggerTutorialSegment(3, GameMain.Config.KeyBind(InputType.Use), GameMain.Config.KeyBind(InputType.Deselect)); // Connect the junction boxes
do { CheckGhostWires(); HandleJunctionBoxWiringHighlights(); yield return null; } while (engineer_workingPump.Voltage < engineer_workingPump.MinVoltage); // Wait until connected all the way to the pump
CheckGhostWires();
@@ -387,7 +402,7 @@ namespace Barotrauma.Tutorials
// Submarine
do { yield return null; } while (!tutorial_enteredSubmarineSensor.MotionDetected);
GameMain.GameSession.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Engineer.Radio.Submarine"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(2f);
+ yield return new WaitForSeconds(2f, false);
TriggerTutorialSegment(4); // Repair junction box
while (ContentRunning) yield return null;
SetHighlight(engineer_submarineJunctionBox_1, true);
@@ -443,7 +458,7 @@ namespace Barotrauma.Tutorials
tutorial_oxygenGenerator.PowerConsumption = reactorLoads[i];
while (timer > 0)
{
- yield return new WaitForSeconds(0.1f);
+ yield return new WaitForSeconds(0.1f, false);
if (IsReactorPoweredUp(engineer_reactor))
{
timer -= 0.1f;
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/MechanicTutorial.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/MechanicTutorial.cs
index 8032483c3..4d516fb8e 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/MechanicTutorial.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/MechanicTutorial.cs
@@ -230,25 +230,25 @@ namespace Barotrauma.Tutorials
{
shakeTimer -= 0.1f;
GameMain.GameScreen.Cam.Shake = shakeAmount;
- yield return new WaitForSeconds(0.1f);
+ yield return new WaitForSeconds(0.1f, false);
}
- yield return new WaitForSeconds(2.5f);
+ yield return new WaitForSeconds(2.5f, false);
mechanic_fabricator.RemoveFabricationRecipes(new List() { "extinguisher", "wrench", "weldingtool", "weldingfuel", "divingmask", "railgunshell", "nuclearshell", "uex", "harpoongun" });
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.WakeUp"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(2.5f);
+ yield return new WaitForSeconds(2.5f, false);
TriggerTutorialSegment(0, GameMain.Config.KeyBind(InputType.Up), GameMain.Config.KeyBind(InputType.Left), GameMain.Config.KeyBind(InputType.Down), GameMain.Config.KeyBind(InputType.Right), GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Select)); // Open door objective
- yield return new WaitForSeconds(0.0f);
+ yield return new WaitForSeconds(0.0f, false);
SetDoorAccess(mechanic_firstDoor, mechanic_firstDoorLight, true);
SetHighlight(mechanic_firstDoor.Item, true);
do { yield return null; } while (!mechanic_firstDoor.IsOpen);
SetHighlight(mechanic_firstDoor.Item, false);
- yield return new WaitForSeconds(1.5f);
+ yield return new WaitForSeconds(1.5f, false);
RemoveCompletedObjective(segments[0]);
// Room 2
- yield return new WaitForSeconds(0.0f);
+ yield return new WaitForSeconds(0.0f, false);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Equipment"), ChatMessageType.Radio, null);
do { yield return null; } while (!mechanic_equipmentObjectiveSensor.MotionDetected);
TriggerTutorialSegment(1, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Deselect)); // Equipment & inventory objective
@@ -287,7 +287,7 @@ namespace Barotrauma.Tutorials
yield return null;
} while (mechanic.Inventory.FindItemByIdentifier("divingmask") == null || mechanic.Inventory.FindItemByIdentifier("weldingtool") == null || mechanic.Inventory.FindItemByIdentifier("wrench") == null); // Wait until looted
SetHighlight(mechanic_equipmentCabinet.Item, false);
- yield return new WaitForSeconds(1.5f);
+ yield return new WaitForSeconds(1.5f, false);
RemoveCompletedObjective(segments[1]);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Breach"), ChatMessageType.Radio, null);
@@ -312,13 +312,13 @@ namespace Barotrauma.Tutorials
do { yield return null; } while (WallHasDamagedSections(mechanic_brokenWall_1)); // Highlight until repaired
mechanic.RemoveActiveObjectiveEntity(mechanic_brokenWall_1);
RemoveCompletedObjective(segments[2]);
- yield return new WaitForSeconds(1f);
+ yield return new WaitForSeconds(1f, false);
TriggerTutorialSegment(3, GameMain.Config.KeyBind(InputType.Select)); // Pump objective
SetHighlight(mechanic_workingPump.Item, true);
do
{
yield return null;
- if (IsSelectedItem(mechanic_brokenPump.Item))
+ if (IsSelectedItem(mechanic_workingPump.Item))
{
if (mechanic_workingPump.IsActiveSlider.FlashTimer <= 0)
{
@@ -330,17 +330,17 @@ namespace Barotrauma.Tutorials
do { yield return null; } while (mechanic_brokenhull_1.WaterPercentage > waterVolumeBeforeOpening); // Unlock door once drained
RemoveCompletedObjective(segments[3]);
SetDoorAccess(mechanic_thirdDoor, mechanic_thirdDoorLight, true);
- yield return new WaitForSeconds(1.5f);
+ yield return new WaitForSeconds(1.5f, false);
//TriggerTutorialSegment(11, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Up), GameMain.Config.KeyBind(InputType.Down), GameMain.Config.KeyBind(InputType.Select)); // Ladder objective
//do { yield return null; } while (!mechanic_ladderSensor.MotionDetected);
//RemoveCompletedObjective(segments[11]);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.News"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(1f);
+ yield return new WaitForSeconds(1f, false);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Mechanic.Radio.Fire"), ChatMessageType.Radio, null);
// Room 4
do { yield return null; } while (!mechanic_thirdDoor.IsOpen);
- yield return new WaitForSeconds(1f);
+ yield return new WaitForSeconds(1f, false);
mechanic_fire = new DummyFireSource(new Vector2(20f, 2f), Item.ItemList.Find(i => i.HasTag("mechanic_fire")).WorldPosition);
//do { yield return null; } while (!mechanic_craftingObjectiveSensor.MotionDetected);
TriggerTutorialSegment(4); // Deconstruct
@@ -364,7 +364,7 @@ namespace Barotrauma.Tutorials
}
yield return null;
} while (mechanic.Inventory.FindItemByIdentifier("oxygentank") == null || mechanic.Inventory.FindItemByIdentifier("sodium") == null); // Wait until looted
- yield return new WaitForSeconds(1.0f);
+ yield return new WaitForSeconds(1.0f, false);
SetHighlight(mechanic_craftingCabinet.Item, false);
SetHighlight(mechanic_deconstructor.Item, true);
@@ -409,7 +409,7 @@ namespace Barotrauma.Tutorials
SetHighlight(mechanic_deconstructor.Item, false);
RemoveCompletedObjective(segments[4]);
- yield return new WaitForSeconds(1f);
+ yield return new WaitForSeconds(1f, false);
TriggerTutorialSegment(5); // Fabricate
SetHighlight(mechanic_fabricator.Item, true);
do
@@ -465,7 +465,7 @@ namespace Barotrauma.Tutorials
do { yield return null; } while (!mechanic_fireSensor.MotionDetected);
TriggerTutorialSegment(6, GameMain.Config.KeyBind(InputType.Aim), GameMain.Config.KeyBind(InputType.Shoot)); // Using the extinguisher
do { yield return null; } while (!mechanic_fire.Removed); // Wait until extinguished
- yield return new WaitForSeconds(3f);
+ yield return new WaitForSeconds(3f, false);
RemoveCompletedObjective(segments[6]);
if (mechanic.HasEquippedItem("extinguisher")) // do not trigger if dropped already
@@ -527,6 +527,16 @@ namespace Barotrauma.Tutorials
}
}
}
+ else
+ {
+ if (IsSelectedItem(mechanic_brokenPump.Item))
+ {
+ if (mechanic_brokenPump.IsActiveSlider.FlashTimer <= 0)
+ {
+ mechanic_brokenPump.IsActiveSlider.Flash(uiHighlightColor, 1.5f, true);
+ }
+ }
+ }
} while (!mechanic_brokenPump.Item.IsFullCondition || mechanic_brokenPump.FlowPercentage >= 0 || !mechanic_brokenPump.IsActive);
RemoveCompletedObjective(segments[9]);
SetHighlight(mechanic_brokenPump.Item, false);
diff --git a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/OfficerTutorial.cs b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/OfficerTutorial.cs
index 3feff2ddd..3b8b62909 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/OfficerTutorial.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSession/GameModes/Tutorials/OfficerTutorial.cs
@@ -197,7 +197,7 @@ namespace Barotrauma.Tutorials
{
shakeTimer -= 0.1f;
GameMain.GameScreen.Cam.Shake = shakeAmount;
- yield return new WaitForSeconds(0.1f);
+ yield return new WaitForSeconds(0.1f, false);
}
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.WakeUp"), ChatMessageType.Radio, null);
@@ -205,7 +205,7 @@ namespace Barotrauma.Tutorials
// Room 2
do { yield return null; } while (!officer_equipmentObjectiveSensor.MotionDetected);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Equipment"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(3f);
+ yield return new WaitForSeconds(3f, false);
//TriggerTutorialSegment(0, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Deselect)); // Retrieve equipment
SetHighlight(officer_equipmentCabinet.Item, true);
bool firstSlotRemoved = false;
@@ -259,7 +259,7 @@ namespace Barotrauma.Tutorials
{
HighlightInventorySlot(officer.Inventory, "ballistichelmet", highlightColor, .5f, .5f, 0f);
}
- yield return new WaitForSeconds(1f);
+ yield return new WaitForSeconds(1f, false);
} while (!officer.HasEquippedItem("stunbaton") || !officer.HasEquippedItem("bodyarmor") || !officer.HasEquippedItem("ballistichelmet"));
RemoveCompletedObjective(segments[1]);
SetDoorAccess(officer_firstDoor, officer_firstDoorLight, true);
@@ -271,7 +271,7 @@ namespace Barotrauma.Tutorials
do { yield return null; } while (!officer_crawler.IsDead);
RemoveCompletedObjective(segments[2]);
Heal(officer);
- yield return new WaitForSeconds(1f);
+ yield return new WaitForSeconds(1f, false);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.CrawlerDead"), ChatMessageType.Radio, null);
SetDoorAccess(officer_secondDoor, officer_secondDoorLight, true);
@@ -296,7 +296,7 @@ namespace Barotrauma.Tutorials
SetHighlight(officer_ammoShelf_1.Item, false);
SetHighlight(officer_ammoShelf_2.Item, false);
RemoveCompletedObjective(segments[3]);
- yield return new WaitForSeconds(2f);
+ yield return new WaitForSeconds(2f, false);
TriggerTutorialSegment(4, GameMain.Config.KeyBind(InputType.Select), GameMain.Config.KeyBind(InputType.Shoot), GameMain.Config.KeyBind(InputType.Deselect)); // Kill hammerhead
officer_hammerhead = SpawnMonster(hammerheadCharacterFile, officer_hammerheadSpawnPos);
officer_hammerhead.AIController.SelectTarget(officer.AiTarget);
@@ -316,14 +316,14 @@ namespace Barotrauma.Tutorials
Heal(officer);
SetHighlight(officer_coilgunPeriscope, false);
RemoveCompletedObjective(segments[4]);
- yield return new WaitForSeconds(1f);
+ yield return new WaitForSeconds(1f, false);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.HammerheadDead"), ChatMessageType.Radio, null);
SetDoorAccess(officer_thirdDoor, officer_thirdDoorLight, true);
// Room 5
//do { yield return null; } while (!officer_rangedWeaponSensor.MotionDetected);
do { yield return null; } while (!officer_thirdDoor.IsOpen);
- yield return new WaitForSeconds(3f);
+ yield return new WaitForSeconds(3f, false);
TriggerTutorialSegment(5, GameMain.Config.KeyBind(InputType.Aim), GameMain.Config.KeyBind(InputType.Shoot)); // Ranged weapons
SetHighlight(officer_rangedWeaponHolder.Item, true);
do { yield return null; } while (!officer_rangedWeaponHolder.Inventory.IsEmpty()); // Wait until looted
@@ -387,8 +387,9 @@ namespace Barotrauma.Tutorials
officer.AddActiveObjectiveEntity(officer_subAmmoBox_1, officer_gunIcon, officer_gunIconColor);
officer.AddActiveObjectiveEntity(officer_subAmmoBox_2, officer_gunIcon, officer_gunIconColor);
officer.AddActiveObjectiveEntity(officer_subSuperCapacitor_1.Item, officer_gunIcon, officer_gunIconColor);
- officer.AddActiveObjectiveEntity(officer_subSuperCapacitor_1.Item, officer_gunIcon, officer_gunIconColor);
officer.AddActiveObjectiveEntity(officer_subSuperCapacitor_2.Item, officer_gunIcon, officer_gunIconColor);
+ SetHighlight(officer_subSuperCapacitor_1.Item, true);
+ SetHighlight(officer_subSuperCapacitor_2.Item, true);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Submarine"), ChatMessageType.Radio, null);
do
{
@@ -409,8 +410,8 @@ namespace Barotrauma.Tutorials
officer.RemoveActiveObjectiveEntity(officer_subSuperCapacitor_2.Item);
}
- SetHighlight(officer_subAmmoBox_1, officer_subLoader_1.Item.ExternalHighlight || officer_subLoader_2.Item.ExternalHighlight);
- SetHighlight(officer_subAmmoBox_2, officer_subLoader_1.Item.ExternalHighlight || officer_subLoader_2.Item.ExternalHighlight);
+ SetHighlight(officer_subAmmoBox_1, officer_subAmmoBox_1.ParentInventory != officer_subLoader_1.Inventory && officer_subAmmoBox_1.ParentInventory != officer_subLoader_2.Inventory);
+ SetHighlight(officer_subAmmoBox_2, officer_subAmmoBox_2.ParentInventory != officer_subLoader_1.Inventory && officer_subAmmoBox_2.ParentInventory != officer_subLoader_2.Inventory);
SetHighlight(officer_subAmmoShelf.Item, officer_subLoader_1.Item.ExternalHighlight || officer_subLoader_2.Item.ExternalHighlight);
if (officer_subAmmoBox_1.ParentInventory == officer_subLoader_1.Inventory || officer_subAmmoBox_1.ParentInventory == officer_subLoader_2.Inventory) officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_1);
if (officer_subAmmoBox_2.ParentInventory == officer_subLoader_1.Inventory || officer_subAmmoBox_2.ParentInventory == officer_subLoader_2.Inventory) officer.RemoveActiveObjectiveEntity(officer_subAmmoBox_2);
@@ -430,7 +431,7 @@ namespace Barotrauma.Tutorials
RemoveCompletedObjective(segments[7]);
GameMain.GameSession?.CrewManager.AddSinglePlayerChatMessage(radioSpeakerName, TextManager.Get("Officer.Radio.Complete"), ChatMessageType.Radio, null);
- yield return new WaitForSeconds(4f);
+ yield return new WaitForSeconds(4f, false);
CoroutineManager.StartCoroutine(TutorialCompleted());
}
diff --git a/Barotrauma/BarotraumaClient/Source/GameSettings.cs b/Barotrauma/BarotraumaClient/Source/GameSettings.cs
index 1dde7cb03..212acdc56 100644
--- a/Barotrauma/BarotraumaClient/Source/GameSettings.cs
+++ b/Barotrauma/BarotraumaClient/Source/GameSettings.cs
@@ -477,7 +477,7 @@ namespace Barotrauma
if (string.IsNullOrWhiteSpace(VoiceCaptureDevice)) VoiceCaptureDevice = deviceNames[0];
#if (!OSX)
- var deviceList = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform), VoiceCaptureDevice, deviceNames.Count);
+ var deviceList = new GUIDropDown(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform), TextManager.EnsureUTF8(VoiceCaptureDevice), deviceNames.Count);
foreach (string name in deviceNames)
{
deviceList.AddItem(TextManager.EnsureUTF8(name), name);
@@ -492,7 +492,7 @@ namespace Barotrauma
};
#else
var suavemente = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), audioSliders.RectTransform),
- TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), VoiceCaptureDevice))
+ TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), TextManager.EnsureUTF8(VoiceCaptureDevice)))
{
ToolTip = TextManager.Get("CurrentDeviceToolTip.OSX"),
TextAlignment = Alignment.CenterX
@@ -507,7 +507,7 @@ namespace Barotrauma
if (VoiceCaptureDevice == deviceNames[0]) return true;
VoipCapture.ChangeCaptureDevice(deviceNames[0]);
- suavemente.Text = TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), VoiceCaptureDevice);
+ suavemente.Text = TextManager.AddPunctuation(':', TextManager.Get("CurrentDevice"), TextManager.EnsureUTF8(VoiceCaptureDevice));
suavemente.Flash(Color.Blue);
return true;
diff --git a/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs b/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs
index 8bb06d630..27ae86b7a 100644
--- a/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs
+++ b/Barotrauma/BarotraumaClient/Source/Map/Map/Map.cs
@@ -624,10 +624,22 @@ namespace Barotrauma
if (mouseOn && PlayerInput.LeftButtonClicked() && !messageBoxOpen)
{
- //TODO: translate or replace
- var messageBox = new GUIMessageBox("Mysteries lie ahead...", "This area is unreachable in this version of Barotrauma. Please wait for future updates!");
- messageBoxOpen = true;
- CoroutineManager.StartCoroutine(WaitForMessageBoxClosed(messageBox));
+ if (TextManager.ContainsTag("centerarealockedheader") && TextManager.ContainsTag("centerarealockedtext") )
+ {
+ var messageBox = new GUIMessageBox(
+ TextManager.Get("centerarealockedheader"),
+ TextManager.Get("centerarealockedtext"));
+ messageBoxOpen = true;
+ CoroutineManager.StartCoroutine(WaitForMessageBoxClosed(messageBox));
+ }
+ else
+ {
+ //if the message cannot be shown in the selected language,
+ //show the campaign roadmap (which mentions the center location not being reachable)
+ var messageBox = new GUIMessageBox(TextManager.Get("CampaignRoadMapTitle"), TextManager.Get("CampaignRoadMapText"));
+ messageBoxOpen = true;
+ CoroutineManager.StartCoroutine(WaitForMessageBoxClosed(messageBox));
+ }
}
}
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs
index 7ef09692e..70b981ebe 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignSetupUI.cs
@@ -435,6 +435,8 @@ namespace Barotrauma
saveTime = time.ToString();
}
+ string mapseed = doc.Root.GetAttributeString("mapseed", "unknown");
+
var saveFileFrame = new GUIFrame(new RectTransform(new Vector2(0.45f, 0.6f), loadGameContainer.RectTransform, Anchor.TopRight)
{
RelativeOffset = new Vector2(0.0f, 0.1f)
diff --git a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs
index 304aba705..e622bc1ca 100644
--- a/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs
+++ b/Barotrauma/BarotraumaClient/Source/Screens/CampaignUI.cs
@@ -74,15 +74,14 @@ namespace Barotrauma
outpostBtn.TextBlock.Font = GUI.LargeFont;
outpostBtn.TextBlock.AutoScale = true;
- var tabButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.3f), topPanelContent.RectTransform, Anchor.BottomLeft), isHorizontal: true);
+ var tabButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 0.4f), topPanelContent.RectTransform, Anchor.BottomLeft), isHorizontal: true);
int i = 0;
var tabValues = Enum.GetValues(typeof(Tab));
foreach (Tab tab in tabValues)
{
var tabButton = new GUIButton(new RectTransform(new Vector2(0.25f, 1.0f), tabButtonContainer.RectTransform),
- TextManager.Get(tab.ToString()),
- textAlignment: Alignment.Center,
+ "",
style: i == 0 ? "GUISlopedTabButtonLeft" : (i == tabValues.Length - 1 ? "GUISlopedTabButtonRight" : "GUISlopedTabButtonMid"))
{
UserData = tab,
@@ -93,11 +92,32 @@ namespace Barotrauma
tabButton.RectTransform.MaxSize = new Point(
(int)(tabButton.Rect.Height * (buttonSprite.Sprite.size.X / buttonSprite.Sprite.size.Y)), int.MaxValue);
+ //the text needs to be positioned differently in the buttons at the edges due to the "slopes" in the button
+ if (i == 0 || i == tabValues.Length - 1)
+ {
+ new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.9f), tabButton.RectTransform, i == 0 ? Anchor.CenterLeft : Anchor.CenterRight) { RelativeOffset = new Vector2(0.05f, 0.0f) },
+ TextManager.Get(tab.ToString()), textColor: tabButton.TextColor, font: GUI.LargeFont, textAlignment: Alignment.Center, style: null)
+ {
+ UserData = "buttontext"
+ };
+ }
+ else
+ {
+ new GUITextBlock(new RectTransform(new Vector2(0.7f, 0.9f), tabButton.RectTransform, Anchor.Center),
+ TextManager.Get(tab.ToString()), textColor: tabButton.TextColor, font: GUI.LargeFont, textAlignment: Alignment.Center, style: null)
+ {
+ UserData = "buttontext"
+ };
+ }
+
tabButtons.Add(tabButton);
- tabButton.Font = GUI.LargeFont;
i++;
}
- GUITextBlock.AutoScaleAndNormalize(tabButtons.Select(t => t.TextBlock));
+ GUITextBlock.AutoScaleAndNormalize(tabButtons.Select(t => t.GetChildByUserData("buttontext") as GUITextBlock));
+ tabButtons.FirstOrDefault().RectTransform.SizeChanged += () =>
+ {
+ GUITextBlock.AutoScaleAndNormalize(tabButtons.Select(t => t.GetChildByUserData("buttontext") as GUITextBlock));
+ };
// crew tab -------------------------------------------------------------------------
diff --git a/Barotrauma/BarotraumaClient/Source/Utils/LocalizationCSVtoXML.cs b/Barotrauma/BarotraumaClient/Source/Utils/LocalizationCSVtoXML.cs
index b67a1d8cd..7e76d6ad2 100644
--- a/Barotrauma/BarotraumaClient/Source/Utils/LocalizationCSVtoXML.cs
+++ b/Barotrauma/BarotraumaClient/Source/Utils/LocalizationCSVtoXML.cs
@@ -133,24 +133,13 @@ namespace Barotrauma
}
}
- int conversationStart = -1;
- for (int i = 0; i < csvContent.Length; i++)
- {
- if (csvContent[i].StartsWith("Generic"))
- {
- conversationStart = i + 1;
- break;
- }
- }
-
- /*if (traitStart == -1)
+ if (traitStart == -1)
{
DebugConsole.ThrowError("Invalid formatting of NPCConversations, no traits found!");
return null;
- }*/
+ }
- //DebugConsole.NewMessage("Count: " + NPCPersonalityTrait.List.Count);
- /*for (int i = 0; i < conversationStart; i++) // Traits
+ for (int i = 0; i < NPCPersonalityTrait.List.Count; i++) // Traits
{
//string[] split = SplitCSV(csvContent[traitStart + i].Trim(separator));
string[] split = csvContent[traitStart + i].Split(separator);
@@ -159,9 +148,9 @@ namespace Barotrauma
$"{GetVariable("name", split[1])}" +
$"{GetVariable("alloweddialogtags", string.Join(",", NPCPersonalityTrait.List[i].AllowedDialogTags))}" +
$"{GetVariable("commonness", NPCPersonalityTrait.List[i].Commonness.ToString())}/>");
- }*/
+ }
- for (int i = conversationStart; i < csvContent.Length; i++) // Conversations
+ for (int i = traitStart + NPCPersonalityTrait.List.Count; i < csvContent.Length; i++) // Conversations
{
//string[] presplit = csvContent[i].Split(separator); // Handling speaker index fetching, somehow doesn't work with the regex
//string[] split = SplitCSV(csvContent[i]);
diff --git a/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs b/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs
index 0a45900e2..c949e94fc 100644
--- a/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs
+++ b/Barotrauma/BarotraumaClient/Source/Utils/ToolBox.cs
@@ -111,7 +111,7 @@ namespace Barotrauma
string currWord = "";
for (int i = 0; i < text.Length; i++)
{
- if (isCJK.IsMatch(text[i].ToString()))
+ if (TextManager.IsCJK(text[i].ToString()))
{
if (currWord.Length > 0)
{
@@ -200,24 +200,13 @@ namespace Barotrauma
linePos = size.X + spaceSize.X;
}
- if (i < words.Count - 1 && !isCJK.IsMatch(words[i]) && !isCJK.IsMatch(words[i + 1]))
+ if (i < words.Count - 1 && !TextManager.IsCJK(words[i]) && !TextManager.IsCJK(words[i + 1]))
{
wrappedText.Append(" ");
}
}
return wrappedText.ToString().Replace(" \n ", "\n");
- }
-
- static Regex isCJK = new Regex(
- @"\p{IsHangulJamo}|" +
- @"\p{IsCJKRadicalsSupplement}|" +
- @"\p{IsCJKSymbolsandPunctuation}|" +
- @"\p{IsEnclosedCJKLettersandMonths}|" +
- @"\p{IsCJKCompatibility}|" +
- @"\p{IsCJKUnifiedIdeographsExtensionA}|" +
- @"\p{IsCJKUnifiedIdeographs}|" +
- @"\p{IsHangulSyllables}|" +
- @"\p{IsCJKCompatibilityForms}");
+ }
}
}
diff --git a/Barotrauma/BarotraumaClient/libvlc.so b/Barotrauma/BarotraumaClient/libvlc.so
new file mode 120000
index 000000000..295941fb8
--- /dev/null
+++ b/Barotrauma/BarotraumaClient/libvlc.so
@@ -0,0 +1 @@
+libvlc.so.5.6.0
\ No newline at end of file
diff --git a/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs b/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs
index 62a738a43..160a3625a 100644
--- a/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs
+++ b/Barotrauma/BarotraumaServer/Properties/AssemblyInfo.cs
@@ -31,5 +31,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.9.0.1")]
-[assembly: AssemblyFileVersion("0.9.0.1")]
+[assembly: AssemblyVersion("0.9.0.2")]
+[assembly: AssemblyFileVersion("0.9.0.2")]
diff --git a/Barotrauma/BarotraumaServer/Source/Program.cs b/Barotrauma/BarotraumaServer/Source/Program.cs
index f7812cbbd..eba307e45 100644
--- a/Barotrauma/BarotraumaServer/Source/Program.cs
+++ b/Barotrauma/BarotraumaServer/Source/Program.cs
@@ -68,6 +68,7 @@ namespace Barotrauma
sb.AppendLine("Game version " + GameMain.Version + " (debug build)");
#else
sb.AppendLine("Game version " + GameMain.Version);
+#endif
sb.AppendLine("Selected content packages: " + (!GameMain.SelectedPackages.Any() ? "None" : string.Join(", ", GameMain.SelectedPackages.Select(c => c.Name))));
sb.AppendLine("Level seed: " + ((Level.Loaded == null) ? "no level loaded" : Level.Loaded.Seed));
sb.AppendLine("Loaded submarine: " + ((Submarine.MainSub == null) ? "None" : Submarine.MainSub.Name + " (" + Submarine.MainSub.MD5Hash + ")"));
diff --git a/Barotrauma/BarotraumaShared/SharedContent.projitems b/Barotrauma/BarotraumaShared/SharedContent.projitems
index 0ae98ed44..4e8cb7f62 100644
--- a/Barotrauma/BarotraumaShared/SharedContent.projitems
+++ b/Barotrauma/BarotraumaShared/SharedContent.projitems
@@ -454,9 +454,15 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs
index 81cb836b6..7c50aefc5 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/HumanAIController.cs
@@ -100,6 +100,25 @@ namespace Barotrauma
steeringManager = outsideSteering;
}
+ float maxDistanceToSub = 3000;
+ if (Character.Submarine != null || SelectedAiTarget?.Entity?.Submarine != null &&
+ Vector2.DistanceSquared(Character.WorldPosition, SelectedAiTarget.Entity.Submarine.WorldPosition) < maxDistanceToSub * maxDistanceToSub)
+ {
+ if (steeringManager != insideSteering)
+ {
+ insideSteering.Reset();
+ }
+ steeringManager = insideSteering;
+ }
+ else
+ {
+ if (steeringManager != outsideSteering)
+ {
+ outsideSteering.Reset();
+ }
+ steeringManager = outsideSteering;
+ }
+
AnimController.Crouching = shouldCrouch;
CheckCrouching(deltaTime);
Character.ClearInputs();
@@ -483,7 +502,11 @@ namespace Barotrauma
}
else if (ObjectiveManager.CurrentOrder is AIObjectiveRescueAll rescueAll && rescueAll.Targets.None())
{
- Character.Speak(TextManager.Get("DialogNoRescueTargets"), null, 3.0f, "norescuetargets");
+ //TODO: re-enable on all languages after DialogNoRescueTargets has been translated
+ if (TextManager.Language == "English")
+ {
+ Character.Speak(TextManager.Get("DialogNoRescueTargets"), null, 3.0f, "norescuetargets");
+ }
}
else if (ObjectiveManager.CurrentOrder is AIObjectivePumpWater pumpWater && pumpWater.Targets.None())
{
@@ -534,6 +557,8 @@ namespace Barotrauma
public static bool HasItem(Character character, string tag, string containedTag, float conditionPercentage = 0)
{
+ if (character == null) { return false; }
+ if (character.Inventory == null) { return false; }
var item = character.Inventory.FindItemByTag(tag);
return item != null &&
item.ConditionPercentage > conditionPercentage &&
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
index 40ebc5006..633163ab7 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/IndoorsSteeringManager.cs
@@ -164,7 +164,15 @@ namespace Barotrauma
}
var newPath = pathFinder.FindPath(pos, target, "(Character: " + character.Name + ")");
- if (currentPath == null || needsNewPath || !newPath.Unreachable && newPath.Cost < currentPath.Cost)
+ bool useNewPath = currentPath == null || needsNewPath;
+ if (!useNewPath && currentPath != null && currentPath.CurrentNode != null && newPath.Nodes.Any() && !newPath.Unreachable)
+ {
+ // It's possible that the current path was calculated from a start point that is no longer valid.
+ // Therefore, let's accept also paths with a greater cost than the current, if the current node is much farther than the new start node.
+ useNewPath = newPath.Cost < currentPath.Cost ||
+ Vector2.DistanceSquared(character.WorldPosition, currentPath.CurrentNode.WorldPosition) > Math.Pow(Vector2.Distance(character.WorldPosition, newPath.Nodes.First().WorldPosition) * 2, 2);
+ }
+ if (useNewPath)
{
currentPath = newPath;
}
@@ -406,7 +414,7 @@ namespace Barotrauma
{
if (door.HasIntegratedButtons)
{
- door.Item.TryInteract(character, false, true, true);
+ door.Item.TryInteract(character, false, true);
buttonPressCooldown = ButtonPressInterval;
break;
}
@@ -414,7 +422,7 @@ namespace Barotrauma
{
if (Vector2.DistanceSquared(closestButton.Item.WorldPosition, character.WorldPosition) < MathUtils.Pow(closestButton.Item.InteractDistance * 2, 2))
{
- closestButton.Item.TryInteract(character, false, true, false);
+ closestButton.Item.TryInteract(character, false, true);
buttonPressCooldown = ButtonPressInterval;
break;
}
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs
index 6fca16ea2..89e3d1e05 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveCombat.cs
@@ -128,7 +128,7 @@ namespace Barotrauma
if (seekAmmunition == null || !subObjectives.Contains(seekAmmunition))
{
Move();
- if (Weapon != null)
+ if (WeaponComponent != null)
{
OperateWeapon(deltaTime);
}
@@ -279,24 +279,6 @@ namespace Barotrauma
Weapon.Drop(character);
}
}
- //if (!character.SelectedItems.Contains(Weapon))
- if (!character.HasEquippedItem(Weapon))
- {
- Weapon.TryInteract(character, forceSelectKey: true);
- var slots = Weapon.AllowedSlots.FindAll(s => s == InvSlotType.LeftHand || s == InvSlotType.RightHand || s == (InvSlotType.LeftHand | InvSlotType.RightHand));
- if (character.Inventory.TryPutItem(Weapon, character, slots))
- {
- Weapon.Equip(character);
- aimTimer = Rand.Range(0.5f, 1f);
- }
- else
- {
- Weapon = null;
- Mode = CombatMode.Retreat;
- return false;
- }
- }
- return true;
}
private bool Equip()
@@ -338,7 +320,10 @@ namespace Barotrauma
{
retreatTarget = findSafety.FindBestHull(HumanAIController.VisibleHulls);
}
- TryAddSubObjective(ref retreatObjective, () => new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true));
+ if (character.CurrentHull != retreatTarget)
+ {
+ TryAddSubObjective(ref retreatObjective, () => new AIObjectiveGoTo(retreatTarget, character, objectiveManager, false, true));
+ }
}
private void Engage()
@@ -354,8 +339,7 @@ namespace Barotrauma
constructor: () => new AIObjectiveGoTo(Enemy, character, objectiveManager, repeat: true, getDivingGearIfNeeded: true)
{
AllowGoingOutside = true,
- IgnoreIfTargetDead = true,
- CheckVisibility = true
+ IgnoreIfTargetDead = true
},
onAbandon: () =>
{
@@ -365,7 +349,7 @@ namespace Barotrauma
if (followTargetObjective != null && subObjectives.Contains(followTargetObjective))
{
followTargetObjective.CloseEnough =
- WeaponComponent is RangedWeapon ? 3 :
+ WeaponComponent is RangedWeapon ? 300 :
WeaponComponent is MeleeWeapon mw ? mw.Range :
WeaponComponent is RepairTool rt ? rt.Range : 50;
}
@@ -455,7 +439,7 @@ namespace Barotrauma
float squaredDistance = Vector2.DistanceSquared(character.Position, Enemy.Position);
character.CursorPosition = Enemy.Position;
float engageDistance = 500;
- if (squaredDistance > engageDistance * engageDistance) { return; }
+ if (character.CurrentHull != Enemy.CurrentHull && squaredDistance > engageDistance * engageDistance) { return; }
if (!character.CanSeeCharacter(Enemy)) { return; }
if (Weapon.RequireAimToUse)
{
@@ -468,7 +452,7 @@ namespace Barotrauma
isOperatingButtons = door.HasIntegratedButtons || door.Item.GetConnectedComponents(true).Any();
}
}
- if (!isOperatingButtons && character.SelectedConstruction == null)
+ if (!isOperatingButtons)
{
character.SetInput(InputType.Aim, false, true);
}
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
index 1a5874252..980ca257d 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveGoTo.cs
@@ -1,7 +1,6 @@
-using FarseerPhysics;
-using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework;
using System;
-using System.Linq;
+using Barotrauma.Extensions;
namespace Barotrauma
{
@@ -17,17 +16,21 @@ namespace Barotrauma
public Func customCondition;
+ public bool followControlledCharacter;
+ public bool mimic;
+
///
/// Display units
///
public float CloseEnough { get; set; } = 50;
public bool IgnoreIfTargetDead { get; set; }
public bool AllowGoingOutside { get; set; }
- public bool CheckVisibility { get; set; }
+
+ public ISpatialEntity Target { get; private set; }
public override float GetPriority()
{
- if (FollowControlledCharacter && Character.Controlled == null) { return 0.0f; }
+ if (followControlledCharacter && Character.Controlled == null) { return 0.0f; }
if (Target is Entity e && e.Removed) { return 0.0f; }
if (IgnoreIfTargetDead && Target is Character character && character.IsDead) { return 0.0f; }
if (objectiveManager.CurrentOrder == this)
@@ -37,23 +40,19 @@ namespace Barotrauma
return 1.0f;
}
- public ISpatialEntity Target { get; private set; }
-
- public bool FollowControlledCharacter;
-
public AIObjectiveGoTo(ISpatialEntity target, Character character, AIObjectiveManager objectiveManager, bool repeat = false, bool getDivingGearIfNeeded = true, float priorityModifier = 1)
: base (character, objectiveManager, priorityModifier)
{
this.Target = target;
this.repeat = repeat;
- waitUntilPathUnreachable = 2.0f;
+ waitUntilPathUnreachable = 3.0f;
this.getDivingGearIfNeeded = getDivingGearIfNeeded;
CalculateCloseEnough();
}
protected override void Act(float deltaTime)
{
- if (FollowControlledCharacter)
+ if (followControlledCharacter)
{
if (Character.Controlled == null)
{
@@ -92,11 +91,18 @@ namespace Barotrauma
{
abandon = true;
}
- else if (!repeat && waitUntilPathUnreachable < 0)
+ else if (waitUntilPathUnreachable < 0)
{
- if (SteeringManager == PathSteering && PathSteering.CurrentPath != null)
+ if (SteeringManager == PathSteering && PathSteering.CurrentPath != null && PathSteering.CurrentPath.Unreachable)
{
- abandon = PathSteering.CurrentPath.Unreachable;
+ if (repeat)
+ {
+ SteeringManager.Reset();
+ }
+ else
+ {
+ abandon = true;
+ }
}
}
if (abandon)
@@ -115,9 +121,9 @@ namespace Barotrauma
Vector2 currTargetSimPos = Vector2.Zero;
currTargetSimPos = Target.SimPosition;
// Take the sub position into account in the sim pos
- if (character.Submarine == null && Target.Submarine != null)
+ if (SteeringManager != PathSteering && character.Submarine == null && Target.Submarine != null)
{
- //currTargetSimPos += Target.Submarine.SimPosition;
+ currTargetSimPos += Target.Submarine.SimPosition;
}
else if (character.Submarine != null && Target.Submarine == null)
{
@@ -132,10 +138,15 @@ namespace Barotrauma
}
}
character.AIController.SteeringManager.SteeringSeek(currTargetSimPos);
+ if (SteeringManager != PathSteering)
+ {
+ SteeringManager.SteeringAvoid(deltaTime, lookAheadDistance: 5, weight: 1, heading: VectorExtensions.Forward(character.AnimController.Collider.Rotation));
+ }
if (getDivingGearIfNeeded)
{
- bool needsDivingGear = HumanAIController.NeedsDivingGear(targetHull);
- bool needsDivingSuit = needsDivingGear && (targetHull == null || targetIsOutside || targetHull.WaterPercentage > 90);
+ Character followTarget = Target as Character;
+ bool needsDivingGear = HumanAIController.NeedsDivingGear(targetHull) || mimic && HumanAIController.HasDivingMask(followTarget);
+ bool needsDivingSuit = needsDivingGear && (targetHull == null || targetIsOutside || targetHull.WaterPercentage > 90) || mimic && HumanAIController.HasDivingSuit(followTarget);
bool needsEquipment = false;
if (needsDivingSuit)
{
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs
index 8aae67958..19a21b7ff 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveManager.cs
@@ -239,7 +239,8 @@ namespace Barotrauma
CloseEnough = 150,
AllowGoingOutside = true,
IgnoreIfTargetDead = true,
- FollowControlledCharacter = orderGiver == character
+ followControlledCharacter = orderGiver == character,
+ mimic = true
};
break;
case "wait":
@@ -258,7 +259,7 @@ namespace Barotrauma
newObjective = new AIObjectiveRescueAll(character, this, priorityModifier);
break;
case "repairsystems":
- newObjective = new AIObjectiveRepairItems(character, this, priorityModifier) { RequireAdequateSkills = option != "all" };
+ newObjective = new AIObjectiveRepairItems(character, this, priorityModifier) { RequireAdequateSkills = option == "jobspecific" };
break;
case "pumpwater":
newObjective = new AIObjectivePumpWater(character, this, option, priorityModifier: priorityModifier);
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
index 455392e05..d77c798c3 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveOperateItem.cs
@@ -68,6 +68,12 @@ namespace Barotrauma
{
if (character.CanInteractWith(target.Item, out _, checkLinked: false))
{
+ // Don't allow to operate an item that someone already operates, unless this objective is an order
+ if (objectiveManager.CurrentOrder != this && Character.CharacterList.Any(c => c.SelectedConstruction == target.Item && c != character && HumanAIController.IsFriendly(c)))
+ {
+ abandon = true;
+ return;
+ }
if (character.SelectedConstruction != target.Item)
{
target.Item.TryInteract(character, false, true);
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRescue.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRescue.cs
index 6c3d8212f..65c43a1d9 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRescue.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/Objectives/AIObjectiveRescue.cs
@@ -2,7 +2,6 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
namespace Barotrauma
@@ -17,13 +16,22 @@ namespace Barotrauma
private readonly Character targetCharacter;
private AIObjectiveGoTo goToObjective;
-
private float treatmentTimer;
+ private Hull safeHull;
public AIObjectiveRescue(Character character, Character targetCharacter, AIObjectiveManager objectiveManager, float priorityModifier = 1)
: base(character, objectiveManager, priorityModifier)
{
- if (targetCharacter != character)
+ if (targetCharacter == null)
+ {
+ string errorMsg = "Attempted to create a Rescue objective with no target!\n" + Environment.StackTrace;
+ DebugConsole.ThrowError(errorMsg);
+ GameAnalyticsManager.AddErrorEventOnce("AIObjectiveRescue:ctor:targetnull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
+ abandon = true;
+ return;
+ }
+
+ if (targetCharacter == character)
{
// TODO: enable healing self too
abandon = true;
@@ -40,6 +48,11 @@ namespace Barotrauma
protected override void Act(float deltaTime)
{
+ if (targetCharacter == null || targetCharacter.Removed)
+ {
+ return;
+ }
+
// Unconcious target is not in a safe place -> Move to a safe place first
if (targetCharacter.IsUnconscious && HumanAIController.GetHullSafety(targetCharacter.CurrentHull, targetCharacter) < HumanAIController.HULL_SAFETY_THRESHOLD)
{
@@ -71,15 +84,22 @@ namespace Barotrauma
{
goToObjective = null;
}
- var findSafety = objectiveManager.GetObjective();
- if (findSafety == null)
+ if (safeHull == null)
{
- // Ensure that we have the find safety objective (should always be the case)
- objectiveManager.AddObjective(new AIObjectiveFindSafety(character, objectiveManager));
+ var findSafety = objectiveManager.GetObjective();
+ if (findSafety == null)
+ {
+ // Ensure that we have the find safety objective (should always be the case)
+ findSafety = new AIObjectiveFindSafety(character, objectiveManager);
+ objectiveManager.AddObjective(findSafety);
+ }
+ safeHull = findSafety.FindBestHull(HumanAIController.VisibleHulls);
+ }
+ if (character.CurrentHull != safeHull)
+ {
+ TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(safeHull, character, objectiveManager));
}
- TryAddSubObjective(ref goToObjective, () => new AIObjectiveGoTo(findSafety.FindBestHull(HumanAIController.VisibleHulls), character, objectiveManager));
}
- return;
}
if (subObjectives.Any()) { return; }
@@ -207,13 +227,19 @@ namespace Barotrauma
public override bool IsCompleted()
{
+ if (targetCharacter == null || targetCharacter.Removed)
+ {
+ abandon = true;
+ return true;
+ }
+
bool isCompleted = targetCharacter.Bleeding <= 0 && targetCharacter.Vitality / targetCharacter.MaxVitality > AIObjectiveRescueAll.GetVitalityThreshold(objectiveManager);
if (isCompleted)
{
character.Speak(TextManager.Get("DialogTargetHealed").Replace("[targetname]", targetCharacter.Name),
null, 1.0f, "targethealed" + targetCharacter.Name, 60.0f);
}
- return isCompleted || targetCharacter.Removed || targetCharacter.IsDead;
+ return isCompleted || targetCharacter.IsDead;
}
public override float GetPriority()
diff --git a/Barotrauma/BarotraumaShared/Source/Characters/AI/SteeringManager.cs b/Barotrauma/BarotraumaShared/Source/Characters/AI/SteeringManager.cs
index 1ff6c66b7..3f47266e4 100644
--- a/Barotrauma/BarotraumaShared/Source/Characters/AI/SteeringManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/Characters/AI/SteeringManager.cs
@@ -45,9 +45,9 @@ namespace Barotrauma
steering += DoSteeringWander(weight);
}
- public void SteeringAvoid(float deltaTime, float lookAheadDistance, float weight = 1)
+ public void SteeringAvoid(float deltaTime, float lookAheadDistance, float weight = 1, Vector2? heading = null)
{
- steering += DoSteeringAvoid(deltaTime, lookAheadDistance, weight);
+ steering += DoSteeringAvoid(deltaTime, lookAheadDistance, weight, heading);
}
public void SteeringManual(float deltaTime, Vector2 velocity)
@@ -129,10 +129,12 @@ namespace Barotrauma
return newSteering;
}
- protected virtual Vector2 DoSteeringAvoid(float deltaTime, float lookAheadDistance, float weight)
+ protected virtual Vector2 DoSteeringAvoid(float deltaTime, float lookAheadDistance, float weight, Vector2? heading = null)
{
- if (steering == Vector2.Zero || host.Steering == Vector2.Zero) return Vector2.Zero;
-
+ if (steering == Vector2.Zero || host.Steering == Vector2.Zero)
+ {
+ return Vector2.Zero;
+ }
float maxDistance = lookAheadDistance;
if (rayCastTimer <= 0.0f)
{
@@ -158,19 +160,11 @@ namespace Barotrauma
{
obstaclePosition.X = closestStructure.SimPosition.X;
}
-
avoidObstaclePos = obstaclePosition;
- //avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - obstaclePosition);
}
- /*else if (closestBody.UserData is Item)
- {
- avoidSteering = Vector2.Normalize(Submarine.LastPickedPosition - item.SimPosition);
- }*/
else
{
-
avoidObstaclePos = Submarine.LastPickedPosition;
- //avoidSteering = Vector2.Normalize(host.SimPosition - Submarine.LastPickedPosition);
}
}
}
@@ -185,14 +179,26 @@ namespace Barotrauma
Vector2 diff = avoidObstaclePos.Value - host.SimPosition;
float dist = diff.Length();
- if (!avoidObstaclePos.HasValue) return Vector2.Zero;
-
- Vector2 diff = avoidObstaclePos.Value - host.SimPosition;
- float dist = diff.Length();
-
- if (dist > maxDistance) return Vector2.Zero;
-
- return -diff * (1.0f - dist / maxDistance) * weight;
+ if (dist > maxDistance)
+ {
+ return Vector2.Zero;
+ }
+ if (heading.HasValue)
+ {
+ var f = heading ?? host.Steering;
+ // Avoid to left or right depending on the current heading
+ Vector2 relativeVector = Vector2.Normalize(diff) - Vector2.Normalize(f);
+ var dir = relativeVector.X > 0 ? diff.Right() : diff.Left();
+ float factor = 1.0f - Math.Min(dist / maxDistance, 1);
+ return dir * factor * weight;
+ }
+ else
+ {
+ // Doesn't work right because it effectively just slows down or reverses the movement, where as we'd like to go right or left to avoid the target.
+ // There's also another issue, which also affects going right or left: the raycast doesn't hit anything if we turn too much -> avoiding doesn't work well.
+ // Could probably "remember" the avoidance a bit longer so that the avoid steering is not immedieately disgarded, but kept for a while and reduced gradually?
+ return -diff * (1.0f - dist / maxDistance) * weight;
+ }
}
}
}
diff --git a/Barotrauma/BarotraumaShared/Source/ContentPackage.cs b/Barotrauma/BarotraumaShared/Source/ContentPackage.cs
index b9071ec17..682e055ae 100644
--- a/Barotrauma/BarotraumaShared/Source/ContentPackage.cs
+++ b/Barotrauma/BarotraumaShared/Source/ContentPackage.cs
@@ -240,6 +240,11 @@ namespace Barotrauma
errorMessages = new List();
foreach (ContentFile file in Files)
{
+#if SERVER
+ //dedicated server doesn't care if the client executable is present or not
+ if (file.Type == ContentType.Executable) { continue; }
+#endif
+
if (!File.Exists(file.Path))
{
errorMessages.Add("File \"" + file.Path + "\" not found.");
diff --git a/Barotrauma/BarotraumaShared/Source/CoroutineManager.cs b/Barotrauma/BarotraumaShared/Source/CoroutineManager.cs
index 5e3d12d47..e31ffb9dc 100644
--- a/Barotrauma/BarotraumaShared/Source/CoroutineManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/CoroutineManager.cs
@@ -204,6 +204,7 @@ namespace Barotrauma
{
timer = time;
TotalTime = time;
+ this.ignorePause = ignorePause;
}
public bool CheckFinished(float deltaTime)
diff --git a/Barotrauma/BarotraumaShared/Source/Events/Missions/MissionPrefab.cs b/Barotrauma/BarotraumaShared/Source/Events/Missions/MissionPrefab.cs
index df7a431fa..49827886d 100644
--- a/Barotrauma/BarotraumaShared/Source/Events/Missions/MissionPrefab.cs
+++ b/Barotrauma/BarotraumaShared/Source/Events/Missions/MissionPrefab.cs
@@ -83,11 +83,15 @@ namespace Barotrauma
Commonness = element.GetAttributeInt("commonness", 1);
SuccessMessage = TextManager.Get("MissionSuccess." + Identifier, true) ?? element.GetAttributeString("successmessage", "Mission completed successfully");
- FailureMessage =
- TextManager.Get("MissionFailure." + Identifier, true) ??
- element.GetAttributeString("failuremessage", null) ??
- TextManager.Get("missionfailed", returnNull: true) ??
- "";
+ FailureMessage = TextManager.Get("MissionFailure." + Identifier, true) ?? "";
+ if (string.IsNullOrEmpty(FailureMessage) && TextManager.ContainsTag("missionfailed"))
+ {
+ FailureMessage = TextManager.Get("missionfailed", returnNull: true) ?? "";
+ }
+ if (string.IsNullOrEmpty(FailureMessage) && GameMain.Config.Language == "English")
+ {
+ FailureMessage = element.GetAttributeString("failuremessage", "");
+ }
SonarLabel = TextManager.Get("MissionSonarLabel." + Identifier, true) ?? element.GetAttributeString("sonarlabel", "");
diff --git a/Barotrauma/BarotraumaShared/Source/Extensions/VectorExtensions.cs b/Barotrauma/BarotraumaShared/Source/Extensions/VectorExtensions.cs
index 3ea2039a7..479b031d3 100644
--- a/Barotrauma/BarotraumaShared/Source/Extensions/VectorExtensions.cs
+++ b/Barotrauma/BarotraumaShared/Source/Extensions/VectorExtensions.cs
@@ -69,6 +69,7 @@ namespace Barotrauma.Extensions
///
public static Vector2 TransformVector(this Vector2 v, Vector2 up)
{
+ up = Vector2.Normalize(up);
return (up * v.Y) + (up.Right() * v.X);
}
diff --git a/Barotrauma/BarotraumaShared/Source/GameSettings.cs b/Barotrauma/BarotraumaShared/Source/GameSettings.cs
index a6c19d120..6d6c0100f 100644
--- a/Barotrauma/BarotraumaShared/Source/GameSettings.cs
+++ b/Barotrauma/BarotraumaShared/Source/GameSettings.cs
@@ -337,6 +337,79 @@ namespace Barotrauma
keyMapping[(int)InputType.SelectNextCharacter] = new KeyOrMouse(Keys.Z);
keyMapping[(int)InputType.SelectPreviousCharacter] = new KeyOrMouse(Keys.X);
}
+ }
+
+ public void CheckBindings(bool useDefaults)
+ {
+ foreach (InputType inputType in Enum.GetValues(typeof(InputType)))
+ {
+ var binding = keyMapping[(int)inputType];
+ if (binding == null)
+ {
+ switch (inputType)
+ {
+ case InputType.Deselect:
+ if (useDefaults)
+ {
+ binding = new KeyOrMouse(1);
+ }
+ else
+ {
+ // Legacy support
+ var selectKey = keyMapping[(int)InputType.Select];
+ if (selectKey != null && selectKey.Key != Keys.None)
+ {
+ binding = new KeyOrMouse(selectKey.Key);
+ }
+ }
+ break;
+ case InputType.Shoot:
+ if (useDefaults)
+ {
+ binding = new KeyOrMouse(0);
+ }
+ else
+ {
+ // Legacy support
+ var useKey = keyMapping[(int)InputType.Use];
+ if (useKey != null && useKey.MouseButton.HasValue)
+ {
+ binding = new KeyOrMouse(useKey.MouseButton.Value);
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ if (binding == null)
+ {
+ DebugConsole.ThrowError("Key binding for the input type \"" + inputType + " not set!");
+ binding = new KeyOrMouse(Keys.D1);
+ }
+ keyMapping[(int)inputType] = binding;
+ }
+ }
+ }
+
+ #region Load DefaultConfig
+ private void LoadDefaultConfig(bool setLanguage = true)
+ {
+ XDocument doc = XMLExtensions.TryLoadXml(savePath);
+
+ if (setLanguage || string.IsNullOrEmpty(Language))
+ {
+ Language = doc.Root.GetAttributeString("language", "English");
+ }
+
+ MasterServerUrl = doc.Root.GetAttributeString("masterserverurl", "");
+
+ AutoCheckUpdates = doc.Root.GetAttributeBool("autocheckupdates", true);
+ WasGameUpdated = doc.Root.GetAttributeBool("wasgameupdated", false);
+
+ VerboseLogging = doc.Root.GetAttributeBool("verboselogging", false);
+ SaveDebugConsoleLogs = doc.Root.GetAttributeBool("savedebugconsolelogs", false);
+
+ QuickStartSubmarineName = doc.Root.GetAttributeString("quickstartsub", "");
if (legacy)
{
@@ -605,6 +678,54 @@ namespace Barotrauma
}
#endregion
+ #region Save DefaultConfig
+ private void SaveNewDefaultConfig()
+ {
+ XDocument doc = new XDocument();
+
+ if (doc.Root == null)
+ {
+ doc.Add(new XElement("config"));
+ }
+
+ doc.Root.Add(
+ new XAttribute("language", TextManager.Language),
+ new XAttribute("masterserverurl", MasterServerUrl),
+ new XAttribute("autocheckupdates", AutoCheckUpdates),
+ new XAttribute("musicvolume", musicVolume),
+ new XAttribute("soundvolume", soundVolume),
+ new XAttribute("voicechatvolume", voiceChatVolume),
+ new XAttribute("verboselogging", VerboseLogging),
+ new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
+ new XAttribute("enablesplashscreen", EnableSplashScreen),
+ new XAttribute("usesteammatchmaking", useSteamMatchmaking),
+ new XAttribute("quickstartsub", QuickStartSubmarineName),
+ new XAttribute("requiresteamauthentication", requireSteamAuthentication),
+ new XAttribute("aimassistamount", aimAssistAmount));
+
+ if (!ShowUserStatisticsPrompt)
+ {
+ doc.Root.Add(new XAttribute("senduserstatistics", sendUserStatistics));
+ }
+
+ if (WasGameUpdated)
+ {
+ doc.Root.Add(new XAttribute("wasgameupdated", true));
+ }
+ if (!SelectedContentPackages.Any())
+ {
+ var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage);
+ if (availablePackage != null)
+ {
+ SelectedContentPackages.Add(availablePackage);
+ }
+ }
+
+ //save to get rid of the invalid selected packages in the config file
+ if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); }
+ }
+ #endregion
+
#region Save DefaultConfig
private void SaveNewDefaultConfig()
{
@@ -750,6 +871,7 @@ namespace Barotrauma
if (!fileFound)
{
ShowLanguageSelectionPrompt = true;
+ ShowUserStatisticsPrompt = true;
SaveNewPlayerConfig();
}
}
@@ -820,58 +942,6 @@ namespace Barotrauma
{
VoiceSetting = voiceSetting;
}
- foreach (ContentFile file in contentPackage.Files)
- {
- ToolBox.IsProperFilenameCase(file.Path);
- }
- }
- if (!SelectedContentPackages.Any())
- {
- var availablePackage = ContentPackage.List.FirstOrDefault(cp => cp.IsCompatible() && cp.CorePackage);
- if (availablePackage != null)
- {
- SelectedContentPackages.Add(availablePackage);
- }
- }
-
- //save to get rid of the invalid selected packages in the config file
- if (missingPackagePaths.Count > 0 || incompatiblePackages.Count > 0) { SaveNewPlayerConfig(); }
- }
- #endregion
-
- #region Save DefaultConfig
- private void SaveNewDefaultConfig()
- {
- XDocument doc = new XDocument();
-
- if (doc.Root == null)
- {
- doc.Add(new XElement("config"));
- }
-
- doc.Root.Add(
- new XAttribute("language", TextManager.Language),
- new XAttribute("masterserverurl", MasterServerUrl),
- new XAttribute("autocheckupdates", AutoCheckUpdates),
- new XAttribute("musicvolume", musicVolume),
- new XAttribute("soundvolume", soundVolume),
- new XAttribute("voicechatvolume", voiceChatVolume),
- new XAttribute("verboselogging", VerboseLogging),
- new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
- new XAttribute("enablesplashscreen", EnableSplashScreen),
- new XAttribute("usesteammatchmaking", useSteamMatchmaking),
- new XAttribute("quickstartsub", QuickStartSubmarineName),
- new XAttribute("requiresteamauthentication", requireSteamAuthentication),
- new XAttribute("aimassistamount", aimAssistAmount));
-
- if (!ShowUserStatisticsPrompt)
- {
- doc.Root.Add(new XAttribute("senduserstatistics", sendUserStatistics));
- }
-
- if (WasGameUpdated)
- {
- doc.Root.Add(new XAttribute("wasgameupdated", true));
}
useSteamMatchmaking = doc.Root.GetAttributeBool("usesteammatchmaking", useSteamMatchmaking);
@@ -940,7 +1010,22 @@ namespace Barotrauma
foreach (XElement subElement in doc.Root.Elements())
{
- switch (subElement.Name.ToString().ToLowerInvariant())
+ gSettings = new XElement("graphicssettings");
+ doc.Root.Add(gSettings);
+ }
+
+ gSettings.ReplaceAttributes(
+ new XAttribute("particlelimit", ParticleLimit),
+ new XAttribute("lightmapscale", LightMapScale),
+ new XAttribute("specularity", SpecularityEnabled),
+ new XAttribute("chromaticaberration", ChromaticAberrationEnabled),
+ new XAttribute("losmode", LosMode),
+ new XAttribute("hudscale", HUDScale),
+ new XAttribute("inventoryscale", InventoryScale));
+
+ foreach (ContentPackage contentPackage in SelectedContentPackages)
+ {
+ if (contentPackage.Path.Contains(vanillaContentPackagePath))
{
case "contentpackage":
string path = System.IO.Path.GetFullPath(subElement.GetAttributeString("path", ""));
@@ -1054,6 +1139,7 @@ namespace Barotrauma
new XAttribute("autocheckupdates", AutoCheckUpdates),
new XAttribute("musicvolume", musicVolume),
new XAttribute("soundvolume", soundVolume),
+ new XAttribute("voicechatvolume", voiceChatVolume),
new XAttribute("verboselogging", VerboseLogging),
new XAttribute("savedebugconsolelogs", SaveDebugConsoleLogs),
new XAttribute("enablesplashscreen", EnableSplashScreen),
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Connection.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Connection.cs
index cb84886c5..d12dfc5a9 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Connection.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Signal/Connection.cs
@@ -79,14 +79,10 @@ namespace Barotrauma.Items.Components
wires = new Wire[MaxLinked];
- if (string.IsNullOrEmpty(DisplayName))
- {
-#if DEBUG
- DebugConsole.ThrowError("Missing display name in connection " + item.Name + ": " + Name);
-#endif
- DisplayName = Name;
- }
+ IsOutput = element.Name.ToString() == "output";
+ Name = element.GetAttributeString("name", IsOutput ? "output" : "input");
+ string displayNameTag = "", fallbackTag = "";
//if displayname is not present, attempt to find it from the prefab
if (element.Attribute("displayname") == null)
{
@@ -98,26 +94,44 @@ namespace Barotrauma.Items.Components
{
if (connectionElement.Name.ToString() != element.Name.ToString()) { continue; }
- string prefabConnectionName = element.GetAttributeString("name", (IsOutput) ? "output" : "input");
+ string prefabConnectionName = element.GetAttributeString("name", IsOutput ? "output" : "input");
if (prefabConnectionName == Name)
{
- DisplayName = TextManager.GetServerMessage(connectionElement.GetAttributeString("displayname", Name));
+ displayNameTag = connectionElement.GetAttributeString("displayname", "");
+ fallbackTag = connectionElement.GetAttributeString("fallbackdisplayname", "");
}
- }
+ }
}
-#if DEBUG
- if (string.IsNullOrEmpty(DisplayName))
- {
- DebugConsole.ThrowError("Missing display name in connection " + item.Name + ": " + Name);
- }
-#endif
}
else
{
- DisplayName = TextManager.GetServerMessage(element.GetAttributeString("displayname", Name));
+ displayNameTag = element.GetAttributeString("displayname", "");
+ fallbackTag = element.GetAttributeString("fallbackdisplayname", null);
}
+ if (!string.IsNullOrEmpty(displayNameTag))
+ {
+ //extract the tag parts in case the tags contains variables
+ string tagWithoutVariables = displayNameTag?.Split('~')?.FirstOrDefault();
+ string fallbackTagWithoutVariables = fallbackTag?.Split('~')?.FirstOrDefault();
+ //use displayNameTag if found, otherwise fallBack
+ if (TextManager.ContainsTag(tagWithoutVariables))
+ {
+ DisplayName = TextManager.GetServerMessage(displayNameTag);
+ }
+ else if (TextManager.ContainsTag(fallbackTagWithoutVariables))
+ {
+ DisplayName = TextManager.GetServerMessage(fallbackTag);
+ }
+ }
+ if (string.IsNullOrEmpty(DisplayName))
+ {
+#if DEBUG
+ DebugConsole.ThrowError("Missing display name in connection " + item.Name + ": " + Name);
+#endif
+ DisplayName = Name;
+ }
IsPower = Name == "power_in" || Name == "power" || Name == "power_out";
diff --git a/Barotrauma/BarotraumaShared/Source/Items/Item.cs b/Barotrauma/BarotraumaShared/Source/Items/Item.cs
index f3e5de9d9..da2ae77e2 100644
--- a/Barotrauma/BarotraumaShared/Source/Items/Item.cs
+++ b/Barotrauma/BarotraumaShared/Source/Items/Item.cs
@@ -1641,7 +1641,7 @@ namespace Barotrauma
{
if (!ic.HasRequiredContainedItems(user == Character.Controlled)) continue;
- bool success = Rand.Range(0.0f, 1.0f) < ic.DegreeOfSuccess(user);
+ bool success = Rand.Range(0.0f, 0.5f) < ic.DegreeOfSuccess(user);
ActionType actionType = success ? ActionType.OnUse : ActionType.OnFailure;
#if CLIENT
diff --git a/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs b/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs
index 9dfe58a9e..cd5989c75 100644
--- a/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/SteamAchievementManager.cs
@@ -119,23 +119,40 @@ namespace Barotrauma
}
}
- if (GameMain.GameSession != null && Character.Controlled != null)
+ if (GameMain.GameSession != null)
{
- if (Character.Controlled.HasEquippedItem("clownmask") &&
- Character.Controlled.HasEquippedItem("clowncostume"))
+#if CLIENT
+ if (Character.Controlled != null) { CheckMidRoundAchievements(Character.Controlled); }
+#else
+ foreach (Client client in GameMain.Server.ConnectedClients)
{
- UnlockAchievement(Character.Controlled, "clowncostume");
- }
-
- if (Submarine.MainSub != null && Character.Controlled.Submarine == null)
- {
- float dist = 500 / Physics.DisplayToRealWorldRatio;
- if (Vector2.DistanceSquared(Character.Controlled.WorldPosition, Submarine.MainSub.WorldPosition) >
- dist * dist)
+ if (client.Character != null)
{
- UnlockAchievement(Character.Controlled, "crewaway");
+ CheckMidRoundAchievements(client.Character);
}
- }
+ }
+#endif
+ }
+ }
+
+ private static void CheckMidRoundAchievements(Character c)
+ {
+ if (c == null || c.Removed) { return; }
+
+ if (c.HasEquippedItem("clownmask") &&
+ c.HasEquippedItem("clowncostume"))
+ {
+ UnlockAchievement(c, "clowncostume");
+ }
+
+ if (Submarine.MainSub != null && c.Submarine == null)
+ {
+ float dist = 500 / Physics.DisplayToRealWorldRatio;
+ if (Vector2.DistanceSquared(c.WorldPosition, Submarine.MainSub.WorldPosition) >
+ dist * dist)
+ {
+ UnlockAchievement(c, "crewaway");
+ }
}
}
@@ -214,7 +231,8 @@ namespace Barotrauma
}
if (character.HasEquippedItem("clownmask") &&
- character.HasEquippedItem("clowncostume"))
+ character.HasEquippedItem("clowncostume") &&
+ causeOfDeath.Killer != character)
{
UnlockAchievement(causeOfDeath.Killer, "killclown");
}
diff --git a/Barotrauma/BarotraumaShared/Source/TextManager.cs b/Barotrauma/BarotraumaShared/Source/TextManager.cs
index 82250d9e5..60ff00a43 100644
--- a/Barotrauma/BarotraumaShared/Source/TextManager.cs
+++ b/Barotrauma/BarotraumaShared/Source/TextManager.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
+using System.Text.RegularExpressions;
namespace Barotrauma
{
@@ -42,6 +43,26 @@ namespace Barotrauma
GetTextFilesRecursive(subDir, ref list);
}
}
+
+ ///
+ /// Returns the name of the language in the respective language
+ ///
+ public static string GetTranslatedLanguageName(string language)
+ {
+ if (!textPacks.ContainsKey(language))
+ {
+ return language;
+ }
+
+ foreach (var textPack in textPacks[language])
+ {
+ if (textPack.Language == language)
+ {
+ return textPack.TranslatedName;
+ }
+ }
+ return language;
+ }
public static void LoadTextPacks(IEnumerable selectedContentPackages)
{
@@ -80,6 +101,26 @@ namespace Barotrauma
}
}
+ public static bool ContainsTag(string textTag)
+ {
+ if (string.IsNullOrEmpty(textTag)) { return false; }
+
+ if (!textPacks.ContainsKey(Language))
+ {
+ DebugConsole.ThrowError("No text packs available for the selected language (" + Language + ")! Switching to English...");
+ Language = "English";
+ if (!textPacks.ContainsKey(Language))
+ {
+ throw new Exception("No text packs available in English!");
+ }
+ }
+ foreach (TextPack textPack in textPacks[Language])
+ {
+ if (textPack.Get(textTag) != null) { return true; }
+ }
+ return false;
+ }
+
public static string Get(string textTag, bool returnNull = false, string fallBackTag = null)
{
if (!textPacks.ContainsKey(Language))
@@ -91,8 +132,6 @@ namespace Barotrauma
throw new Exception("No text packs available in English!");
}
}
- return false;
- }
foreach (TextPack textPack in textPacks[Language])
{
@@ -116,7 +155,13 @@ namespace Barotrauma
foreach (TextPack textPack in textPacks["English"])
{
string text = textPack.Get(textTag);
- if (text != null) return text;
+ if (text != null)
+ {
+#if DEBUG
+ DebugConsole.NewMessage("Text \"" + textTag + "\" not found for the language \"" + Language + "\". Using the English text \"" + text + "\" instead.");
+#endif
+ return text;
+ }
}
}
@@ -367,42 +412,6 @@ namespace Barotrauma
return isCJK.IsMatch(text);
}
-#if DEBUG
- public static void CheckForDuplicates(string lang)
- {
- if (!textPacks.ContainsKey(lang))
- {
- DebugConsole.ThrowError("No text packs available for the selected language (" + lang + ")!");
- return;
- }
-
- int packIndex = 0;
- foreach (TextPack textPack in textPacks[lang])
- {
- textPack.CheckForDuplicates(packIndex);
- packIndex++;
- }
- }
-
- public static void WriteToCSV()
- {
- string lang = "English";
-
- if (!textPacks.ContainsKey(lang))
- {
- DebugConsole.ThrowError("No text packs available for the selected language (" + lang + ")!");
- return;
- }
-
- int packIndex = 0;
- foreach (TextPack textPack in textPacks[lang])
- {
- textPack.WriteToCSV(packIndex);
- packIndex++;
- }
- }
-#endif
-
#if DEBUG
public static void CheckForDuplicates(string lang)
{
diff --git a/Barotrauma/BarotraumaShared/Source/TextPack.cs b/Barotrauma/BarotraumaShared/Source/TextPack.cs
index 18b0170d8..565b752da 100644
--- a/Barotrauma/BarotraumaShared/Source/TextPack.cs
+++ b/Barotrauma/BarotraumaShared/Source/TextPack.cs
@@ -10,6 +10,11 @@ namespace Barotrauma
{
public readonly string Language;
+ ///
+ /// The name of the language in the language this pack is written in
+ ///
+ public readonly string TranslatedName;
+
private Dictionary> texts;
private readonly string filePath;
@@ -23,6 +28,7 @@ namespace Barotrauma
if (doc == null || doc.Root == null) return;
Language = doc.Root.GetAttributeString("language", "Unknown");
+ TranslatedName = doc.Root.GetAttributeString("translatedname", Language);
foreach (XElement subElement in doc.Root.Elements())
{
diff --git a/Barotrauma/BarotraumaShared/Submarines/Bunyip.sub b/Barotrauma/BarotraumaShared/Submarines/Bunyip.sub
index 3d6deb368..0981c2849 100644
Binary files a/Barotrauma/BarotraumaShared/Submarines/Bunyip.sub and b/Barotrauma/BarotraumaShared/Submarines/Bunyip.sub differ
diff --git a/Barotrauma/BarotraumaShared/Submarines/Dugong.sub b/Barotrauma/BarotraumaShared/Submarines/Dugong.sub
index ce81dd5a0..4286ee8ec 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 c986d80a9..0a5465f3e 100644
Binary files a/Barotrauma/BarotraumaShared/Submarines/Humpback.sub and b/Barotrauma/BarotraumaShared/Submarines/Humpback.sub differ
diff --git a/Barotrauma/BarotraumaShared/Submarines/Orca.sub b/Barotrauma/BarotraumaShared/Submarines/Orca.sub
index 39ebfe8e7..311edf3e7 100644
Binary files a/Barotrauma/BarotraumaShared/Submarines/Orca.sub and b/Barotrauma/BarotraumaShared/Submarines/Orca.sub differ
diff --git a/Barotrauma/BarotraumaShared/Submarines/Remora.sub b/Barotrauma/BarotraumaShared/Submarines/Remora.sub
index 7e277f1ff..6e3afa65c 100644
Binary files a/Barotrauma/BarotraumaShared/Submarines/Remora.sub and b/Barotrauma/BarotraumaShared/Submarines/Remora.sub differ
diff --git a/Barotrauma/BarotraumaShared/Submarines/RemoraDrone.sub b/Barotrauma/BarotraumaShared/Submarines/RemoraDrone.sub
index eb9b88997..ec48ad330 100644
Binary files a/Barotrauma/BarotraumaShared/Submarines/RemoraDrone.sub and b/Barotrauma/BarotraumaShared/Submarines/RemoraDrone.sub differ
diff --git a/Barotrauma/BarotraumaShared/Submarines/Selkie.sub b/Barotrauma/BarotraumaShared/Submarines/Selkie.sub
index 1c30b9a86..e5a2fc4f9 100644
Binary files a/Barotrauma/BarotraumaShared/Submarines/Selkie.sub and b/Barotrauma/BarotraumaShared/Submarines/Selkie.sub differ
diff --git a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub
index 8605eff50..110792142 100644
Binary files a/Barotrauma/BarotraumaShared/Submarines/Typhon.sub and b/Barotrauma/BarotraumaShared/Submarines/Typhon.sub differ
diff --git a/Barotrauma/BarotraumaShared/changelog.txt b/Barotrauma/BarotraumaShared/changelog.txt
index 3d6fcc970..893423726 100644
--- a/Barotrauma/BarotraumaShared/changelog.txt
+++ b/Barotrauma/BarotraumaShared/changelog.txt
@@ -2,16 +2,42 @@
v0.9.0.2
---------------------------------------------------------------------------------------------------------
-- Fixed a bug that caused frequent desync kicks when playing a multiplayer monster mission.
-- Fixed an index out of range error in DoctorTutorial if proceeding too fast to the submarine.
-- Fixes to missing translations and UI layout problems when using languages other than English.
+- Automatically set the keybinds to AZERTY when French is selected as the display language.
- More readable font and a fix to some texts appearing slightly "clipped".
- Additions to the credits.
-- Fixed bots loading only half of the target items in the contain item objective.
- Minor tweaks to subs and shuttles.
-- Fixed find safety AI objective not working properly.
+- Added propeller damage to the shuttle engine.
+- Increased maximum voice chat volume.
+- Directional voice chat is enabled by default.
+- Display the language names in the respective languages in the initial language selection screen.
+- Playing the splash screens or tutorial videos doesn't require libvlc and libvlccore to be installed
+on the user's system in the Linux version anymore.
+
+Bugfixes:
+- Fixed a bug that caused frequent desync kicks when playing a multiplayer monster mission.
+- Fixed private servers showing up in the server list.
+- Fixed an index out of range error in DoctorTutorial if proceeding too fast to the submarine.
+- Fixed report messages not going through to some clients when there are multiple clients on the server.
+- Fixed players not seeing reports made by bots in multiplayer.
+- Fixes to missing translations and UI layout problems when using languages other than English.
- Miscellaneous crew AI fixes and improvements.
+- Fixed find safety AI objective not working properly.
+- Fixed bots loading only half of the target items in the contain item objective.
+- Fixed directional sonar indicators not being displayed on the sonar monitor.
+- Fixed floating ice chunks occasionally spawning too close to the start of a level, causing them to clip
+through the submarin and/or the outpost.
- Fixed incorrect reward amount in the "Chemical shipment" description.
+- Fixed inability to use the underwater scooters with LMB.
+- Fixes to UI layouts on 4K resolution.
+- Fixed unnecessary silence at the end of the "Objective Complete" music track.
+- Fixed ruin walls being almost impossible to cut from inside the ruins.
+- Fixed the "report leaks" button being highlighted inside ruins.
+- Fixes to wall colliders.
+- Fixed "Pause on focus lost" setting being always treated as if being enabled.
+- Fixed dedicated server overwriting existing crash reports.
+- Fixed save time being displayed in UNIX time in the right-hand panel in the campaign setup UI.
+- Fixed "Praise the Honkmother" and "Extravehicular activity" achievements not unlocking in multiplayer.
+- Fixed "No fun allowed" achievement being possible to unlock by committing suicide while wearing a clown costume.
---------------------------------------------------------------------------------------------------------
v0.9.0.1
diff --git a/Barotrauma/BarotraumaShared/config.xml b/Barotrauma/BarotraumaShared/config.xml
index ee19fb607..6e38e3c7c 100644
--- a/Barotrauma/BarotraumaShared/config.xml
+++ b/Barotrauma/BarotraumaShared/config.xml
@@ -9,13 +9,13 @@
savedebugconsolelogs="false"
enablesplashscreen="true"
usesteammatchmaking="true"
- quickstartsub = "Humpback"
+ quickstartsub="Humpback"
requiresteamauthentication="true">