(8f9250974) Fix spritesheet orientation offestting the joint widgets in the wrong direction, which made it a bit difficult to use.
This commit is contained in:
@@ -79,8 +79,8 @@
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\ParamsEditor.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\RectTransform.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\ShapeExtensions.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\SpriteSheetPlayer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\UISprite.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\VideoPlayer.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\GUI\Widget.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\CharacterInventory.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Source\Items\Components\Door.cs" />
|
||||
|
||||
@@ -16,13 +16,14 @@ namespace Barotrauma
|
||||
|
||||
if (SelectedAiTarget?.Entity != null)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.3f, 0, 5);
|
||||
GUI.DrawLine(spriteBatch, pos, new Vector2(SelectedAiTarget.WorldPosition.X, -SelectedAiTarget.WorldPosition.Y), Color.Red * 0.5f, 0, 4);
|
||||
|
||||
if (wallTarget != null)
|
||||
{
|
||||
Vector2 wallTargetPos = wallTarget.Position;
|
||||
if (wallTarget.Structure.Submarine != null) { wallTargetPos += wallTarget.Structure.Submarine.Position; }
|
||||
wallTargetPos.Y = -wallTargetPos.Y;
|
||||
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Red, false);
|
||||
GUI.DrawRectangle(spriteBatch, wallTargetPos - new Vector2(10.0f, 10.0f), new Vector2(20.0f, 20.0f), Color.Orange, false);
|
||||
GUI.DrawLine(spriteBatch, pos, wallTargetPos, Color.Orange * 0.5f, 0, 5);
|
||||
}
|
||||
GUI.DrawString(spriteBatch, pos - Vector2.UnitY * 60.0f, $"{SelectedAiTarget.Entity.ToString()} ({targetValue.FormatZeroDecimal()})", Color.Red, Color.Black);
|
||||
@@ -56,18 +57,16 @@ namespace Barotrauma
|
||||
{
|
||||
GUI.DrawLine(spriteBatch,
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorA.X, -attachJoint.WorldAnchorA.Y)),
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), Color.Orange * 0.6f, 0, 5);
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(attachJoint.WorldAnchorB.X, -attachJoint.WorldAnchorB.Y)), Color.Green, 0, 4);
|
||||
}
|
||||
|
||||
if (latchOntoAI.WallAttachPos.HasValue)
|
||||
{
|
||||
GUI.DrawLine(spriteBatch, pos,
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(latchOntoAI.WallAttachPos.Value.X, -latchOntoAI.WallAttachPos.Value.Y)), Color.Orange * 0.6f, 0, 3);
|
||||
ConvertUnits.ToDisplayUnits(new Vector2(latchOntoAI.WallAttachPos.Value.X, -latchOntoAI.WallAttachPos.Value.Y)), Color.Green, 0, 3);
|
||||
}
|
||||
}
|
||||
|
||||
GUI.DrawLine(spriteBatch, pos, pos + ConvertUnits.ToDisplayUnits(new Vector2(Steering.X, -Steering.Y)), Color.Blue, width: 3);
|
||||
|
||||
if (steeringManager is IndoorsSteeringManager pathSteering)
|
||||
{
|
||||
var path = pathSteering.CurrentPath;
|
||||
|
||||
@@ -68,14 +68,6 @@ namespace Barotrauma
|
||||
|
||||
private float dropItemAnimDuration = 0.5f;
|
||||
private float dropItemAnimTimer;
|
||||
|
||||
public Item DroppedItem
|
||||
{
|
||||
get
|
||||
{
|
||||
return droppedItem;
|
||||
}
|
||||
}
|
||||
private Item droppedItem;
|
||||
|
||||
private GUIComponent draggingMed;
|
||||
|
||||
@@ -1815,6 +1815,189 @@ namespace Barotrauma
|
||||
NPCConversation.WriteToCSV();
|
||||
}));
|
||||
|
||||
commands.Add(new Command("csvtoxml", "csvtoxml [language] -> Converts .csv localization files in Content/NPCConversations & Content/Texts to .xml for use in-game.", (string[] args) =>
|
||||
{
|
||||
if (args.Length == 0) return;
|
||||
LocalizationCSVtoXML.Convert(args[0]);
|
||||
}));
|
||||
#endif
|
||||
|
||||
commands.Add(new Command("cleanbuild", "", (string[] args) =>
|
||||
{
|
||||
float defaultZoom = Screen.Selected.Cam.DefaultZoom;
|
||||
if (args.Length > 0) float.TryParse(args[0], NumberStyles.Number, CultureInfo.InvariantCulture, out defaultZoom);
|
||||
|
||||
float zoomSmoothness = Screen.Selected.Cam.ZoomSmoothness;
|
||||
if (args.Length > 1) float.TryParse(args[1], NumberStyles.Number, CultureInfo.InvariantCulture, out zoomSmoothness);
|
||||
float moveSmoothness = Screen.Selected.Cam.MoveSmoothness;
|
||||
if (args.Length > 2) float.TryParse(args[2], NumberStyles.Number, CultureInfo.InvariantCulture, out moveSmoothness);
|
||||
|
||||
float minZoom = Screen.Selected.Cam.MinZoom;
|
||||
if (args.Length > 3) float.TryParse(args[3], NumberStyles.Number, CultureInfo.InvariantCulture, out minZoom);
|
||||
float maxZoom = Screen.Selected.Cam.MaxZoom;
|
||||
if (args.Length > 4) float.TryParse(args[4], NumberStyles.Number, CultureInfo.InvariantCulture, out maxZoom);
|
||||
|
||||
Screen.Selected.Cam.DefaultZoom = defaultZoom;
|
||||
Screen.Selected.Cam.ZoomSmoothness = zoomSmoothness;
|
||||
Screen.Selected.Cam.MoveSmoothness = moveSmoothness;
|
||||
Screen.Selected.Cam.MinZoom = minZoom;
|
||||
Screen.Selected.Cam.MaxZoom = maxZoom;
|
||||
}));
|
||||
|
||||
commands.Add(new Command("waterparams", "waterparams [distortionscalex] [distortionscaley] [distortionstrengthx] [distortionstrengthy] [bluramount]: default 0.5 0.5 0.5 0.5 1", (string[] args) =>
|
||||
{
|
||||
float distortScaleX = 0.5f, distortScaleY = 0.5f;
|
||||
float distortStrengthX = 0.5f, distortStrengthY = 0.5f;
|
||||
float blurAmount = 0.0f;
|
||||
if (args.Length > 0) float.TryParse(args[0], NumberStyles.Number, CultureInfo.InvariantCulture, out distortScaleX);
|
||||
if (args.Length > 1) float.TryParse(args[1], NumberStyles.Number, CultureInfo.InvariantCulture, out distortScaleY);
|
||||
if (args.Length > 2) float.TryParse(args[2], NumberStyles.Number, CultureInfo.InvariantCulture, out distortStrengthX);
|
||||
if (args.Length > 3) float.TryParse(args[3], NumberStyles.Number, CultureInfo.InvariantCulture, out distortStrengthY);
|
||||
if (args.Length > 4) float.TryParse(args[4], NumberStyles.Number, CultureInfo.InvariantCulture, out blurAmount);
|
||||
WaterRenderer.DistortionScale = new Vector2(distortScaleX, distortScaleY);
|
||||
WaterRenderer.DistortionStrength = new Vector2(distortStrengthX, distortStrengthY);
|
||||
WaterRenderer.BlurAmount = blurAmount;
|
||||
}));
|
||||
|
||||
|
||||
commands.Add(new Command("refreshrect", "Updates the dimensions of the selected items to match the ones defined in the prefab. Applied only in the subeditor.", (string[] args) =>
|
||||
{
|
||||
//TODO: maybe do this automatically during loading when possible?
|
||||
if (Screen.Selected == GameMain.SubEditorScreen)
|
||||
{
|
||||
if (!MapEntity.SelectedAny)
|
||||
{
|
||||
ThrowError("You have to select item(s) first!");
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var mapEntity in MapEntity.SelectedList)
|
||||
{
|
||||
if (mapEntity is Item item)
|
||||
{
|
||||
item.Rect = new Rectangle(item.Rect.X, item.Rect.Y,
|
||||
(int)(item.Prefab.sprite.size.X * item.Prefab.Scale),
|
||||
(int)(item.Prefab.sprite.size.Y * item.Prefab.Scale));
|
||||
}
|
||||
else if (mapEntity is Structure structure)
|
||||
{
|
||||
if (!structure.ResizeHorizontal)
|
||||
{
|
||||
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
|
||||
(int)structure.Prefab.ScaledSize.X,
|
||||
structure.Rect.Height);
|
||||
}
|
||||
if (!structure.ResizeVertical)
|
||||
{
|
||||
structure.Rect = new Rectangle(structure.Rect.X, structure.Rect.Y,
|
||||
structure.Rect.Width,
|
||||
(int)structure.Prefab.ScaledSize.Y);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, isCheat: false));
|
||||
#endif
|
||||
|
||||
GameMain.Config.SaveNewPlayerConfig();
|
||||
|
||||
commands.Add(new Command("loadtexts", "loadtexts [sourcefile] [destinationfile]: Loads all lines of text from a given .txt file and inserts them sequientially into the elements of an xml file. If the file paths are omitted, EnglishVanilla.txt and EnglishVanilla.xml are used.", (string[] args) =>
|
||||
{
|
||||
string sourcePath = args.Length > 0 ? args[0] : "Content/Texts/EnglishVanilla.txt";
|
||||
string destinationPath = args.Length > 1 ? args[1] : "Content/Texts/EnglishVanilla.xml";
|
||||
|
||||
string[] lines;
|
||||
try
|
||||
{
|
||||
lines = File.ReadAllLines(sourcePath);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
ThrowError("Reading the file \"" + sourcePath + "\" failed.", e);
|
||||
return;
|
||||
}
|
||||
var doc = XMLExtensions.TryLoadXml(destinationPath);
|
||||
int i = 0;
|
||||
foreach (XElement element in doc.Root.Elements())
|
||||
{
|
||||
if (i >= lines.Length)
|
||||
{
|
||||
ThrowError("Error while loading texts to the xml file. The xml has more elements than the number of lines in the text file.");
|
||||
return;
|
||||
}
|
||||
element.Value = lines[i];
|
||||
i++;
|
||||
}
|
||||
doc.Save(destinationPath);
|
||||
},
|
||||
() =>
|
||||
{
|
||||
var files = TextManager.GetTextFiles().Select(f => f.Replace("\\", "/"));
|
||||
return new string[][]
|
||||
{
|
||||
files.Where(f => Path.GetExtension(f)==".txt").ToArray(),
|
||||
files.Where(f => Path.GetExtension(f)==".xml").ToArray()
|
||||
};
|
||||
}));
|
||||
|
||||
commands.Add(new Command("updatetextfile", "updatetextfile [sourcefile] [destinationfile]: Inserts all the xml elements that are only present in the source file into the destination file. Can be used to update outdated translation files more easily.", (string[] args) =>
|
||||
{
|
||||
if (args.Length < 2) return;
|
||||
string sourcePath = args[0];
|
||||
string destinationPath = args[1];
|
||||
|
||||
var sourceDoc = XMLExtensions.TryLoadXml(sourcePath);
|
||||
var destinationDoc = XMLExtensions.TryLoadXml(destinationPath);
|
||||
|
||||
XElement destinationElement = destinationDoc.Root.Elements().First();
|
||||
foreach (XElement element in sourceDoc.Root.Elements())
|
||||
{
|
||||
if (destinationDoc.Root.Element(element.Name) == null)
|
||||
{
|
||||
element.Value = "!!!!!!!!!!!!!" + element.Value;
|
||||
destinationElement.AddAfterSelf(element);
|
||||
}
|
||||
XNode nextNode = destinationElement.NextNode;
|
||||
while ((!(nextNode is XElement) || nextNode == element) && nextNode != null) nextNode = nextNode.NextNode;
|
||||
destinationElement = nextNode as XElement;
|
||||
}
|
||||
destinationDoc.Save(destinationPath);
|
||||
},
|
||||
() =>
|
||||
{
|
||||
var files = TextManager.GetTextFiles().Where(f => Path.GetExtension(f) == ".xml").Select(f => f.Replace("\\", "/")).ToArray();
|
||||
return new string[][]
|
||||
{
|
||||
files,
|
||||
files
|
||||
};
|
||||
}));
|
||||
|
||||
commands.Add(new Command("dumpentitytexts", "dumpentitytexts [filepath]: gets the names and descriptions of all entity prefabs and writes them into a file along with xml tags that can be used in translation files. If the filepath is omitted, the file is written to Content/Texts/EntityTexts.txt", (string[] args) =>
|
||||
{
|
||||
string filePath = args.Length > 0 ? args[0] : "Content/Texts/EntityTexts.txt";
|
||||
List<string> lines = new List<string>();
|
||||
foreach (MapEntityPrefab me in MapEntityPrefab.List)
|
||||
{
|
||||
lines.Add("<EntityName." + me.Identifier + ">" + me.Name + "</" + me.Identifier + ".Name>");
|
||||
lines.Add("<EntityDescription." + me.Identifier + ">" + me.Description + "</" + me.Identifier + ".Description>");
|
||||
}
|
||||
File.WriteAllLines(filePath, lines);
|
||||
}));
|
||||
#if DEBUG
|
||||
commands.Add(new Command("checkduplicates", "Checks the given language for duplicate translation keys and writes to file.", (string[] args) =>
|
||||
{
|
||||
if (args.Length != 1) return;
|
||||
TextManager.CheckForDuplicates(args[0]);
|
||||
}));
|
||||
|
||||
commands.Add(new Command("writetocsv", "Writes the default language (English) to a .csv file.", (string[] args) =>
|
||||
{
|
||||
TextManager.WriteToCSV();
|
||||
NPCConversation.WriteToCSV();
|
||||
}));
|
||||
|
||||
commands.Add(new Command("csvtoxml", "csvtoxml [language] -> Converts .csv localization files in Content/NPCConversations & Content/Texts to .xml for use in-game.", (string[] args) =>
|
||||
{
|
||||
if (args.Length == 0) return;
|
||||
|
||||
@@ -69,9 +69,6 @@ namespace Barotrauma
|
||||
public static ScalableFont Font => Style?.Font;
|
||||
public static ScalableFont SmallFont => Style?.SmallFont;
|
||||
public static ScalableFont LargeFont => Style?.LargeFont;
|
||||
public static ScalableFont VideoTitleFont => Style?.VideoTitleFont;
|
||||
public static ScalableFont ObjectiveTitleFont => Style?.ObjectiveTitleFont;
|
||||
public static ScalableFont ObjectiveNameFont => Style?.ObjectiveNameFont;
|
||||
|
||||
public static UISprite UIGlow => Style.UIGlow;
|
||||
|
||||
@@ -533,19 +530,14 @@ namespace Barotrauma
|
||||
if (list.Count == 0) { return; }
|
||||
foreach (var item in list)
|
||||
{
|
||||
int index = 0;
|
||||
if (updateList.Count > 0)
|
||||
int i = updateList.Count - 1;
|
||||
while (updateList[i].UpdateOrder > item.UpdateOrder)
|
||||
{
|
||||
index = updateList.Count - 1;
|
||||
while (updateList[index].UpdateOrder > item.UpdateOrder)
|
||||
{
|
||||
index--;
|
||||
if (index == 0) { break; }
|
||||
}
|
||||
i--;
|
||||
}
|
||||
if (!updateListSet.Contains(item))
|
||||
{
|
||||
updateList.Insert(index, item);
|
||||
updateList.Insert(Math.Max(i, 0), item);
|
||||
updateListSet.Add(item);
|
||||
}
|
||||
}
|
||||
@@ -656,21 +648,6 @@ namespace Barotrauma
|
||||
msg.Timer -= deltaTime;
|
||||
msg.Pos += msg.Velocity * deltaTime;
|
||||
}
|
||||
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
if (!msg.WorldSpace) continue;
|
||||
msg.Timer -= deltaTime;
|
||||
msg.Pos += msg.Velocity * deltaTime;
|
||||
}
|
||||
|
||||
foreach (GUIMessage msg in messages)
|
||||
{
|
||||
if (!msg.WorldSpace) continue;
|
||||
msg.Timer -= deltaTime;
|
||||
msg.Pos += msg.Velocity * deltaTime;
|
||||
}
|
||||
}
|
||||
|
||||
messages.RemoveAll(m => m.Timer <= 0.0f);
|
||||
}
|
||||
@@ -744,10 +721,6 @@ namespace Barotrauma
|
||||
Vector2 textSize = font.MeasureString(text);
|
||||
DrawRectangle(sb, pos - Vector2.One * backgroundPadding, textSize + Vector2.One * 2.0f * backgroundPadding, (Color)backgroundColor, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Draw(t, new Rectangle(rect.X + thickness, rect.Y, rect.Width - thickness * 2, thickness), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
||||
sb.Draw(t, new Rectangle(rect.X + thickness, rect.Y + rect.Height - thickness, rect.Width - thickness * 2, thickness), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
||||
|
||||
font.DrawString(sb, text, pos, color);
|
||||
}
|
||||
|
||||
@@ -12,9 +12,6 @@ namespace Barotrauma
|
||||
public ScalableFont Font { get; private set; }
|
||||
public ScalableFont SmallFont { get; private set; }
|
||||
public ScalableFont LargeFont { get; private set; }
|
||||
public ScalableFont VideoTitleFont { get; private set; }
|
||||
public ScalableFont ObjectiveTitleFont { get; private set; }
|
||||
public ScalableFont ObjectiveNameFont { get; private set; }
|
||||
|
||||
public Sprite CursorSprite { get; private set; }
|
||||
|
||||
@@ -51,15 +48,6 @@ namespace Barotrauma
|
||||
case "largefont":
|
||||
LargeFont = new ScalableFont(subElement, graphicsDevice);
|
||||
break;
|
||||
case "objectivetitle":
|
||||
ObjectiveTitleFont = new ScalableFont(subElement, graphicsDevice);
|
||||
break;
|
||||
case "objectivename":
|
||||
ObjectiveNameFont = new ScalableFont(subElement, graphicsDevice);
|
||||
break;
|
||||
case "videotitle":
|
||||
VideoTitleFont = new ScalableFont(subElement, graphicsDevice);
|
||||
break;
|
||||
case "cursor":
|
||||
CursorSprite = new Sprite(subElement);
|
||||
break;
|
||||
|
||||
@@ -50,11 +50,6 @@ namespace Barotrauma
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public static Rectangle ObjectiveAnchor
|
||||
{
|
||||
get; private set;
|
||||
}
|
||||
|
||||
public static Rectangle InventoryAreaLower
|
||||
{
|
||||
get; private set;
|
||||
@@ -161,10 +156,6 @@ namespace Barotrauma
|
||||
new Rectangle(Padding, CrewArea.Y, chatBoxWidth, chatBoxHeight) :
|
||||
new Rectangle(GameMain.GraphicsWidth - Padding - chatBoxWidth, CrewArea.Y, chatBoxWidth, chatBoxHeight);
|
||||
|
||||
int objectiveAnchorWidth = (int)(250 * GUI.Scale);
|
||||
int objectiveAnchorOffsetY = (int)(100 * GUI.Scale);
|
||||
ObjectiveAnchor = new Rectangle(GameMain.GraphicsWidth - Padding - objectiveAnchorWidth, CrewArea.Y + crewAreaHeight + objectiveAnchorOffsetY, objectiveAnchorWidth, 0);
|
||||
|
||||
int lowerAreaHeight = (int)Math.Min(GameMain.GraphicsHeight * 0.25f, 280);
|
||||
InventoryAreaLower = new Rectangle(Padding, GameMain.GraphicsHeight - lowerAreaHeight, GameMain.GraphicsWidth - Padding * 2, lowerAreaHeight);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace Barotrauma
|
||||
|
||||
ContextualTutorial = Tutorial.Tutorials.Find(t => t is ContextualTutorial) as ContextualTutorial;
|
||||
|
||||
if (ContextualTutorial.Selected) // Selected when starting a new game -> initialize
|
||||
if (ContextualTutorial.Selected && !ContextualTutorial.Initialized) // Selected when starting a new game -> initialize
|
||||
{
|
||||
ContextualTutorial.Initialize();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Xml.Linq;
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Items.Components;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
|
||||
namespace Barotrauma.Tutorials
|
||||
{
|
||||
@@ -14,60 +13,38 @@ namespace Barotrauma.Tutorials
|
||||
public static bool ContentRunning = false;
|
||||
public static bool Initialized = false;
|
||||
|
||||
private enum ContentTypes { None = 0, Video = 1, TextOnly = 2 };
|
||||
private enum ContentTypes { None = 0, Video = 1, Text = 2 };
|
||||
|
||||
private TutorialSegment activeSegment;
|
||||
private List<TutorialSegment> segments;
|
||||
|
||||
private VideoPlayer videoPlayer;
|
||||
|
||||
private SpriteSheetPlayer spriteSheetPlayer;
|
||||
private Steering navConsole;
|
||||
private Reactor reactor;
|
||||
private Sonar sonar;
|
||||
private Vector2 subStartingPosition;
|
||||
private List<Character> crew;
|
||||
private Character mechanic;
|
||||
private Character engineer;
|
||||
private Character injuredMember = null;
|
||||
|
||||
private List<Pair<Character, float>> characterTimeOnSonar;
|
||||
private float requiredTimeOnSonar = 5f;
|
||||
|
||||
private bool started = false;
|
||||
private string playableContentPath;
|
||||
|
||||
|
||||
private float tutorialTimer;
|
||||
private float degrading2ActivationCountdown;
|
||||
|
||||
private bool disableTutorialOnDeficiencyFound = true;
|
||||
|
||||
private GUIFrame holderFrame, objectiveFrame;
|
||||
//private GUIButton toggleButton;
|
||||
//private bool objectivesOpen = false;
|
||||
//private float openState = 0f;
|
||||
private List<TutorialSegment> activeObjectives = new List<TutorialSegment>();
|
||||
private string objectiveTranslated;
|
||||
//private Point objectiveBaseOffset = Point.Zero;
|
||||
|
||||
private float floodTutorialTimer = 0.0f;
|
||||
private const float floodTutorialDelay = 2.0f;
|
||||
private float medicalTutorialTimer = 0.0f;
|
||||
private const float medicalTutorialDelay = 2.0f;
|
||||
|
||||
private class TutorialSegment
|
||||
{
|
||||
public string Id;
|
||||
public string Objective;
|
||||
public string Name;
|
||||
public ContentTypes ContentType;
|
||||
public XElement TextContent;
|
||||
public XElement VideoContent;
|
||||
public XElement Content;
|
||||
public bool IsTriggered;
|
||||
public GUIButton ReplayButton;
|
||||
public GUITextBlock LinkedTitle, LinkedText;
|
||||
|
||||
public TutorialSegment(XElement config)
|
||||
{
|
||||
Id = config.GetAttributeString("id", "Missing ID");
|
||||
Objective = TextManager.Get(config.GetAttributeString("objective", string.Empty), true);
|
||||
Name = config.GetAttributeString("name", "Missing Name");
|
||||
Enum.TryParse(config.GetAttributeString("contenttype", "None"), true, out ContentType);
|
||||
IsTriggered = config.GetAttributeBool("istriggered", false);
|
||||
|
||||
@@ -76,11 +53,10 @@ namespace Barotrauma.Tutorials
|
||||
case ContentTypes.None:
|
||||
break;
|
||||
case ContentTypes.Video:
|
||||
VideoContent = config.Element("Video");
|
||||
TextContent = config.Element("Text");
|
||||
Content = config.Element("Video");
|
||||
break;
|
||||
case ContentTypes.TextOnly:
|
||||
TextContent = config.Element("Text");
|
||||
case ContentTypes.Text:
|
||||
Content = config.Element("Text");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -101,18 +77,17 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
for (int i = 0; i < segments.Count; i++)
|
||||
{
|
||||
segments[i].IsTriggered = false;
|
||||
}
|
||||
|
||||
if (Initialized) return;
|
||||
Initialized = true;
|
||||
|
||||
base.Initialize();
|
||||
videoPlayer = new VideoPlayer();
|
||||
spriteSheetPlayer = new SpriteSheetPlayer();
|
||||
characterTimeOnSonar = new List<Pair<Character, float>>();
|
||||
//objectivesOpen = true;
|
||||
|
||||
for (int i = 0; i < segments.Count; i++)
|
||||
{
|
||||
segments[i].IsTriggered = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void LoadPartiallyComplete(XElement element)
|
||||
@@ -136,13 +111,13 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
}
|
||||
|
||||
private void PreloadVideoContent() // Have to see if needed with videos
|
||||
private void PreloadVideoContent()
|
||||
{
|
||||
/*for (int i = 0; i < segments.Count; i++)
|
||||
for (int i = 0; i < segments.Count; i++)
|
||||
{
|
||||
if (segments[i].ContentType != ContentTypes.Video || segments[i].IsTriggered) continue;
|
||||
spriteSheetPlayer.PreloadContent(playableContentPath, "tutorial", segments[i].Id, segments[i].VideoContent);
|
||||
}*/
|
||||
spriteSheetPlayer.PreloadContent(playableContentPath, "tutorial", segments[i].Name, segments[i].Content);
|
||||
}
|
||||
}
|
||||
|
||||
public void SavePartiallyComplete(XElement element)
|
||||
@@ -180,12 +155,9 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
base.Start();
|
||||
|
||||
injuredMember = null;
|
||||
activeObjectives.Clear();
|
||||
objectiveTranslated = TextManager.Get("Objective");
|
||||
CreateObjectiveFrame();
|
||||
activeSegment = null;
|
||||
tutorialTimer = floodTutorialTimer = medicalTutorialTimer = 0.0f;
|
||||
tutorialTimer = 0.0f;
|
||||
degrading2ActivationCountdown = -1;
|
||||
subStartingPosition = Vector2.Zero;
|
||||
characterTimeOnSonar.Clear();
|
||||
|
||||
@@ -221,9 +193,6 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
|
||||
crew = GameMain.GameSession.CrewManager.GetCharacters().ToList();
|
||||
mechanic = CrewMemberWithJob("mechanic");
|
||||
engineer = CrewMemberWithJob("engineer");
|
||||
|
||||
Completed = true; // Trigger completed at start to prevent the contextual tutorial from automatically activating on starting new campaigns after this one
|
||||
started = true;
|
||||
}
|
||||
@@ -239,196 +208,71 @@ namespace Barotrauma.Tutorials
|
||||
public void Stop()
|
||||
{
|
||||
started = ContentRunning = Initialized = false;
|
||||
videoPlayer.Remove();
|
||||
videoPlayer = null;
|
||||
spriteSheetPlayer.Remove();
|
||||
spriteSheetPlayer = null;
|
||||
characterTimeOnSonar = null;
|
||||
}
|
||||
|
||||
private void CreateObjectiveFrame()
|
||||
{
|
||||
holderFrame = new GUIFrame(new RectTransform(new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight), GUI.Canvas, Anchor.Center));
|
||||
objectiveFrame = new GUIFrame(HUDLayoutSettings.ToRectTransform(HUDLayoutSettings.ObjectiveAnchor, holderFrame.RectTransform), style: null);
|
||||
|
||||
/*int toggleButtonWidth = (int)(30 * GUI.Scale);
|
||||
int toggleButtonHeight = (int)(40 * GUI.Scale);
|
||||
toggleButton = new GUIButton(new RectTransform(new Point(toggleButtonWidth, toggleButtonHeight), objectiveFrame.RectTransform, Anchor.CenterRight) { AbsoluteOffset = new Point(0, 20) }, style: "UIToggleButton");
|
||||
toggleButton.OnClicked += (GUIButton btn, object userdata) =>
|
||||
{
|
||||
objectivesOpen = !objectivesOpen;
|
||||
foreach (GUIComponent child in btn.Children)
|
||||
{
|
||||
child.SpriteEffects = objectivesOpen ? SpriteEffects.FlipHorizontally : SpriteEffects.None;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
objectiveBaseOffset = new Point((int)(-2.5f * toggleButton.Rect.Width), 0);*/
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
{
|
||||
if (objectiveFrame != null && activeObjectives.Count > 0)
|
||||
{
|
||||
objectiveFrame.AddToGUIUpdateList(order: -1);
|
||||
}
|
||||
base.AddToGUIUpdateList();
|
||||
if (videoPlayer != null)
|
||||
if (spriteSheetPlayer != null)
|
||||
{
|
||||
videoPlayer.AddToGUIUpdateList(order: 100);
|
||||
spriteSheetPlayer.AddToGUIUpdateList();
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
{
|
||||
if (videoPlayer != null)
|
||||
{
|
||||
videoPlayer.Update();
|
||||
}
|
||||
|
||||
if (infoBox != null)
|
||||
{
|
||||
if (PlayerInput.KeyHit(Keys.Enter) || PlayerInput.KeyHit(Keys.Escape))
|
||||
{
|
||||
CloseInfoFrame(null, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (!started || ContentRunning) return;
|
||||
|
||||
deltaTime *= 0.5f;
|
||||
|
||||
|
||||
for (int i = 0; i < segments.Count; i++)
|
||||
{
|
||||
if (segments[i].IsTriggered || activeObjectives.Contains(segments[i])) continue;
|
||||
if (segments[i].IsTriggered) continue;
|
||||
if (CheckContextualTutorials(i, deltaTime)) // Found a relevant tutorial, halt finding new ones
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
CheckActiveObjectives(activeObjectives[i], deltaTime);
|
||||
}
|
||||
|
||||
/*if (activeObjectives.Count > 0)
|
||||
{
|
||||
if (objectivesOpen)
|
||||
{
|
||||
openState -= deltaTime * 5.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
openState += deltaTime * 5.0f;
|
||||
}
|
||||
|
||||
openState = MathHelper.Clamp(openState, 0.0f, 1.0f);
|
||||
|
||||
float widestObjective = 0f;
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
if (activeObjectives[i].ReplayButton.Rect.Width > widestObjective)
|
||||
{
|
||||
widestObjective = activeObjectives[i].ReplayButton.Rect.Width;
|
||||
}
|
||||
}
|
||||
|
||||
float objectivesHiddenOffset = widestObjective + toggleButton.Rect.Width + 100f;
|
||||
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
activeObjectives[i].ReplayButton.RectTransform.AbsoluteOffset = objectiveBaseOffset + new Point((int)MathHelper.SmoothStep(0, objectivesHiddenOffset, openState), 0);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
private void ClosePreTextAndTriggerVideoCallback()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(activeSegment.Objective))
|
||||
{
|
||||
videoPlayer.LoadContentWithObjective(playableContentPath, new VideoPlayer.VideoSettings(activeSegment.VideoContent), new VideoPlayer.TextSettings(activeSegment.VideoContent), activeSegment.Id, true, activeSegment.Objective, CurrentSegmentStopCallback);
|
||||
}
|
||||
else
|
||||
{
|
||||
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(activeSegment.VideoContent), new VideoPlayer.TextSettings(activeSegment.VideoContent), activeSegment.Id, true, CurrentSegmentStopCallback);
|
||||
}
|
||||
}
|
||||
|
||||
private void CurrentSegmentStopCallback()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(activeSegment.Objective))
|
||||
{
|
||||
AddNewObjective(activeSegment);
|
||||
}
|
||||
|
||||
activeSegment = null;
|
||||
ContentRunning = false;
|
||||
}
|
||||
|
||||
private void AddNewObjective(TutorialSegment segment)
|
||||
{
|
||||
activeObjectives.Add(segment);
|
||||
|
||||
Point replayButtonSize = new Point((int)GUI.ObjectiveNameFont.MeasureString(segment.Objective).X, (int)(GUI.ObjectiveNameFont.MeasureString(segment.Objective).Y * 1.45f));
|
||||
|
||||
segment.ReplayButton = new GUIButton(new RectTransform(replayButtonSize, objectiveFrame.RectTransform, Anchor.TopRight, Pivot.TopRight) { AbsoluteOffset = new Point(/*(int)(-2.5f * toggleButton.Rect.Width)*/0, (replayButtonSize.Y + 20) * (activeObjectives.Count - 1)) }, style: null);
|
||||
segment.ReplayButton.OnClicked += (GUIButton btn, object userdata) =>
|
||||
{
|
||||
ReplaySegmentVideo(segment);
|
||||
return true;
|
||||
};
|
||||
|
||||
int yOffset = (int)(GUI.ObjectiveNameFont.MeasureString(objectiveTranslated).Y / 2f) + 5;
|
||||
segment.LinkedTitle = new GUITextBlock(new RectTransform(new Point(replayButtonSize.X, yOffset), segment.ReplayButton.RectTransform, Anchor.Center, Pivot.BottomCenter) { AbsoluteOffset = new Point(10, 0) }, objectiveTranslated, textColor: Color.White, font: GUI.ObjectiveTitleFont, textAlignment: Alignment.CenterRight);
|
||||
segment.LinkedText = new GUITextBlock(new RectTransform(new Point(replayButtonSize.X, yOffset), segment.ReplayButton.RectTransform, Anchor.Center, Pivot.TopCenter) { AbsoluteOffset = new Point(10, 0) }, segment.Objective, textColor: new Color(4, 180, 108), font: GUI.ObjectiveNameFont, textAlignment: Alignment.CenterRight);
|
||||
|
||||
segment.LinkedTitle.Color = segment.LinkedTitle.HoverColor = segment.LinkedTitle.PressedColor = segment.LinkedTitle.SelectedColor = Color.Transparent;
|
||||
segment.LinkedText.Color = segment.LinkedText.HoverColor = segment.LinkedText.PressedColor = segment.LinkedText.SelectedColor = Color.Transparent;
|
||||
segment.ReplayButton.Color = segment.ReplayButton.HoverColor = segment.ReplayButton.PressedColor = segment.ReplayButton.SelectedColor = Color.Transparent;
|
||||
}
|
||||
|
||||
private void RemoveCompletedObjective(TutorialSegment objective)
|
||||
{
|
||||
objectiveFrame.RemoveChild(objective.ReplayButton);
|
||||
activeObjectives.Remove(objective);
|
||||
objective.IsTriggered = true;
|
||||
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
activeObjectives[i].ReplayButton.RectTransform.AbsoluteOffset = new Point(0, (activeObjectives[i].ReplayButton.Rect.Height + 20) * i);
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckContextualTutorials(int index, float deltaTime)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: // Welcome: Game Start [Text]
|
||||
if (tutorialTimer < 1.0f)
|
||||
if (tutorialTimer < 0.5f)
|
||||
{
|
||||
tutorialTimer += deltaTime;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 1: // Command Reactor: 2 seconds after 'Welcome' dismissed and only if no command given to start reactor [Video]
|
||||
if (!segments[0].IsTriggered) return false;
|
||||
if (tutorialTimer < 3.0f)
|
||||
case 1: // Command Reactor: 10 seconds after 'Welcome' dismissed and only if no command given to start reactor [Video]
|
||||
if (tutorialTimer < 10.5f)
|
||||
{
|
||||
tutorialTimer += deltaTime;
|
||||
|
||||
if (HasOrder("operatereactor"))
|
||||
{
|
||||
segments[index].IsTriggered = true;
|
||||
tutorialTimer = 2.5f;
|
||||
tutorialTimer = 10.5f;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 2: // Nav Console: 2 seconds after 'Command Reactor' dismissed or if nav console is activated [Video]
|
||||
if (!IsReactorPoweredUp()) return false; // Do not advance tutorial based on this segment if reactor has not been powered up
|
||||
case 2: // Nav Console: 20 seconds after 'Command Reactor' dismissed or if nav console is activated [Video]
|
||||
if (Character.Controlled?.SelectedConstruction != navConsole.Item)
|
||||
{
|
||||
if (tutorialTimer < 4.5f)
|
||||
{
|
||||
if (!segments[1].IsTriggered) return false; // Do not advance tutorial timer based on this segment if reactor has not been powered up
|
||||
if (tutorialTimer < 30.5f)
|
||||
{
|
||||
tutorialTimer += deltaTime;
|
||||
return false;
|
||||
@@ -436,13 +280,20 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
else
|
||||
{
|
||||
tutorialTimer = 4.5f;
|
||||
}
|
||||
if (!segments[1].IsTriggered || !HasOrder("operatereactor")) // If reactor has not been powered up or ordered to be, default to that one first
|
||||
{
|
||||
if (tutorialTimer < 10.5f)
|
||||
{
|
||||
tutorialTimer = 10.5f;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
||||
return true;
|
||||
tutorialTimer = 30.5f;
|
||||
}
|
||||
break;
|
||||
case 3: // Objective: Travel ~150 meters and while sub is not flooding [Text]
|
||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 8000f || IsFlooding())
|
||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 12000f || IsFlooding())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -456,11 +307,6 @@ namespace Barotrauma.Tutorials
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (floodTutorialTimer < floodTutorialDelay)
|
||||
{
|
||||
floodTutorialTimer += deltaTime;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 5: // Reactor: Player uses reactor for the first time [Video]
|
||||
if (Character.Controlled?.SelectedConstruction != reactor.Item)
|
||||
@@ -475,23 +321,19 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
break;
|
||||
case 7: // Degrading1: Any equipment degrades to 50% health or less and player has not assigned any crew to perform maintenance [Text]
|
||||
if ((mechanic == null || mechanic.IsDead) && (engineer == null || engineer.IsDead)) // Both engineer and mechanic are dead or do not exist -> do not display
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool degradedEquipmentFound = false;
|
||||
|
||||
foreach (Item item in Item.ItemList)
|
||||
{
|
||||
if (!item.Repairables.Any() || item.Condition > 50.0f) continue;
|
||||
if (!item.Repairables.Any() || item.ConditionPercentage > 50) continue;
|
||||
degradedEquipmentFound = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (degradedEquipmentFound)
|
||||
{
|
||||
if (HasOrder("repairsystems", "jobspecific"))
|
||||
degrading2ActivationCountdown = 5f;
|
||||
if (HasOrder("repairsystems"))
|
||||
{
|
||||
segments[index].IsTriggered = true;
|
||||
return false;
|
||||
@@ -502,44 +344,43 @@ namespace Barotrauma.Tutorials
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 8: // Medical: Crewmember is injured but not killed [Video]
|
||||
|
||||
if (injuredMember == null)
|
||||
case 8: // Degrading2: 5 seconds after 'Degrading1' dismissed, and only if player has not assigned any crew to perform maintenance [Video]
|
||||
if (degrading2ActivationCountdown == -1f)
|
||||
{
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
return false;
|
||||
}
|
||||
else if (degrading2ActivationCountdown > 0.0f)
|
||||
{
|
||||
degrading2ActivationCountdown -= deltaTime;
|
||||
if (HasOrder("repairsystems"))
|
||||
{
|
||||
Character member = crew[i];
|
||||
if (member.Vitality < member.MaxVitality && !member.IsDead)
|
||||
{
|
||||
injuredMember = member;
|
||||
break;
|
||||
}
|
||||
segments[index].IsTriggered = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (medicalTutorialTimer < medicalTutorialDelay)
|
||||
break;
|
||||
case 9: // Medical: Crewmember is injured but not killed [Video]
|
||||
bool injuredFound = false;
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
medicalTutorialTimer += deltaTime;
|
||||
return false;
|
||||
Character member = crew[i];
|
||||
if (member.Vitality < member.MaxVitality && !member.IsDead)
|
||||
{
|
||||
injuredFound = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TriggerTutorialSegment(index, new string[] { injuredMember.Info.DisplayName,
|
||||
(injuredMember.Info.Gender == Gender.Male) ? TextManager.Get("PronounPossessiveMale").ToLower() : TextManager.Get("PronounPossessiveFemale").ToLower() });
|
||||
return true;
|
||||
}
|
||||
case 9: // Approach1: Destination is within ~100m [Video]
|
||||
|
||||
if (!injuredFound) return false;
|
||||
break;
|
||||
case 10: // Approach1: Destination is within ~100m [Video]
|
||||
if (Vector2.Distance(Submarine.MainSub.WorldPosition, Level.Loaded.EndPosition) > 8000f)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
TriggerTutorialSegment(index, GameMain.GameSession.EndLocation.Name);
|
||||
return true;
|
||||
}
|
||||
case 10: // Approach2: Sub is docked [Text]
|
||||
break;
|
||||
case 11: // Approach2: Sub is docked [Text]
|
||||
if (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0)
|
||||
{
|
||||
return false;
|
||||
@@ -551,128 +392,11 @@ namespace Barotrauma.Tutorials
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool HasObjective(string objectiveName)
|
||||
{
|
||||
for (int i = 0; i < activeObjectives.Count; i++)
|
||||
{
|
||||
if (activeObjectives[i].Id == objectiveName) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void CheckActiveObjectives(TutorialSegment objective, float deltaTime)
|
||||
{
|
||||
switch(objective.Id)
|
||||
{
|
||||
case "ReactorCommand": // Reactor commanded
|
||||
if (!IsReactorPoweredUp())
|
||||
{
|
||||
if (!HasOrder("operatereactor")) return;
|
||||
}
|
||||
break;
|
||||
case "NavConsole": // traveled 50 meters
|
||||
if (Vector2.Distance(subStartingPosition, Submarine.MainSub.WorldPosition) < 4000f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "Flood": // Hull breaches repaired
|
||||
if (IsFlooding()) return;
|
||||
break;
|
||||
case "Medical":
|
||||
if (injuredMember != null && !injuredMember.IsDead)
|
||||
{
|
||||
if (injuredMember.CharacterHealth.DroppedItem == null) return;
|
||||
}
|
||||
break;
|
||||
case "EnemyOnSonar": // Enemy dispatched
|
||||
if (HasEnemyOnSonarForDuration(deltaTime))
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "Degrading": // Fixed
|
||||
if (mechanic != null && !mechanic.IsDead)
|
||||
{
|
||||
HumanAIController humanAI = mechanic.AIController as HumanAIController;
|
||||
if (mechanic.CurrentOrder?.AITag != "repairsystems" || humanAI.CurrentOrderOption != "jobspecific")
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (engineer != null && !engineer.IsDead)
|
||||
{
|
||||
HumanAIController humanAI = engineer.AIController as HumanAIController;
|
||||
if (engineer.CurrentOrder?.AITag != "repairsystems" || humanAI.CurrentOrderOption != "jobspecific")
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case "Approach1": // Wait until docked
|
||||
if (!Submarine.MainSub.AtEndPosition || Submarine.MainSub.DockedTo.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
RemoveCompletedObjective(objective);
|
||||
}
|
||||
|
||||
private bool IsReactorPoweredUp()
|
||||
{
|
||||
float load = 0.0f;
|
||||
List<Connection> connections = reactor.Item.Connections;
|
||||
if (connections != null && connections.Count > 0)
|
||||
{
|
||||
foreach (Connection connection in connections)
|
||||
{
|
||||
if (!connection.IsPower) continue;
|
||||
foreach (Connection recipient in connection.Recipients)
|
||||
{
|
||||
if (!(recipient.Item is Item it)) continue;
|
||||
|
||||
PowerTransfer pt = it.GetComponent<PowerTransfer>();
|
||||
if (pt == null) continue;
|
||||
|
||||
load = Math.Max(load, pt.PowerLoad);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Math.Abs(load + reactor.CurrPowerConsumption) < 10;
|
||||
}
|
||||
|
||||
private Character CrewMemberWithJob(string job)
|
||||
private bool HasOrder(string aiTag)
|
||||
{
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
if (crew[i].Info.Job.Name == job) return crew[i];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool HasOrder(string aiTag, string option = null)
|
||||
{
|
||||
for (int i = 0; i < crew.Count; i++)
|
||||
{
|
||||
if (crew[i].CurrentOrder?.AITag == aiTag)
|
||||
{
|
||||
if (option == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
HumanAIController humanAI = crew[i].AIController as HumanAIController;
|
||||
return humanAI.CurrentOrderOption == option;
|
||||
}
|
||||
}
|
||||
if (crew[i].CurrentOrder?.AITag == aiTag) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -723,51 +447,27 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
}
|
||||
|
||||
return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar && !ct.First.IsDead) != null;
|
||||
return characterTimeOnSonar.Find(ct => ct.Second >= requiredTimeOnSonar) != null;
|
||||
}
|
||||
|
||||
private void TriggerTutorialSegment(int index, params object[] args)
|
||||
{
|
||||
Inventory.draggingItem = null;
|
||||
ContentRunning = true;
|
||||
activeSegment = segments[index];
|
||||
|
||||
string tutorialText = TextManager.GetFormatted(activeSegment.TextContent.GetAttributeString("tag", ""), true, args);
|
||||
string objectiveText = string.Empty;
|
||||
|
||||
if (!string.IsNullOrEmpty(activeSegment.Objective))
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
objectiveText = activeSegment.Objective;
|
||||
}
|
||||
else
|
||||
{
|
||||
objectiveText = string.Format(activeSegment.Objective, args);
|
||||
}
|
||||
|
||||
activeSegment.Objective = objectiveText;
|
||||
}
|
||||
else
|
||||
{
|
||||
activeSegment.IsTriggered = true; // Complete at this stage only if no related objective
|
||||
}
|
||||
activeSegment.IsTriggered = true;
|
||||
|
||||
switch (activeSegment.ContentType)
|
||||
{
|
||||
case ContentTypes.None:
|
||||
break;
|
||||
case ContentTypes.Video:
|
||||
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Id), tutorialText,
|
||||
activeSegment.TextContent.GetAttributeInt("width", 300),
|
||||
activeSegment.TextContent.GetAttributeInt("height", 80),
|
||||
activeSegment.TextContent.GetAttributeString("anchor", "Center"), true, ClosePreTextAndTriggerVideoCallback);
|
||||
spriteSheetPlayer.LoadContent(playableContentPath, activeSegment.Content, activeSegment.Name, true, true, CurrentSegmentStopCallback);
|
||||
break;
|
||||
case ContentTypes.TextOnly:
|
||||
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Id), tutorialText,
|
||||
activeSegment.TextContent.GetAttributeInt("width", 300),
|
||||
activeSegment.TextContent.GetAttributeInt("height", 80),
|
||||
activeSegment.TextContent.GetAttributeString("anchor", "Center"), true, CurrentSegmentStopCallback);
|
||||
case ContentTypes.Text:
|
||||
infoBox = CreateInfoFrame(TextManager.Get(activeSegment.Name), TextManager.GetFormatted(activeSegment.Content.GetAttributeString("tag", ""), false, args),
|
||||
activeSegment.Content.GetAttributeInt("width", 300),
|
||||
activeSegment.Content.GetAttributeInt("height", 80),
|
||||
activeSegment.Content.GetAttributeString("anchor", "Center"), true, CurrentSegmentStopCallback);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -779,13 +479,6 @@ namespace Barotrauma.Tutorials
|
||||
CoroutineManager.StartCoroutine(WaitToStop()); // Completed
|
||||
}
|
||||
|
||||
private void ReplaySegmentVideo(TutorialSegment segment)
|
||||
{
|
||||
if (ContentRunning) return;
|
||||
ContentRunning = true;
|
||||
videoPlayer.LoadContent(playableContentPath, new VideoPlayer.VideoSettings(segment.VideoContent), new VideoPlayer.TextSettings(segment.VideoContent), segment.Id, true, () => ContentRunning = false);
|
||||
}
|
||||
|
||||
private IEnumerable<object> WaitToStop()
|
||||
{
|
||||
while (ContentRunning) yield return null;
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace Barotrauma.Tutorials
|
||||
|
||||
public virtual void AddToGUIUpdateList()
|
||||
{
|
||||
if (infoBox != null) infoBox.AddToGUIUpdateList(order: 100);
|
||||
if (infoBox != null) infoBox.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public virtual void Update(float deltaTime)
|
||||
@@ -194,7 +194,7 @@ namespace Barotrauma.Tutorials
|
||||
if (title.Length > 0)
|
||||
{
|
||||
var titleBlock = new GUITextBlock(new RectTransform(new Vector2(1f, .35f), infoBlock.RectTransform, Anchor.TopCenter,
|
||||
Pivot.TopCenter), title, font: GUI.VideoTitleFont, textAlignment: Alignment.Center, textColor: new Color(253, 174, 0));
|
||||
Pivot.TopCenter), title, font: GUI.LargeFont, textAlignment: Alignment.Center);
|
||||
}
|
||||
|
||||
var textBlock = new GUITextBlock(new RectTransform(new Vector2(0.9f, 1f), infoBlock.RectTransform, Anchor.BottomCenter),
|
||||
|
||||
@@ -127,6 +127,18 @@ namespace Barotrauma.Items.Components
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.03f
|
||||
};
|
||||
autopilotTickBox = new GUITickBox(new RectTransform(new Vector2(0.3f, 0.3f), paddedControlContainer.RectTransform),
|
||||
TextManager.Get("SteeringAutoPilot"), style: "GUIRadioButton")
|
||||
{
|
||||
OnSelected = (GUITickBox box) =>
|
||||
{
|
||||
AutoPilot = box.Selected;
|
||||
if (AutoPilot && MaintainPos)
|
||||
{
|
||||
posToMaintain = controlledSub == null ? item.WorldPosition : controlledSub.WorldPosition;
|
||||
}
|
||||
unsentChanges = true;
|
||||
user = Character.Controlled;
|
||||
|
||||
maintainPosTickBox = new GUITickBox(new RectTransform(new Vector2(0.2f, 0.2f), paddedAutoPilotControls.RectTransform),
|
||||
TextManager.Get("SteeringMaintainPos"), font: GUI.SmallFont)
|
||||
@@ -484,26 +496,14 @@ namespace Barotrauma.Items.Components
|
||||
user = Character.Controlled;
|
||||
}
|
||||
}
|
||||
if (!AutoPilot && Character.DisableControls)
|
||||
if (!AutoPilot && Character.DisableControls && GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
steeringAdjustSpeed = character == null ? 0.2f : MathHelper.Lerp(0.2f, 1.0f, character.GetSkillLevel("helm") / 100.0f);
|
||||
Vector2 input = Vector2.Zero;
|
||||
if (PlayerInput.KeyDown(InputType.Left))
|
||||
{
|
||||
input -= Vector2.UnitX;
|
||||
}
|
||||
if (PlayerInput.KeyDown(InputType.Right))
|
||||
{
|
||||
input += Vector2.UnitX;
|
||||
}
|
||||
if (PlayerInput.KeyDown(InputType.Up))
|
||||
{
|
||||
input += Vector2.UnitY;
|
||||
}
|
||||
if (PlayerInput.KeyDown(InputType.Down))
|
||||
{
|
||||
input -= Vector2.UnitY;
|
||||
}
|
||||
if (PlayerInput.KeyDown(InputType.Left)) { input -= Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Right)) { input += Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Up)) { input += Vector2.UnitY; }
|
||||
if (PlayerInput.KeyDown(InputType.Down)) { input -= Vector2.UnitY; }
|
||||
if (PlayerInput.KeyDown(Keys.LeftShift))
|
||||
{
|
||||
SteeringInput += input * deltaTime * 200;
|
||||
|
||||
@@ -364,15 +364,23 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
if (GUI.KeyboardDispatcher.Subscriber == null)
|
||||
{
|
||||
float moveSpeed = 1000.0f;
|
||||
Vector2 moveAmount = Vector2.Zero;
|
||||
if (PlayerInput.KeyDown(InputType.Left)) { moveAmount += Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Right)) { moveAmount -= Vector2.UnitX; }
|
||||
if (PlayerInput.KeyDown(InputType.Up)) { moveAmount += Vector2.UnitY; }
|
||||
if (PlayerInput.KeyDown(InputType.Down)) { moveAmount -= Vector2.UnitY; }
|
||||
drawOffset += moveAmount * moveSpeed / zoom * deltaTime;
|
||||
}
|
||||
|
||||
if (GUI.MouseOn == mapContainer)
|
||||
{
|
||||
zoom += PlayerInput.ScrollWheelSpeed / 1000.0f;
|
||||
zoom = MathHelper.Clamp(zoom, 1.0f, 4.0f);
|
||||
|
||||
if (PlayerInput.MidButtonHeld())
|
||||
{
|
||||
drawOffset += PlayerInput.MouseSpeed / zoom;
|
||||
}
|
||||
if (PlayerInput.MidButtonHeld()) { drawOffset += PlayerInput.MouseSpeed / zoom; }
|
||||
#if DEBUG
|
||||
if (PlayerInput.DoubleClicked() && highlightedLocation != null)
|
||||
{
|
||||
@@ -551,11 +559,6 @@ namespace Barotrauma
|
||||
null, connectionColor * MathHelper.Clamp(a, 0.1f, 0.5f), MathUtils.VectorToAngle(end - start),
|
||||
new Vector2(0, 16), SpriteEffects.None, 0.01f);
|
||||
}
|
||||
}
|
||||
|
||||
rect.Inflate(8, 8);
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.Black, false, 0.0f, 8);
|
||||
GUI.DrawRectangle(spriteBatch, rect, Color.LightGray);
|
||||
|
||||
if (GameMain.DebugDraw && zoom > 1.0f && generationParams.ShowLevelTypeNames)
|
||||
{
|
||||
|
||||
@@ -292,8 +292,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (damageEffect != null)
|
||||
{
|
||||
float newCutoff = Sections[i].damage > 0 ?
|
||||
MathHelper.Lerp(0.2f, 0.65f, Sections[i].damage / Prefab.Health) : 0.0f;
|
||||
float newCutoff = MathHelper.Lerp(0.0f, 0.65f, Sections[i].damage / Prefab.Health);
|
||||
|
||||
if (Math.Abs(newCutoff - Submarine.DamageEffectCutoff) > 0.01f || color != Submarine.DamageEffectColor)
|
||||
{
|
||||
|
||||
@@ -141,8 +141,23 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (!permissions.HasFlag(ClientPermissions.ManageRound)) return false;
|
||||
RequestRoundEnd();
|
||||
if (!permissions.HasFlag(ClientPermissions.ManageRound)) { return false; }
|
||||
if (!Submarine.MainSub.AtStartPosition && !Submarine.MainSub.AtEndPosition)
|
||||
{
|
||||
var msgBox = new GUIMessageBox("", TextManager.Get("EndRoundSubNotAtLevelEnd"),
|
||||
new string[] { TextManager.Get("Yes"), TextManager.Get("No") });
|
||||
msgBox.Buttons[0].OnClicked = (_, __) =>
|
||||
{
|
||||
GameMain.Client.RequestRoundEnd();
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[0].OnClicked += msgBox.Close;
|
||||
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
||||
}
|
||||
else
|
||||
{
|
||||
RequestRoundEnd();
|
||||
}
|
||||
return true;
|
||||
},
|
||||
Visible = false
|
||||
@@ -1267,6 +1282,75 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadLobbyUpdate(NetIncomingMessage inc)
|
||||
{
|
||||
UInt16 listId = inc.ReadUInt16();
|
||||
List<TempClient> tempClients = new List<TempClient>();
|
||||
int clientCount = inc.ReadByte();
|
||||
for (int i = 0; i < clientCount; i++)
|
||||
{
|
||||
byte id = inc.ReadByte();
|
||||
string name = inc.ReadString();
|
||||
UInt16 characterID = inc.ReadUInt16();
|
||||
bool muted = inc.ReadBoolean();
|
||||
inc.ReadPadBits();
|
||||
|
||||
tempClients.Add(new TempClient
|
||||
{
|
||||
ID = id,
|
||||
Name = name,
|
||||
CharacterID = characterID,
|
||||
Muted = muted
|
||||
});
|
||||
}
|
||||
|
||||
if (NetIdUtils.IdMoreRecent(listId, LastClientListUpdateID))
|
||||
{
|
||||
bool updateClientListId = true;
|
||||
List<Client> currentClients = new List<Client>();
|
||||
foreach (TempClient tc in tempClients)
|
||||
{
|
||||
//see if the client already exists
|
||||
var existingClient = ConnectedClients.Find(c => c.ID == tc.ID && c.Name == tc.Name);
|
||||
if (existingClient == null) //if not, create it
|
||||
{
|
||||
existingClient = new Client(tc.Name, tc.ID)
|
||||
{
|
||||
Muted = tc.Muted
|
||||
};
|
||||
ConnectedClients.Add(existingClient);
|
||||
GameMain.NetLobbyScreen.AddPlayer(existingClient);
|
||||
}
|
||||
existingClient.Character = null;
|
||||
existingClient.Muted = tc.Muted;
|
||||
if (tc.CharacterID > 0)
|
||||
{
|
||||
existingClient.Character = Entity.FindEntityByID(tc.CharacterID) as Character;
|
||||
if (existingClient.Character == null)
|
||||
{
|
||||
updateClientListId = false;
|
||||
}
|
||||
}
|
||||
if (existingClient.ID == myID)
|
||||
{
|
||||
existingClient.SetPermissions(permissions, permittedConsoleCommands);
|
||||
}
|
||||
currentClients.Add(existingClient);
|
||||
}
|
||||
//remove clients that aren't present anymore
|
||||
for (int i = ConnectedClients.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (!currentClients.Contains(ConnectedClients[i]))
|
||||
{
|
||||
GameMain.NetLobbyScreen.RemovePlayer(ConnectedClients[i]);
|
||||
ConnectedClients[i].Dispose();
|
||||
ConnectedClients.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
if (updateClientListId) LastClientListUpdateID = listId;
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadLobbyUpdate(NetIncomingMessage inc)
|
||||
{
|
||||
ServerNetObject objHeader;
|
||||
@@ -1377,114 +1461,6 @@ namespace Barotrauma.Networking
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CLIENT_LIST:
|
||||
ReadClientList(inc);
|
||||
break;
|
||||
case ServerNetObject.CHAT_MESSAGE:
|
||||
ChatMessage.ClientRead(inc);
|
||||
break;
|
||||
|
||||
@@ -64,14 +64,11 @@ namespace Barotrauma
|
||||
|
||||
// New game left side
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), leftColumn.RectTransform), TextManager.Get("SelectedSub") + ":", textAlignment: Alignment.BottomLeft);
|
||||
subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform))
|
||||
{
|
||||
OnSelected = CheckForPax
|
||||
};
|
||||
subList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.65f), leftColumn.RectTransform));
|
||||
|
||||
UpdateSubList(submarines);
|
||||
|
||||
// New game right sideon
|
||||
// New game right side
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), TextManager.Get("SaveName") + ":", textAlignment: Alignment.BottomLeft);
|
||||
saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.1f), rightColumn.RectTransform), string.Empty);
|
||||
|
||||
@@ -271,11 +268,6 @@ namespace Barotrauma
|
||||
saveFiles = SaveUtil.GetSaveFiles(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer);
|
||||
}
|
||||
|
||||
saveList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), loadGameContainer.RectTransform, Anchor.CenterLeft))
|
||||
{
|
||||
OnSelected = SelectSaveFile
|
||||
};
|
||||
|
||||
saveList = new GUIListBox(new RectTransform(new Vector2(0.5f, 1.0f), loadGameContainer.RectTransform, Anchor.CenterLeft))
|
||||
{
|
||||
OnSelected = SelectSaveFile
|
||||
@@ -283,7 +275,9 @@ namespace Barotrauma
|
||||
|
||||
foreach (string saveFile in saveFiles)
|
||||
{
|
||||
XDocument doc = SaveUtil.LoadGameSessionDoc(saveFile);
|
||||
string fileName = saveFile;
|
||||
string subName = "";
|
||||
string saveTime = "";
|
||||
var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform), style: "ListBoxElement")
|
||||
{
|
||||
UserData = saveFile
|
||||
@@ -291,25 +285,38 @@ namespace Barotrauma
|
||||
|
||||
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform),
|
||||
text: Path.GetFileNameWithoutExtension(saveFile));
|
||||
if (doc?.Root == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error loading save file \"" + saveFile + "\". The file may be corrupted.");
|
||||
nameText.Color = Color.Red;
|
||||
continue;
|
||||
}
|
||||
|
||||
string submarineName = doc.Root.GetAttributeString("submarine", "");
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
|
||||
text: submarineName, font: GUI.SmallFont)
|
||||
if (!isMultiplayer)
|
||||
{
|
||||
UserData = saveFile
|
||||
XDocument doc = SaveUtil.LoadGameSessionDoc(saveFile);
|
||||
if (doc?.Root == null)
|
||||
{
|
||||
DebugConsole.ThrowError("Error loading save file \"" + saveFile + "\". The file may be corrupted.");
|
||||
nameText.Color = Color.Red;
|
||||
continue;
|
||||
}
|
||||
subName = doc.Root.GetAttributeString("submarine", "");
|
||||
saveTime = doc.Root.GetAttributeString("savetime", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
string[] splitSaveFile = saveFile.Split(';');
|
||||
saveFrame.UserData = splitSaveFile[0];
|
||||
fileName = nameText.Text = Path.GetFileNameWithoutExtension(splitSaveFile[0]);
|
||||
if (splitSaveFile.Length > 1) { subName = splitSaveFile[1]; }
|
||||
if (splitSaveFile.Length > 2) { saveTime = splitSaveFile[2]; }
|
||||
}
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
|
||||
text: subName, font: GUI.SmallFont)
|
||||
{
|
||||
UserData = fileName
|
||||
};
|
||||
|
||||
string saveTime = doc.Root.GetAttributeString("savetime", "");
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform),
|
||||
text: saveTime, textAlignment: Alignment.Right, font: GUI.SmallFont)
|
||||
{
|
||||
UserData = saveFile
|
||||
UserData = fileName
|
||||
};
|
||||
}
|
||||
|
||||
@@ -358,25 +365,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (isMultiplayer) return;
|
||||
Tutorial contextualTutorial = Tutorial.Tutorials.Find(t => t is ContextualTutorial);
|
||||
|
||||
Submarine selectedSub = subList.SelectedData as Submarine;
|
||||
|
||||
if (selectedSub == null || selectedSub.Name != "PAX")
|
||||
{
|
||||
contextualTutorialBox.Selected = (contextualTutorial != null) ? !GameMain.Config.CompletedTutorialNames.Contains(contextualTutorial.Name) : true;
|
||||
}
|
||||
else
|
||||
{
|
||||
contextualTutorialBox.Selected = true;
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckForPax(GUIComponent component, object obj)
|
||||
{
|
||||
if (!(obj is Submarine) || contextualTutorialBox == null) return false;
|
||||
Submarine sub = obj as Submarine;
|
||||
contextualTutorialBox.Selected = sub.Name == "PAX";
|
||||
return true;
|
||||
contextualTutorialBox.Selected = (contextualTutorial != null) ? !GameMain.Config.CompletedTutorialNames.Contains(contextualTutorial.Name) : true;
|
||||
}
|
||||
|
||||
private bool SelectSaveFile(GUIComponent component, object obj)
|
||||
|
||||
@@ -118,6 +118,19 @@ namespace Barotrauma
|
||||
instance = this;
|
||||
}
|
||||
|
||||
private void Reset()
|
||||
{
|
||||
AnimParams.ForEach(a => a.Reset(true));
|
||||
RagdollParams.Reset(true);
|
||||
RagdollParams.ClearHistory();
|
||||
CurrentAnimation.ClearHistory();
|
||||
if (!character.Removed)
|
||||
{
|
||||
character.Remove();
|
||||
}
|
||||
character = null;
|
||||
}
|
||||
|
||||
public override void Deselect()
|
||||
{
|
||||
base.Deselect();
|
||||
@@ -128,15 +141,7 @@ namespace Barotrauma
|
||||
isEndlessRunner = false;
|
||||
if (character != null)
|
||||
{
|
||||
AnimParams.ForEach(a => a.Reset(true));
|
||||
RagdollParams.Reset(true);
|
||||
RagdollParams.ClearHistory();
|
||||
CurrentAnimation.ClearHistory();
|
||||
if (!character.Removed)
|
||||
{
|
||||
character.Remove();
|
||||
}
|
||||
character = null;
|
||||
Reset();
|
||||
}
|
||||
GameMain.World.ProcessChanges();
|
||||
}
|
||||
@@ -393,6 +398,12 @@ namespace Barotrauma
|
||||
}
|
||||
if (!isFreezed)
|
||||
{
|
||||
if (character.AnimController.Invalid)
|
||||
{
|
||||
Reset();
|
||||
SpawnCharacter(currentCharacterConfig);
|
||||
}
|
||||
|
||||
Submarine.MainSub.SetPrevTransform(Submarine.MainSub.Position);
|
||||
Submarine.MainSub.Update((float)deltaTime);
|
||||
|
||||
@@ -1215,7 +1226,7 @@ namespace Barotrauma
|
||||
Cam.Position = character.WorldPosition;
|
||||
}
|
||||
|
||||
private bool CreateCharacter(string name, bool isHumanoid, params object[] ragdollConfig)
|
||||
private bool CreateCharacter(string name, string mainFolder, bool isHumanoid, params object[] ragdollConfig)
|
||||
{
|
||||
var contentPackage = GameMain.Config.SelectedContentPackages.LastOrDefault();
|
||||
if (contentPackage == null)
|
||||
@@ -1234,17 +1245,16 @@ namespace Barotrauma
|
||||
#endif
|
||||
|
||||
string speciesName = name;
|
||||
string mainFolder = $"Content/Characters/{speciesName}";
|
||||
// Config file
|
||||
string configFilePath = $"{mainFolder}/{speciesName}.xml";
|
||||
string configFilePath = Path.Combine(mainFolder, $"{speciesName}.xml").Replace(@"\", @"/");
|
||||
if (ContentPackage.GetFilesOfType(GameMain.SelectedPackages, ContentType.Character).None(path => path.Contains(speciesName)))
|
||||
{
|
||||
// Create the config file
|
||||
XElement mainElement = new XElement("Character",
|
||||
new XAttribute("name", speciesName),
|
||||
new XAttribute("humanoid", isHumanoid),
|
||||
new XElement("ragdolls"),
|
||||
new XElement("animations"),
|
||||
new XElement("ragdolls", new XAttribute("folder", Path.Combine(mainFolder, $"Ragdolls/").Replace(@"\", @"/"))),
|
||||
new XElement("animations", new XAttribute("folder", Path.Combine(mainFolder, $"Animations/").Replace(@"\", @"/"))),
|
||||
new XElement("health"),
|
||||
new XElement("ai"));
|
||||
XDocument doc = new XDocument(mainElement);
|
||||
@@ -1259,13 +1269,13 @@ namespace Barotrauma
|
||||
DebugConsole.NewMessage(GetCharacterEditorTranslation("ContentPackageSaved").Replace("[path]", contentPackage.Path));
|
||||
}
|
||||
// Ragdoll
|
||||
string ragdollFolder = RagdollParams.GetDefaultFolder(speciesName);
|
||||
string ragdollFolder = RagdollParams.GetFolder(speciesName);
|
||||
string ragdollPath = RagdollParams.GetDefaultFile(speciesName);
|
||||
RagdollParams ragdollParams = isHumanoid
|
||||
? RagdollParams.CreateDefault<HumanRagdollParams>(ragdollPath, speciesName, ragdollConfig)
|
||||
: RagdollParams.CreateDefault<FishRagdollParams>(ragdollPath, speciesName, ragdollConfig) as RagdollParams;
|
||||
// Animations
|
||||
string animFolder = AnimationParams.GetDefaultFolder(speciesName);
|
||||
string animFolder = AnimationParams.GetFolder(speciesName);
|
||||
foreach (AnimationType animType in Enum.GetValues(typeof(AnimationType)))
|
||||
{
|
||||
if (animType != AnimationType.NotDefined)
|
||||
@@ -3918,7 +3928,7 @@ namespace Barotrauma
|
||||
|
||||
private void DrawJointLimitWidgets(SpriteBatch spriteBatch, Limb limb, LimbJoint joint, Vector2 drawPos, bool autoFreeze, bool allowPairEditing, float rotationOffset = 0)
|
||||
{
|
||||
rotationOffset -= MathHelper.ToRadians(RagdollParams.SpritesheetOrientation);
|
||||
rotationOffset += MathHelper.ToRadians(RagdollParams.SpritesheetOrientation);
|
||||
Color angleColor = joint.UpperLimit - joint.LowerLimit > 0 ? Color.LightGreen * 0.5f : Color.Red;
|
||||
DrawRadialWidget(spriteBatch, drawPos, MathHelper.ToDegrees(joint.UpperLimit), $"joint.jointParams.Name {GetCharacterEditorTranslation("UpperLimit")}", Color.Cyan, angle =>
|
||||
{
|
||||
@@ -4652,7 +4662,7 @@ namespace Barotrauma
|
||||
LimbXElements.Values,
|
||||
JointXElements
|
||||
};
|
||||
if (CharacterEditorScreen.instance.CreateCharacter(Name, IsHumanoid, ragdollParams))
|
||||
if (CharacterEditorScreen.instance.CreateCharacter(Name, Path.GetDirectoryName(XMLPath), IsHumanoid, ragdollParams))
|
||||
{
|
||||
GUI.AddMessage(GetCharacterEditorTranslation("CharacterCreated").Replace("[name]", Name), Color.Green, font: GUI.Font);
|
||||
}
|
||||
|
||||
@@ -866,18 +866,21 @@ namespace Barotrauma
|
||||
spectateButton.Enabled = true;
|
||||
}
|
||||
|
||||
public void SetCampaignCharacterInfo(CharacterInfo characterInfo)
|
||||
{
|
||||
if (CampaignCharacterDiscarded) return;
|
||||
|
||||
campaignCharacterInfo = characterInfo;
|
||||
if (campaignCharacterInfo != null)
|
||||
public void SetCampaignCharacterInfo(CharacterInfo newCampaignCharacterInfo)
|
||||
{
|
||||
if (newCampaignCharacterInfo != null)
|
||||
{
|
||||
UpdatePlayerFrame(campaignCharacterInfo, false);
|
||||
if (CampaignCharacterDiscarded) { return; }
|
||||
if (campaignCharacterInfo != newCampaignCharacterInfo)
|
||||
{
|
||||
campaignCharacterInfo = newCampaignCharacterInfo;
|
||||
UpdatePlayerFrame(campaignCharacterInfo, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (campaignCharacterInfo != null)
|
||||
{
|
||||
UpdatePlayerFrame(null, true);
|
||||
campaignCharacterInfo = null;
|
||||
UpdatePlayerFrame(campaignCharacterInfo, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -564,6 +564,9 @@ namespace Barotrauma
|
||||
|
||||
MapEntityPrefab.Selected = null;
|
||||
|
||||
saveFrame = null;
|
||||
loadFrame = null;
|
||||
|
||||
MapEntity.DeselectAll();
|
||||
MapEntity.SelectionGroups.Clear();
|
||||
|
||||
@@ -2040,6 +2043,10 @@ namespace Barotrauma
|
||||
dummyCharacter.SelectedConstruction = null;
|
||||
}
|
||||
}
|
||||
else if (MapEntity.SelectedList.Count == 1)
|
||||
{
|
||||
(MapEntity.SelectedList[0] as Item)?.UpdateHUD(cam, dummyCharacter, (float)deltaTime);
|
||||
}
|
||||
|
||||
CharacterHUD.Update((float)deltaTime, dummyCharacter, cam);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Text;
|
||||
using System.IO.Compression;
|
||||
using System.IO;
|
||||
using Barotrauma.Steam;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace Barotrauma.Networking
|
||||
{
|
||||
@@ -1039,7 +1040,7 @@ namespace Barotrauma.Networking
|
||||
if (command == ClientPermissions.ManageRound && inc.PeekBoolean() &&
|
||||
GameMain.GameSession?.GameMode is MultiPlayerCampaign mpCampaign)
|
||||
{
|
||||
if (!mpCampaign.AllowedToEndRound(sender.Character))
|
||||
if (!mpCampaign.AllowedToEndRound(sender.Character) && !sender.HasPermission(command))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -1125,9 +1126,22 @@ namespace Barotrauma.Networking
|
||||
UInt16 modeIndex = inc.ReadUInt16();
|
||||
if (GameMain.NetLobbyScreen.GameModes[modeIndex].Identifier.ToLowerInvariant() == "multiplayercampaign")
|
||||
{
|
||||
string[] saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer);
|
||||
for (int i = 0; i < saveFiles.Length; i++)
|
||||
{
|
||||
XDocument doc = SaveUtil.LoadGameSessionDoc(saveFiles[i]);
|
||||
if (doc?.Root != null)
|
||||
{
|
||||
saveFiles[i] =
|
||||
string.Join(";",
|
||||
saveFiles[i].Replace(';', ' '),
|
||||
doc.Root.GetAttributeString("submarine", ""),
|
||||
doc.Root.GetAttributeString("savetime", ""));
|
||||
}
|
||||
}
|
||||
|
||||
NetOutgoingMessage msg = server.CreateMessage();
|
||||
msg.Write((byte)ServerPacketHeader.CAMPAIGN_SETUP_INFO);
|
||||
string[] saveFiles = SaveUtil.GetSaveFiles(SaveUtil.SaveType.Multiplayer);
|
||||
msg.Write((UInt16)saveFiles.Count());
|
||||
foreach (string saveFile in saveFiles)
|
||||
{
|
||||
@@ -1212,6 +1226,7 @@ namespace Barotrauma.Networking
|
||||
ClientWriteLobby(c);
|
||||
|
||||
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign &&
|
||||
GameMain.NetLobbyScreen.SelectedMode == campaign.Preset &&
|
||||
NetIdUtils.IdMoreRecent(campaign.LastSaveID, c.LastRecvCampaignSave))
|
||||
{
|
||||
//already sent an up-to-date campaign save
|
||||
@@ -1529,7 +1544,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
var campaign = GameMain.GameSession?.GameMode as MultiPlayerCampaign;
|
||||
if (campaign != null && NetIdUtils.IdMoreRecent(campaign.LastUpdateID, c.LastRecvCampaignUpdate))
|
||||
if (campaign != null && campaign.Preset == GameMain.NetLobbyScreen.SelectedMode &&
|
||||
NetIdUtils.IdMoreRecent(campaign.LastUpdateID, c.LastRecvCampaignUpdate))
|
||||
{
|
||||
outmsg.Write(true);
|
||||
outmsg.WritePadBits();
|
||||
|
||||
@@ -332,7 +332,7 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
}
|
||||
|
||||
if (client.NeedsMidRoundSync)
|
||||
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||
{
|
||||
msg.Write((byte)ServerNetObject.ENTITY_EVENT_INITIAL);
|
||||
msg.Write(client.UnreceivedEntityEventCount);
|
||||
@@ -340,36 +340,13 @@ namespace Barotrauma.Networking
|
||||
|
||||
Write(msg, eventsToSync, out sentEvents, client);
|
||||
}
|
||||
else
|
||||
|
||||
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||
{
|
||||
msg.Write((byte)ServerNetObject.ENTITY_EVENT);
|
||||
Write(msg, eventsToSync, out sentEvents, client);
|
||||
}
|
||||
|
||||
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||
{
|
||||
(entityEvent as ServerEntityEvent).Sent = true;
|
||||
client.EntityEventLastSent[entityEvent.ID] = NetTime.Now;
|
||||
}
|
||||
|
||||
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||
{
|
||||
(entityEvent as ServerEntityEvent).Sent = true;
|
||||
client.EntityEventLastSent[entityEvent.ID] = NetTime.Now;
|
||||
}
|
||||
|
||||
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||
{
|
||||
(entityEvent as ServerEntityEvent).Sent = true;
|
||||
client.EntityEventLastSent[entityEvent.ID] = NetTime.Now;
|
||||
}
|
||||
|
||||
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||
{
|
||||
(entityEvent as ServerEntityEvent).Sent = true;
|
||||
client.EntityEventLastSent[entityEvent.ID] = NetTime.Now;
|
||||
}
|
||||
|
||||
foreach (NetEntityEvent entityEvent in sentEvents)
|
||||
{
|
||||
(entityEvent as ServerEntityEvent).Sent = true;
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
<Character file="Content/Characters/Husk/Husk.xml" />
|
||||
<Character file="Content/Characters/Humanhusk/Humanhusk.xml" />
|
||||
<Character file="Content/Characters/Legacyhusk/Legacyhusk.xml" />
|
||||
<Character file="Content/Characters/Legacycharybdis/Legacycharybdis.xml" />
|
||||
<Character file="Content/Characters/Legacycrawler/Legacycrawler.xml" />
|
||||
<Character file="Content/Characters/Legacymoloch/Legacymoloch.xml" />
|
||||
<Character file="Content/Characters/Mudraptor/Mudraptor.xml" />
|
||||
@@ -70,7 +71,7 @@
|
||||
<Outpost file="Content/Map/Outposts/Outpost.sub" />
|
||||
<Submarine file="Submarines/Orca.sub" />
|
||||
<Submarine file="Submarines/Typhon.sub" />
|
||||
<Submarine file="Submarines/Muikku.sub" />
|
||||
<Submarine file="Submarines/Selkie.sub" />
|
||||
<Submarine file="Submarines/Bunyip.sub" />
|
||||
<Submarine file="Submarines/Humpback.sub" />
|
||||
<Submarine file="Submarines/Dugong.sub" />
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Animations\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Animations\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycrawler\" />
|
||||
<Folder Include="$(MSBuildThisFileDirectory)Content\Characters\Endworm\Animations\" />
|
||||
@@ -45,12 +45,27 @@
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Ragdolls\CarrierDefaultRagdoll.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimFast.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimSlow.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Charybdis.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Charybdis.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Ragdolls\CharybdisDefaultRagdoll.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Legacycharybdis.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Ragdolls\LegacycharybdisDefaultRagdoll.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Coelanth.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -342,33 +357,6 @@
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Effects\waterbump.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\1_CommandReactor\BaroTutorial_CommandReactor.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\2_NavConsole\BaroTutorial_NavConsole.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\3_Flood\BaroTutorial_Flood.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\4_Reactor\BaroTutorial_Reactor.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\5_EnemyOnSonar\BaroTutorial_EnemyOnSonar.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\6_Degrading2\BaroTutorial_Degrading.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\7_Medical\BaroTutorial_Medical.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Tutorials\ContextualTutorial\8_Approach1\BaroTutorial_Approach.mp4">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Fonts\BebasNeue-Regular.otf">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Fonts\NotoSans\LICENSE_OFL.txt">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
@@ -924,13 +912,13 @@
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Carrier\Animations\CarrierSwimSlow.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\charybdis.png">
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\charybdis.png">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimFast.xml">
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Animations\LegacycharybdisSwimFast.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\Animations\CharybdisSwimSlow.xml">
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\Animations\LegacycharybdisSwimSlow.xml">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\Animations\CoelanthSwimFast.xml">
|
||||
@@ -2383,7 +2371,7 @@
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Mudraptor\MUDRAPTOR_idle3.ogg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Charybdis\charybdisattack.ogg">
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Legacycharybdis\charybdisattack.ogg">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Content\Characters\Coelanth\attack1.ogg">
|
||||
@@ -3141,7 +3129,7 @@
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Muikku.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Orca.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
@@ -3161,6 +3149,9 @@
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\RemoraDrone.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Selkie.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="$(MSBuildThisFileDirectory)Submarines\Typhon.sub">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
||||
@@ -288,7 +288,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
var targetingPriority = UpdateTargets(Character);
|
||||
UpdateTargets(Character, out TargetingPriority targetingPriority);
|
||||
updateTargetsTimer = UpdateTargetsInterval;
|
||||
|
||||
if (SelectedAiTarget == null)
|
||||
@@ -472,7 +472,10 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateWallTarget();
|
||||
if (!IsProperlyLatched)
|
||||
{
|
||||
UpdateWallTarget();
|
||||
}
|
||||
raycastTimer = RaycastInterval;
|
||||
}
|
||||
|
||||
@@ -496,6 +499,10 @@ namespace Barotrauma
|
||||
if (wallTarget != null)
|
||||
{
|
||||
attackWorldPos = wallTarget.Position;
|
||||
if (wallTarget.Structure.Submarine != null)
|
||||
{
|
||||
attackWorldPos += wallTarget.Structure.Submarine.Position;
|
||||
}
|
||||
attackSimPos = ConvertUnits.ToSimUnits(attackWorldPos);
|
||||
}
|
||||
else
|
||||
@@ -840,12 +847,7 @@ namespace Barotrauma
|
||||
attachTargetNormal = new Vector2(Math.Sign(WorldPosition.X - wall.WorldPosition.X), 0.0f);
|
||||
sectionPos.X += (wall.BodyWidth <= 0.0f ? wall.Rect.Width : wall.BodyWidth) / 2 * attachTargetNormal.X;
|
||||
}
|
||||
|
||||
latchOntoAI?.SetAttachTarget(wall.Submarine.PhysicsBody.FarseerBody, wall.Submarine, sectionPos, attachTargetNormal);
|
||||
if (wall.Submarine != null)
|
||||
{
|
||||
sectionPos += wall.Submarine.Position;
|
||||
}
|
||||
latchOntoAI?.SetAttachTarget(wall.Submarine.PhysicsBody.FarseerBody, wall.Submarine, ConvertUnits.ToSimUnits(sectionPos), attachTargetNormal);
|
||||
wallTarget = new WallTarget(sectionPos, wall, sectionIndex);
|
||||
}
|
||||
}
|
||||
@@ -978,10 +980,17 @@ namespace Barotrauma
|
||||
//goes through all the AItargets, evaluates how preferable it is to attack the target,
|
||||
//whether the Character can see/hear the target and chooses the most preferable target within
|
||||
//sight/hearing range
|
||||
public TargetingPriority UpdateTargets(Character character)
|
||||
public AITarget UpdateTargets(Character character, out TargetingPriority priority)
|
||||
{
|
||||
if (IsProperlyLatched)
|
||||
{
|
||||
// If attached to a valid target, just keep the target.
|
||||
// Priority not used in this case.
|
||||
priority = null;
|
||||
return SelectedAiTarget;
|
||||
}
|
||||
AITarget newTarget = null;
|
||||
TargetingPriority targetingPriority = null;
|
||||
priority = null;
|
||||
selectedTargetMemory = null;
|
||||
targetValue = 0.0f;
|
||||
|
||||
@@ -1180,7 +1189,7 @@ namespace Barotrauma
|
||||
{
|
||||
newTarget = target;
|
||||
selectedTargetMemory = targetMemory;
|
||||
targetingPriority = targetingPriorities[targetingTag];
|
||||
priority = targetingPriorities[targetingTag];
|
||||
targetValue = valueModifier;
|
||||
}
|
||||
}
|
||||
@@ -1190,7 +1199,7 @@ namespace Barotrauma
|
||||
{
|
||||
wallTarget = null;
|
||||
}
|
||||
return targetingPriority;
|
||||
return SelectedAiTarget;
|
||||
}
|
||||
|
||||
private AITargetMemory GetTargetMemory(AITarget target)
|
||||
|
||||
@@ -193,7 +193,7 @@ namespace Barotrauma
|
||||
// is not attached or is attached to something else
|
||||
if (!IsAttached || IsAttached && attachJoints[0].BodyB == attachTargetBody)
|
||||
{
|
||||
if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.Range * enemyAI.AttackingLimb.attack.Range)
|
||||
if (Vector2.DistanceSquared(ConvertUnits.ToDisplayUnits(transformedAttachPos), enemyAI.AttackingLimb.WorldPosition) < enemyAI.AttackingLimb.attack.DamageRange * enemyAI.AttackingLimb.attack.DamageRange)
|
||||
{
|
||||
AttachToBody(character.AnimController.Collider, attachLimb, attachTargetBody, transformedAttachPos);
|
||||
}
|
||||
|
||||
@@ -369,7 +369,16 @@ namespace Barotrauma
|
||||
|
||||
float movementAngle = MathUtils.VectorToAngle(movement) - MathHelper.PiOver2;
|
||||
|
||||
float mainLimbAngle = (MainLimb.type == LimbType.Torso ? TorsoAngle.Value : HeadAngle.Value) * Dir;
|
||||
float mainLimbAngle = 0;
|
||||
if (MainLimb.type == LimbType.Torso && TorsoAngle.HasValue)
|
||||
{
|
||||
mainLimbAngle = TorsoAngle.Value;
|
||||
}
|
||||
else if (MainLimb.type == LimbType.Head && HeadAngle.HasValue)
|
||||
{
|
||||
mainLimbAngle = HeadAngle.Value;
|
||||
}
|
||||
mainLimbAngle *= Dir;
|
||||
while (MainLimb.Rotation - (movementAngle + mainLimbAngle) > MathHelper.Pi)
|
||||
{
|
||||
movementAngle += MathHelper.TwoPi;
|
||||
@@ -408,7 +417,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
while (MainLimb.Rotation - (movementAngle + mainLimbAngle) < -MathHelper.Pi)
|
||||
else
|
||||
{
|
||||
movementAngle = Dir > 0 ? -MathHelper.PiOver2 : MathHelper.PiOver2;
|
||||
if (MainLimb.type == LimbType.Head && HeadAngle.HasValue)
|
||||
@@ -683,12 +692,6 @@ namespace Barotrauma
|
||||
|
||||
limb.body.ApplyForce(diff * (float)(Math.Sin(WalkPos) * Math.Sqrt(limb.Mass)) * 30.0f * animStrength);
|
||||
}
|
||||
while (referenceLimb.Rotation - angle < -MathHelper.TwoPi)
|
||||
{
|
||||
angle -= MathHelper.TwoPi;
|
||||
}
|
||||
|
||||
limb?.body.SmoothRotate(angle, torque, wrapAngle: false);
|
||||
}
|
||||
|
||||
private void SmoothRotateWithoutWrapping(Limb limb, float angle, Limb referenceLimb, float torque)
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Barotrauma
|
||||
public static string GetDefaultFolder(string speciesName) => $"Content/Characters/{speciesName.CapitaliseFirstInvariant()}/Animations/";
|
||||
public static string GetDefaultFile(string speciesName, AnimationType animType) => $"{GetFolder(speciesName)}{GetDefaultFileName(speciesName, animType)}.xml";
|
||||
|
||||
protected static string GetFolder(string speciesName)
|
||||
public static string GetFolder(string speciesName)
|
||||
{
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("animations")?.GetAttributeString("folder", string.Empty);
|
||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace Barotrauma
|
||||
new XAttribute("sourcerect", $"0, 0, 1, 1")))
|
||||
};
|
||||
|
||||
protected static string GetFolder(string speciesName)
|
||||
public static string GetFolder(string speciesName)
|
||||
{
|
||||
var folder = XMLExtensions.TryLoadXml(Character.GetConfigFile(speciesName))?.Root?.Element("ragdolls")?.GetAttributeString("folder", string.Empty);
|
||||
if (string.IsNullOrEmpty(folder) || folder.ToLowerInvariant() == "default")
|
||||
|
||||
@@ -1035,78 +1035,6 @@ namespace Barotrauma
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
CheckValidity();
|
||||
|
||||
UpdateNetPlayerPosition(deltaTime);
|
||||
CheckDistFromCollider();
|
||||
UpdateCollisionCategories();
|
||||
@@ -1367,17 +1295,42 @@ namespace Barotrauma
|
||||
UpdateProjSpecific(deltaTime);
|
||||
}
|
||||
|
||||
private void CheckValidity()
|
||||
public bool Invalid { get; private set; }
|
||||
private int validityResets;
|
||||
private bool CheckValidity()
|
||||
{
|
||||
CheckValidity(Collider);
|
||||
bool isColliderValid = CheckValidity(Collider);
|
||||
bool limbsValid = true;
|
||||
foreach (Limb limb in limbs)
|
||||
{
|
||||
if (limb.body == null || !limb.body.Enabled) { continue; }
|
||||
CheckValidity(limb.body);
|
||||
if (!CheckValidity(limb.body))
|
||||
{
|
||||
limbsValid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool isValid = isColliderValid && limbsValid;
|
||||
if (!isValid)
|
||||
{
|
||||
validityResets++;
|
||||
if (validityResets > 1)
|
||||
{
|
||||
Invalid = true;
|
||||
DebugConsole.ThrowError("Invalid ragdoll physics. Ragdoll freezed to prevent crashes.");
|
||||
Collider.SetTransform(Vector2.Zero, 0.0f);
|
||||
foreach (Limb limb in Limbs)
|
||||
{
|
||||
limb.body.SetTransform(Collider.SimPosition, 0.0f);
|
||||
limb.body.ResetDynamics();
|
||||
}
|
||||
Frozen = true;
|
||||
}
|
||||
}
|
||||
return isValid;
|
||||
}
|
||||
|
||||
private void CheckValidity(PhysicsBody body)
|
||||
private bool CheckValidity(PhysicsBody body)
|
||||
{
|
||||
string errorMsg = null;
|
||||
string bodyName = body.UserData is Limb ? "Limb" : "Collider";
|
||||
@@ -1429,9 +1382,9 @@ namespace Barotrauma
|
||||
limb.body.ResetDynamics();
|
||||
}
|
||||
SetInitialLimbPositions();
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
UpdateProjSpecific(deltaTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
partial void UpdateProjSpecific(float deltaTime);
|
||||
|
||||
@@ -808,6 +808,7 @@ namespace Barotrauma
|
||||
|
||||
public void LoadHeadAttachments()
|
||||
{
|
||||
if (Info == null) { return; }
|
||||
if (AnimController == null) { return; }
|
||||
var head = AnimController.GetLimb(LimbType.Head);
|
||||
if (head == null) { return; }
|
||||
|
||||
@@ -804,6 +804,11 @@ namespace Barotrauma
|
||||
var newItem = Item.Load(itemElement, inventory.Owner.Submarine, createNetworkEvent: true);
|
||||
if (newItem == null) { continue; }
|
||||
|
||||
if (!MathUtils.NearlyEqual(newItem.Condition, newItem.MaxCondition))
|
||||
{
|
||||
GameMain.NetworkMember.CreateEntityEvent(newItem, new object[] { NetEntityEvent.Type.Status });
|
||||
}
|
||||
|
||||
int[] slotIndices = itemElement.GetAttributeIntArray("i", new int[] { 0 });
|
||||
if (!slotIndices.Any())
|
||||
{
|
||||
|
||||
@@ -528,7 +528,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the attack is aimed to a character but hits a structure, the hit is blocked.
|
||||
// If there is nothing between, the hit is successful
|
||||
wasHit = structureBody == null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,8 +118,13 @@ namespace Barotrauma
|
||||
{
|
||||
allowedMissions.RemoveAll(m => !m.IsAllowed(locations[0], locations[1]));
|
||||
}
|
||||
|
||||
if (allowedMissions.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int probabilitySum = allowedMissions.Sum(m => m.Commonness);
|
||||
int probabilitySum = allowedMissions.Sum(m => m.Commonness);
|
||||
int randomNumber = rand.NextInt32() % probabilitySum;
|
||||
foreach (MissionPrefab missionPrefab in allowedMissions)
|
||||
{
|
||||
|
||||
@@ -534,7 +534,6 @@ namespace Barotrauma.Items.Components
|
||||
GameAnalyticsManager.AddErrorEventOnce("ItemComponent.DegreeOfSuccess:CharacterNull", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg);
|
||||
return 0.0f;
|
||||
}
|
||||
float average = skillSuccessSum / requiredSkills.Count;
|
||||
|
||||
float skillSuccessSum = 0.0f;
|
||||
for (int i = 0; i < requiredSkills.Count; i++)
|
||||
|
||||
@@ -153,7 +153,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (!pt.IsActive) { continue; }
|
||||
if (!pt.IsActive || !pt.CanTransfer) { continue; }
|
||||
|
||||
gridLoad += pt.PowerLoad;
|
||||
gridPower -= pt.CurrPowerConsumption;
|
||||
@@ -209,9 +209,9 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
Charge -= CurrPowerOutput / 3600.0f;
|
||||
}
|
||||
item.SendSignal(0, Charge.ToString(), "charge", null);
|
||||
item.SendSignal(0, ((Charge / capacity) * 100).ToString(), "charge_%", null);
|
||||
item.SendSignal(0, ((RechargeSpeed / maxRechargeSpeed) * 100).ToString(), "charge_rate", null);
|
||||
item.SendSignal(0, ((int)Charge).ToString(), "charge", null);
|
||||
item.SendSignal(0, ((int)((Charge / capacity) * 100)).ToString(), "charge_%", null);
|
||||
item.SendSignal(0, ((int)((RechargeSpeed / maxRechargeSpeed) * 100)).ToString(), "charge_rate", null);
|
||||
|
||||
foreach (Pair<Powered, Connection> connected in directlyConnected)
|
||||
{
|
||||
|
||||
@@ -319,7 +319,13 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
ApplyStatusEffects(ActionType.OnActive, deltaTime, null);
|
||||
|
||||
float maxPower = this is RelayComponent relayComponent ? relayComponent.MaxPower : float.PositiveInfinity;
|
||||
//float maxPower = this is RelayComponent relayComponent ? relayComponent.MaxPower : float.PositiveInfinity;
|
||||
RelayComponent thisRelayComponent = this as RelayComponent;
|
||||
if (thisRelayComponent != null)
|
||||
{
|
||||
clampPower = Math.Min(Math.Min(clampPower, thisRelayComponent.MaxPower), powerLoad);
|
||||
clampLoad = Math.Min(clampLoad, thisRelayComponent.MaxPower);
|
||||
}
|
||||
|
||||
foreach (Connection c in PowerConnections)
|
||||
{
|
||||
@@ -357,6 +363,8 @@ namespace Barotrauma.Items.Components
|
||||
continue;
|
||||
}
|
||||
|
||||
float addLoad = 0.0f;
|
||||
float addPower = 0.0f;
|
||||
if (powered is PowerContainer powerContainer)
|
||||
{
|
||||
if (recipient.Name == "power_in")
|
||||
@@ -365,7 +373,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
else
|
||||
{
|
||||
fullPower += Math.Min(powerContainer.CurrPowerOutput, maxPower);
|
||||
addPower = powerContainer.CurrPowerOutput;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -380,10 +388,16 @@ namespace Barotrauma.Items.Components
|
||||
//negative power consumption = the construction is a
|
||||
//generator/battery or another junction box
|
||||
{
|
||||
fullPower -= Math.Max(powered.CurrPowerConsumption, -maxPower);
|
||||
addPower -= powered.CurrPowerConsumption;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (addPower + fullPower > clampPower) { addPower -= (addPower + fullPower) - clampPower; };
|
||||
if (addPower > 0) { fullPower += addPower; }
|
||||
|
||||
if (addLoad + fullLoad > clampLoad) { addLoad -= (addLoad + fullLoad) - clampLoad; };
|
||||
if (addLoad > 0) { fullLoad += addLoad; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,10 @@ namespace Barotrauma
|
||||
|
||||
public Explosion(float range, float force, float damage, float structureDamage, float empStrength = 0.0f)
|
||||
{
|
||||
attack = new Attack(damage, 0.0f, 0.0f, structureDamage, range);
|
||||
attack.SeverLimbsProbability = 1.0f;
|
||||
attack = new Attack(damage, 0.0f, 0.0f, structureDamage, range)
|
||||
{
|
||||
SeverLimbsProbability = 1.0f
|
||||
};
|
||||
this.force = force;
|
||||
this.empStrength = empStrength;
|
||||
sparks = true;
|
||||
@@ -183,114 +185,6 @@ namespace Barotrauma
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
Hull hull = Hull.FindHull(ConvertUnits.ToDisplayUnits(explosionPos), null, false);
|
||||
bool underWater = hull == null || explosionPos.Y < hull.Surface;
|
||||
|
||||
explosionPos = ConvertUnits.ToSimUnits(explosionPos);
|
||||
|
||||
Dictionary<Limb, float> distFactors = new Dictionary<Limb, float>();
|
||||
|
||||
@@ -323,7 +323,7 @@ namespace Barotrauma
|
||||
for (int i = 0; i <= maxLoadRetries; i++)
|
||||
{
|
||||
doc = OpenFile(filePath);
|
||||
if (doc != null || i == maxLoadRetries) { break; }
|
||||
if (doc != null || i == maxLoadRetries || !File.Exists(filePath)) { break; }
|
||||
DebugConsole.NewMessage("Opening submarine file \"" + filePath + "\" failed, retrying in 250 ms...");
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
@@ -1192,7 +1192,7 @@ namespace Barotrauma
|
||||
for (int i = 0; i <= maxLoadRetries; i++)
|
||||
{
|
||||
doc = OpenFile(filePath);
|
||||
if (doc != null || i == maxLoadRetries) { break; }
|
||||
if (doc != null || i == maxLoadRetries || !File.Exists(filePath)) { break; }
|
||||
DebugConsole.NewMessage("Loading the submarine \"" + Name + "\" failed, retrying in 250 ms...");
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
|
||||
@@ -358,8 +358,8 @@ namespace Barotrauma
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
if (i >= maxRetries) { throw; }
|
||||
DebugConsole.NewMessage("Failed to initiate a file transfer {" + e.Message + "}, retrying in 250 ms...", Color.Red);
|
||||
if (i >= maxRetries || !File.Exists(sCompressedFile)) { throw; }
|
||||
DebugConsole.NewMessage("Failed decompress file \"" + sCompressedFile + "\" {" + e.Message + "}, retrying in 250 ms...", Color.Red);
|
||||
Thread.Sleep(250);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user