Unstable v0.1300.0.1
This commit is contained in:
@@ -257,7 +257,7 @@ namespace Barotrauma
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Freeze { get; set; }
|
public bool Freeze { get; set; }
|
||||||
|
|
||||||
public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true)
|
public void MoveCamera(float deltaTime, bool allowMove = true, bool allowZoom = true, Rectangle? overrideMouseOn = null)
|
||||||
{
|
{
|
||||||
prevPosition = position;
|
prevPosition = position;
|
||||||
prevZoom = zoom;
|
prevZoom = zoom;
|
||||||
@@ -294,7 +294,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allowZoom && GUI.MouseOn == null)
|
if (allowZoom && (GUI.MouseOn == null || (overrideMouseOn?.Contains(PlayerInput.MousePosition) ?? false)))
|
||||||
{
|
{
|
||||||
Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
|
Vector2 mouseInWorld = ScreenToWorld(PlayerInput.MousePosition);
|
||||||
Vector2 diffViewCenter;
|
Vector2 diffViewCenter;
|
||||||
|
|||||||
@@ -529,6 +529,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ushort infoID = inc.ReadUInt16();
|
ushort infoID = inc.ReadUInt16();
|
||||||
string newName = inc.ReadString();
|
string newName = inc.ReadString();
|
||||||
|
string originalName = inc.ReadString();
|
||||||
int gender = inc.ReadByte();
|
int gender = inc.ReadByte();
|
||||||
int race = inc.ReadByte();
|
int race = inc.ReadByte();
|
||||||
int headSpriteID = inc.ReadByte();
|
int headSpriteID = inc.ReadByte();
|
||||||
@@ -556,7 +557,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: animations
|
// TODO: animations
|
||||||
CharacterInfo ch = new CharacterInfo(speciesName, newName, jobPrefab, ragdollFile, variant)
|
CharacterInfo ch = new CharacterInfo(speciesName, newName, originalName, jobPrefab, ragdollFile, variant)
|
||||||
{
|
{
|
||||||
ID = infoID,
|
ID = infoID,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -240,6 +240,8 @@ namespace Barotrauma
|
|||||||
Character.Controlled.SelectedConstruction = null;
|
Character.Controlled.SelectedConstruction = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HintManager.OnShowHealthInterface();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -718,6 +720,7 @@ namespace Barotrauma
|
|||||||
int dmgPerSecond = Math.Sign(a2.DamagePerSecond - a1.DamagePerSecond);
|
int dmgPerSecond = Math.Sign(a2.DamagePerSecond - a1.DamagePerSecond);
|
||||||
return dmgPerSecond != 0 ? dmgPerSecond : Math.Sign(a1.Strength - a1.Strength);
|
return dmgPerSecond != 0 ? dmgPerSecond : Math.Sign(a1.Strength - a1.Strength);
|
||||||
});
|
});
|
||||||
|
HintManager.OnAfflictionDisplayed(Character, currentDisplayedAfflictions.FirstOrDefault());
|
||||||
updateDisplayedAfflictionsTimer = UpdateDisplayedAfflictionsInterval;
|
updateDisplayedAfflictionsTimer = UpdateDisplayedAfflictionsInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1188,7 +1191,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Color GetAfflictionIconColor(AfflictionPrefab prefab, Affliction affliction)
|
public static Color GetAfflictionIconColor(AfflictionPrefab prefab, Affliction affliction)
|
||||||
{
|
{
|
||||||
// No specific colors, use generic
|
// No specific colors, use generic
|
||||||
if (prefab.IconColors == null)
|
if (prefab.IconColors == null)
|
||||||
@@ -1208,6 +1211,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Color GetAfflictionIconColor(Affliction affliction) => GetAfflictionIconColor(affliction.Prefab, affliction);
|
||||||
|
|
||||||
private void UpdateAfflictionContainer(LimbHealth selectedLimb)
|
private void UpdateAfflictionContainer(LimbHealth selectedLimb)
|
||||||
{
|
{
|
||||||
selectedLimbText.Text = selectedLimb == null ? "" : selectedLimb.Name;
|
selectedLimbText.Text = selectedLimb == null ? "" : selectedLimb.Name;
|
||||||
@@ -1275,7 +1280,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
var afflictionIcon = new GUIImage(new RectTransform(Vector2.One * 0.8f, button.RectTransform, Anchor.Center), affliction.Prefab.Icon, scaleToFit: true)
|
var afflictionIcon = new GUIImage(new RectTransform(Vector2.One * 0.8f, button.RectTransform, Anchor.Center), affliction.Prefab.Icon, scaleToFit: true)
|
||||||
{
|
{
|
||||||
Color = GetAfflictionIconColor(affliction.Prefab, affliction),
|
Color = GetAfflictionIconColor(affliction),
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
afflictionIcon.PressedColor = afflictionIcon.Color;
|
afflictionIcon.PressedColor = afflictionIcon.Color;
|
||||||
@@ -1911,7 +1916,7 @@ namespace Barotrauma
|
|||||||
float alpha = MathHelper.Lerp(0.3f, 1.0f,
|
float alpha = MathHelper.Lerp(0.3f, 1.0f,
|
||||||
(affliction.Strength - showIconThreshold) / Math.Min(affliction.Prefab.MaxStrength - showIconThreshold, 10.0f));
|
(affliction.Strength - showIconThreshold) / Math.Min(affliction.Prefab.MaxStrength - showIconThreshold, 10.0f));
|
||||||
|
|
||||||
affliction.Prefab.Icon.Draw(spriteBatch, iconPos - iconSize / 2.0f, GetAfflictionIconColor(affliction.Prefab, affliction) * alpha, 0, iconScale);
|
affliction.Prefab.Icon.Draw(spriteBatch, iconPos - iconSize / 2.0f, GetAfflictionIconColor(affliction) * alpha, 0, iconScale);
|
||||||
iconPos += new Vector2(10.0f, 20.0f) * iconScale;
|
iconPos += new Vector2(10.0f, 20.0f) * iconScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1534,7 +1534,9 @@ namespace Barotrauma
|
|||||||
List<string> lines = missingTags.Select(t => "\"" + t.Key + "\"\n missing from " + string.Join(", ", t.Value)).ToList();
|
List<string> lines = missingTags.Select(t => "\"" + t.Key + "\"\n missing from " + string.Join(", ", t.Value)).ToList();
|
||||||
|
|
||||||
string filePath = "missingloca.txt";
|
string filePath = "missingloca.txt";
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
File.WriteAllLines(filePath, lines);
|
File.WriteAllLines(filePath, lines);
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||||
TextManager.Language = "English";
|
TextManager.Language = "English";
|
||||||
}));
|
}));
|
||||||
@@ -1543,7 +1545,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
var debugLines = EventSet.GetDebugStatistics();
|
var debugLines = EventSet.GetDebugStatistics();
|
||||||
string filePath = "eventstats.txt";
|
string filePath = "eventstats.txt";
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
File.WriteAllLines(filePath, debugLines);
|
File.WriteAllLines(filePath, debugLines);
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -1824,7 +1828,9 @@ namespace Barotrauma
|
|||||||
lines.Add("<EntityName." + me.Identifier + ">" + me.Name + "</EntityName." + me.Identifier + ">");
|
lines.Add("<EntityName." + me.Identifier + ">" + me.Name + "</EntityName." + me.Identifier + ">");
|
||||||
lines.Add("<EntityDescription." + me.Identifier + ">" + me.Description + "</EntityDescription." + me.Identifier + ">");
|
lines.Add("<EntityDescription." + me.Identifier + ">" + me.Description + "</EntityDescription." + me.Identifier + ">");
|
||||||
}
|
}
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
File.WriteAllLines(filePath, lines);
|
File.WriteAllLines(filePath, lines);
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("dumpeventtexts", "dumpeventtexts [filepath]: gets the texts from event files and 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/EventTexts.txt", (string[] args) =>
|
commands.Add(new Command("dumpeventtexts", "dumpeventtexts [filepath]: gets the texts from event files and 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/EventTexts.txt", (string[] args) =>
|
||||||
@@ -1843,16 +1849,15 @@ namespace Barotrauma
|
|||||||
docs.Add(eventPrefab.ConfigElement.Document);
|
docs.Add(eventPrefab.ConfigElement.Document);
|
||||||
getTextsFromElement(eventPrefab.ConfigElement, lines, eventPrefab.Identifier);
|
getTextsFromElement(eventPrefab.ConfigElement, lines, eventPrefab.Identifier);
|
||||||
}
|
}
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
File.WriteAllLines(filePath, lines);
|
File.WriteAllLines(filePath, lines);
|
||||||
|
|
||||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||||
|
|
||||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
||||||
{
|
{
|
||||||
Indent = true,
|
Indent = true,
|
||||||
NewLineOnAttributes = false
|
NewLineOnAttributes = false
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (XDocument doc in docs)
|
foreach (XDocument doc in docs)
|
||||||
{
|
{
|
||||||
using (var writer = XmlWriter.Create(new System.Uri(doc.BaseUri).LocalPath, settings))
|
using (var writer = XmlWriter.Create(new System.Uri(doc.BaseUri).LocalPath, settings))
|
||||||
@@ -1861,6 +1866,7 @@ namespace Barotrauma
|
|||||||
writer.Flush();
|
writer.Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
|
|
||||||
void getTextsFromElement(XElement element, List<string> list, string parentName)
|
void getTextsFromElement(XElement element, List<string> list, string parentName)
|
||||||
{
|
{
|
||||||
@@ -2007,7 +2013,9 @@ namespace Barotrauma
|
|||||||
lines.Add("[/table]");
|
lines.Add("[/table]");
|
||||||
lines.Add("");
|
lines.Add("");
|
||||||
}
|
}
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
File.WriteAllLines(filePath, lines);
|
File.WriteAllLines(filePath, lines);
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||||
}));
|
}));
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
@@ -2049,7 +2057,9 @@ namespace Barotrauma
|
|||||||
commands.Add(new Command("printproperties", "Goes through the currently collected property list for missing localizations and writes them to a file.", (string[] args) =>
|
commands.Add(new Command("printproperties", "Goes through the currently collected property list for missing localizations and writes them to a file.", (string[] args) =>
|
||||||
{
|
{
|
||||||
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\propertylocalization.txt";
|
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\propertylocalization.txt";
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
File.WriteAllLines(path, SerializableEntityEditor.MissingLocalizations);
|
File.WriteAllLines(path, SerializableEntityEditor.MissingLocalizations);
|
||||||
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
commands.Add(new Command("getproperties", "Goes through the MapEntity prefabs and checks their serializable properties for localization issues.", (string[] args) =>
|
commands.Add(new Command("getproperties", "Goes through the MapEntity prefabs and checks their serializable properties for localization issues.", (string[] args) =>
|
||||||
|
|||||||
@@ -560,6 +560,22 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case NetworkEventType.UNLOCKPATH:
|
||||||
|
UInt16 connectionIndex = msg.ReadUInt16();
|
||||||
|
if (GameMain.GameSession?.Map?.Connections != null)
|
||||||
|
{
|
||||||
|
if (connectionIndex >= GameMain.GameSession.Map.Connections.Count)
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Failed to unlock a path on the campaign map. Connection index out of bounds (index: {connectionIndex}, number of connections: {GameMain.GameSession.Map.Connections.Count})");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GameMain.GameSession.Map.Connections[connectionIndex].Locked = false;
|
||||||
|
new GUIMessageBox(string.Empty, TextManager.Get("pathunlockedgeneric"),
|
||||||
|
new string[0], type: GUIMessageBox.Type.InGame, iconStyle: "UnlockPathIcon", relativeSize: new Vector2(0.3f, 0.15f), minSize: new Point(512, 128));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-1
@@ -10,7 +10,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
for (int i = 0; i < characterCount; i++)
|
for (int i = 0; i < characterCount; i++)
|
||||||
{
|
{
|
||||||
characters.Add(Character.ReadSpawnData(msg));
|
Character character = Character.ReadSpawnData(msg);
|
||||||
|
characters.Add(character);
|
||||||
|
if (msg.ReadBoolean()) { requireKill.Add(character); }
|
||||||
|
if (msg.ReadBoolean())
|
||||||
|
{
|
||||||
|
requireRescue.Add(character);
|
||||||
|
#if CLIENT
|
||||||
|
GameMain.GameSession.CrewManager.AddCharacterToCrewList(character);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
ushort itemCount = msg.ReadUInt16();
|
ushort itemCount = msg.ReadUInt16();
|
||||||
for (int j = 0; j < itemCount; j++)
|
for (int j = 0; j < itemCount; j++)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
yield return new WaitForSeconds(1.0f);
|
yield return new WaitForSeconds(1.0f);
|
||||||
}
|
}
|
||||||
new GUIMessageBox(header, message, buttons: new string[0], type: GUIMessageBox.Type.InGame, icon: Prefab.Icon)
|
new GUIMessageBox(header, message, buttons: new string[0], type: GUIMessageBox.Type.InGame, icon: Prefab.Icon, parseRichText: true)
|
||||||
{
|
{
|
||||||
IconColor = Prefab.IconColor
|
IconColor = Prefab.IconColor
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
{
|
{
|
||||||
foreach (Mission mission in missions)
|
foreach (Mission mission in missions)
|
||||||
{
|
{
|
||||||
new GUIMessageBox(mission.Name, mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon)
|
new GUIMessageBox(mission.Name, mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon, parseRichText: true)
|
||||||
{
|
{
|
||||||
IconColor = mission.Prefab.IconColor,
|
IconColor = mission.Prefab.IconColor,
|
||||||
UserData = "missionstartmessage"
|
UserData = "missionstartmessage"
|
||||||
|
|||||||
@@ -422,12 +422,12 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, List<RichTextData> richTextData)
|
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, float scale, SpriteEffects se, float layerDepth, List<RichTextData> richTextData, int rtdOffset = 0)
|
||||||
{
|
{
|
||||||
DrawStringWithColors(sb, text, position, color, rotation, origin, new Vector2(scale), se, layerDepth, richTextData);
|
DrawStringWithColors(sb, text, position, color, rotation, origin, new Vector2(scale), se, layerDepth, richTextData, rtdOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth, List<RichTextData> richTextData)
|
public void DrawStringWithColors(SpriteBatch sb, string text, Vector2 position, Color color, float rotation, Vector2 origin, Vector2 scale, SpriteEffects se, float layerDepth, List<RichTextData> richTextData, int rtdOffset = 0)
|
||||||
{
|
{
|
||||||
if (textures.Count == 0 && !DynamicLoading) { return; }
|
if (textures.Count == 0 && !DynamicLoading) { return; }
|
||||||
|
|
||||||
@@ -457,13 +457,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
Color currentTextColor;
|
Color currentTextColor;
|
||||||
|
|
||||||
if (currentRichTextData != null && i > currentRichTextData.EndIndex + lineNum)
|
while (currentRichTextData != null && i + rtdOffset > currentRichTextData.EndIndex + lineNum)
|
||||||
{
|
{
|
||||||
richTextDataIndex++;
|
richTextDataIndex++;
|
||||||
currentRichTextData = richTextDataIndex < richTextData.Count ? richTextData[richTextDataIndex] : null;
|
currentRichTextData = richTextDataIndex < richTextData.Count ? richTextData[richTextDataIndex] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentRichTextData != null && currentRichTextData.StartIndex + lineNum <= i && i <= currentRichTextData.EndIndex + lineNum)
|
if (currentRichTextData != null && currentRichTextData.StartIndex + lineNum <= i + rtdOffset && i + rtdOffset <= currentRichTextData.EndIndex + lineNum)
|
||||||
{
|
{
|
||||||
currentTextColor = currentRichTextData.Color ?? color;
|
currentTextColor = currentRichTextData.Color ?? color;
|
||||||
if (!string.IsNullOrEmpty(currentRichTextData.Metadata))
|
if (!string.IsNullOrEmpty(currentRichTextData.Metadata))
|
||||||
|
|||||||
@@ -321,6 +321,10 @@ namespace Barotrauma
|
|||||||
float prevSize = chatBox.BarSize;
|
float prevSize = chatBox.BarSize;
|
||||||
|
|
||||||
string displayedText = message.TranslatedText;
|
string displayedText = message.TranslatedText;
|
||||||
|
if (message.Type == ChatMessageType.Server)
|
||||||
|
{
|
||||||
|
RichTextData.GetRichTextData(displayedText, out displayedText);
|
||||||
|
}
|
||||||
string senderName = "";
|
string senderName = "";
|
||||||
Color senderColor = Color.White;
|
Color senderColor = Color.White;
|
||||||
if (!string.IsNullOrWhiteSpace(message.SenderName))
|
if (!string.IsNullOrWhiteSpace(message.SenderName))
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using Barotrauma.Extensions;
|
using Barotrauma.Extensions;
|
||||||
|
using Barotrauma.Networking;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Barotrauma.Networking;
|
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -189,7 +189,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaignmenucrew"), font: GUI.SubHeadingFont);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, height), pendingAndCrewGroup.RectTransform), TextManager.Get("campaignmenucrew"), font: GUI.SubHeadingFont);
|
||||||
crewList = new GUIListBox(new RectTransform(new Vector2(1.0f, (8)* height), pendingAndCrewGroup.RectTransform))
|
crewList = new GUIListBox(new RectTransform(new Vector2(1.0f, 8 * height), pendingAndCrewGroup.RectTransform))
|
||||||
{
|
{
|
||||||
Spacing = 1
|
Spacing = 1
|
||||||
};
|
};
|
||||||
@@ -208,7 +208,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ClickSound = GUISoundType.HireRepairClick,
|
ClickSound = GUISoundType.HireRepairClick,
|
||||||
ForceUpperCase = true,
|
ForceUpperCase = true,
|
||||||
OnClicked = (b, o) => ValidatePendingHires(true)
|
OnClicked = (b, o) => ValidateHires(PendingHires, true)
|
||||||
};
|
};
|
||||||
clearAllButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaignstore.clearall"))
|
clearAllButton = new GUIButton(new RectTransform(new Vector2(1.0f / 3.0f, 1.0f), group.RectTransform), text: TextManager.Get("campaignstore.clearall"))
|
||||||
{
|
{
|
||||||
@@ -338,7 +338,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 55)), parent: listBox.Content.RectTransform), "ListBoxElement")
|
GUIFrame frame = new GUIFrame(new RectTransform(new Point(listBox.Content.Rect.Width, (int)(GUI.yScale * 55)), parent: listBox.Content.RectTransform), "ListBoxElement")
|
||||||
{
|
{
|
||||||
UserData = new Tuple<CharacterInfo, float>(characterInfo, skill != null ? skill.Level : 0.0f)
|
UserData = new Tuple<CharacterInfo, float>(characterInfo, skill?.Level ?? 0.0f)
|
||||||
};
|
};
|
||||||
GUILayoutGroup mainGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), frame.RectTransform, anchor: Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
GUILayoutGroup mainGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.95f), frame.RectTransform, anchor: Anchor.Center), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
{
|
{
|
||||||
@@ -346,19 +346,22 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
|
|
||||||
float portraitWidth = (0.8f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
|
float portraitWidth = (0.8f * mainGroup.Rect.Height) / mainGroup.Rect.Width;
|
||||||
new GUICustomComponent(new RectTransform(new Vector2(portraitWidth, 0.8f), mainGroup.RectTransform),
|
var icon = new GUICustomComponent(new RectTransform(new Vector2(portraitWidth, 0.8f), mainGroup.RectTransform),
|
||||||
onDraw: (sb, component) => characterInfo.DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()))
|
onDraw: (sb, component) => characterInfo.DrawIcon(sb, component.Rect.Center.ToVector2(), targetAreaSize: component.Rect.Size.ToVector2()))
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
|
||||||
GUILayoutGroup nameAndJobGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.4f - portraitWidth, 0.8f), mainGroup.RectTransform));
|
GUILayoutGroup nameAndJobGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.4f - portraitWidth, 0.8f), mainGroup.RectTransform)) { CanBeFocused = false };
|
||||||
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform),
|
GUILayoutGroup nameGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { CanBeFocused = false };
|
||||||
characterInfo.Name, textColor: jobColor, textAlignment: Alignment.BottomLeft)
|
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(Vector2.One, nameGroup.RectTransform),
|
||||||
|
listBox == hireableList ? characterInfo.OriginalName : characterInfo.Name,
|
||||||
|
textColor: jobColor, textAlignment: Alignment.BottomLeft)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
nameBlock.Text = ToolBox.LimitString(nameBlock.Text, nameBlock.Font, nameBlock.Rect.Width);
|
nameBlock.Text = ToolBox.LimitString(nameBlock.Text, nameBlock.Font, nameBlock.Rect.Width);
|
||||||
|
|
||||||
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform),
|
GUITextBlock jobBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform),
|
||||||
characterInfo.Job.Name, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopLeft)
|
characterInfo.Job.Name, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopLeft)
|
||||||
{
|
{
|
||||||
@@ -384,11 +387,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (listBox != crewList)
|
if (listBox != crewList)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform), FormatCurrency(characterInfo.Salary), textAlignment: Alignment.Center)
|
new GUITextBlock(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform),
|
||||||
|
FormatCurrency(characterInfo.Salary),
|
||||||
|
textAlignment: Alignment.Center)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Just a bit of padding to make list layouts similar
|
||||||
|
new GUIFrame(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform), style: null) { CanBeFocused = false };
|
||||||
|
}
|
||||||
|
|
||||||
if (listBox == hireableList)
|
if (listBox == hireableList)
|
||||||
{
|
{
|
||||||
@@ -447,6 +457,23 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (listBox == pendingList || listBox == crewList)
|
||||||
|
{
|
||||||
|
nameBlock.RectTransform.Resize(new Point(nameBlock.Rect.Width - nameBlock.Rect.Height, nameBlock.Rect.Height));
|
||||||
|
nameBlock.Text = ToolBox.LimitString(nameBlock.Text, nameBlock.Font, nameBlock.Rect.Width);
|
||||||
|
nameBlock.RectTransform.Resize(new Point((int)(nameBlock.Padding.X + nameBlock.TextSize.X + nameBlock.Padding.Z), nameBlock.Rect.Height));
|
||||||
|
Point size = new Point((int)(0.7f * nameBlock.Rect.Height));
|
||||||
|
new GUIImage(new RectTransform(size, nameGroup.RectTransform), "EditIcon") { CanBeFocused = false };
|
||||||
|
size = new Point(3 * mainGroup.AbsoluteSpacing + icon.Rect.Width + nameAndJobGroup.Rect.Width, mainGroup.Rect.Height);
|
||||||
|
new GUIButton(new RectTransform(size, frame.RectTransform) { RelativeOffset = new Vector2(0.025f) }, style: null)
|
||||||
|
{
|
||||||
|
Enabled = HasPermission,
|
||||||
|
ToolTip = TextManager.GetWithVariable("campaigncrew.givenicknametooltip", "[mouseprimary]", TextManager.Get($"input.{(PlayerInput.MouseButtonsSwapped() ? "rightmouse" : "leftmouse")}")),
|
||||||
|
UserData = characterInfo,
|
||||||
|
OnClicked = CreateRenamingComponent
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CreateCharacterPreviewFrame(GUIListBox listBox, GUIFrame characterFrame, CharacterInfo characterInfo)
|
private void CreateCharacterPreviewFrame(GUIListBox listBox, GUIFrame characterFrame, CharacterInfo characterInfo)
|
||||||
@@ -479,7 +506,10 @@ namespace Barotrauma
|
|||||||
GUILayoutGroup infoValueGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.6f, 1.0f), infoGroup.RectTransform)) { Stretch = true };
|
GUILayoutGroup infoValueGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.6f, 1.0f), infoGroup.RectTransform)) { Stretch = true };
|
||||||
float blockHeight = 1.0f / 4;
|
float blockHeight = 1.0f / 4;
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("name"));
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("name"));
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), characterInfo.Name);
|
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoValueGroup.RectTransform), "");
|
||||||
|
string name = listBox == hireableList ? characterInfo.OriginalName : characterInfo.Name;
|
||||||
|
nameBlock.Text = ToolBox.LimitString(name, nameBlock.Font, nameBlock.Rect.Width);
|
||||||
|
|
||||||
if (characterInfo.HasGenders)
|
if (characterInfo.HasGenders)
|
||||||
{
|
{
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("gender"));
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, blockHeight), infoLabelGroup.RectTransform), TextManager.Get("gender"));
|
||||||
@@ -554,9 +584,18 @@ namespace Barotrauma
|
|||||||
if (PendingHires.Contains(characterInfo)) { PendingHires.Remove(characterInfo); }
|
if (PendingHires.Contains(characterInfo)) { PendingHires.Remove(characterInfo); }
|
||||||
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
|
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
|
||||||
pendingList.UpdateScrollBarSize();
|
pendingList.UpdateScrollBarSize();
|
||||||
CreateCharacterFrame(characterInfo, hireableList);
|
|
||||||
SortCharacters(hireableList, (SortingMethod)sortingDropDown.SelectedItemData);
|
// Server will reset the names to originals in multiplayer
|
||||||
hireableList.UpdateScrollBarSize();
|
if (!GameMain.IsMultiplayer) { characterInfo?.ResetName(); }
|
||||||
|
|
||||||
|
if (campaign.Map.CurrentLocation.HireManager.AvailableCharacters.Any(info => info.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()) &&
|
||||||
|
hireableList.Content.Children.None(c => c.UserData is Tuple<CharacterInfo, float> userData && userData.Item1.GetIdentifierUsingOriginalName() == characterInfo.GetIdentifierUsingOriginalName()))
|
||||||
|
{
|
||||||
|
CreateCharacterFrame(characterInfo, hireableList);
|
||||||
|
SortCharacters(hireableList, (SortingMethod)sortingDropDown.SelectedItemData);
|
||||||
|
hireableList.UpdateScrollBarSize();
|
||||||
|
}
|
||||||
|
|
||||||
if (setTotalHireCost) { SetTotalHireCost(); }
|
if (setTotalHireCost) { SetTotalHireCost(); }
|
||||||
if (createNetworkMessage) { SendCrewState(true); }
|
if (createNetworkMessage) { SendCrewState(true); }
|
||||||
return true;
|
return true;
|
||||||
@@ -573,36 +612,41 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (pendingList == null || totalBlock == null || validateHiresButton == null) { return; }
|
if (pendingList == null || totalBlock == null || validateHiresButton == null) { return; }
|
||||||
int total = 0;
|
int total = 0;
|
||||||
pendingList.Content.Children.ForEach(c => total += (c.UserData as Tuple<CharacterInfo, float>).Item1.Salary);
|
pendingList.Content.Children.ForEach(c =>
|
||||||
|
{
|
||||||
|
total += (c.UserData as Tuple<CharacterInfo, float>).Item1.Salary;
|
||||||
|
});
|
||||||
totalBlock.Text = FormatCurrency(total);
|
totalBlock.Text = FormatCurrency(total);
|
||||||
bool enoughMoney = campaign != null ? total <= campaign.Money : true;
|
bool enoughMoney = campaign != null ? total <= campaign.Money : true;
|
||||||
totalBlock.TextColor = enoughMoney ? Color.White : Color.Red;
|
totalBlock.TextColor = enoughMoney ? Color.White : Color.Red;
|
||||||
validateHiresButton.Enabled = enoughMoney && pendingList.Content.RectTransform.Children.Any();
|
validateHiresButton.Enabled = enoughMoney && pendingList.Content.RectTransform.Children.Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ValidatePendingHires(bool createNetworkEvent = false)
|
public bool ValidateHires(List<CharacterInfo> hires, bool createNetworkEvent = false)
|
||||||
{
|
{
|
||||||
List<CharacterInfo> hires = new List<CharacterInfo>();
|
if (hires == null || hires.None()) { return false; }
|
||||||
int total = 0;
|
|
||||||
foreach (GUIComponent c in pendingList.Content.Children.ToList())
|
|
||||||
{
|
|
||||||
if (c.UserData is Tuple<CharacterInfo, float> info)
|
|
||||||
{
|
|
||||||
hires.Add(info.Item1);
|
|
||||||
total += info.Item1.Salary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hires.None() || total > campaign.Money) { return false; }
|
List<CharacterInfo> nonDuplicateHires = new List<CharacterInfo>();
|
||||||
|
hires.ForEach(hireInfo =>
|
||||||
|
{
|
||||||
|
if(campaign.CrewManager.GetCharacterInfos().None(crewInfo => crewInfo.IsNewHire && crewInfo.GetIdentifierUsingOriginalName() == hireInfo.GetIdentifierUsingOriginalName()))
|
||||||
|
{
|
||||||
|
nonDuplicateHires.Add(hireInfo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nonDuplicateHires.None()) { return false; }
|
||||||
|
|
||||||
|
int total = nonDuplicateHires.Aggregate(0, (total, info) => total + info.Salary);
|
||||||
|
|
||||||
|
if (total > campaign.Money) { return false; }
|
||||||
|
|
||||||
bool atLeastOneHired = false;
|
bool atLeastOneHired = false;
|
||||||
foreach (CharacterInfo ci in hires)
|
foreach (CharacterInfo ci in nonDuplicateHires)
|
||||||
{
|
{
|
||||||
if (campaign.TryHireCharacter(campaign.Map.CurrentLocation, ci))
|
if (campaign.TryHireCharacter(campaign.Map.CurrentLocation, ci))
|
||||||
{
|
{
|
||||||
atLeastOneHired = true;
|
atLeastOneHired = true;
|
||||||
PendingHires.Remove(ci);
|
|
||||||
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == ci));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -629,6 +673,93 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool CreateRenamingComponent(GUIButton button, object userData)
|
||||||
|
{
|
||||||
|
if (!HasPermission || !(userData is CharacterInfo characterInfo)) { return false; }
|
||||||
|
var outerGlowFrame = new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), parentComponent.RectTransform, Anchor.Center),
|
||||||
|
style: "OuterGlow", color: Color.Black * 0.7f);
|
||||||
|
var frame = new GUIFrame(new RectTransform(new Vector2(0.33f, 0.4f), outerGlowFrame.RectTransform, anchor: Anchor.Center)
|
||||||
|
{
|
||||||
|
MaxSize = new Point(400, 300).Multiply(GUI.Scale)
|
||||||
|
});
|
||||||
|
var layoutGroup = new GUILayoutGroup(new RectTransform((frame.Rect.Size - GUIStyle.ItemFrameMargin).Multiply(new Vector2(0.75f, 1.0f)), frame.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||||
|
{
|
||||||
|
RelativeSpacing = 0.02f,
|
||||||
|
Stretch = true
|
||||||
|
};
|
||||||
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), layoutGroup.RectTransform), TextManager.Get("campaigncrew.givenickname"), font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
|
||||||
|
var groupElementSize = new Vector2(1.0f, 0.25f);
|
||||||
|
var nameBox = new GUITextBox(new RectTransform(groupElementSize, layoutGroup.RectTransform))
|
||||||
|
{
|
||||||
|
MaxTextLength = Client.MaxNameLength
|
||||||
|
};
|
||||||
|
new GUIButton(new RectTransform(groupElementSize, layoutGroup.RectTransform), text: TextManager.Get("confirm"))
|
||||||
|
{
|
||||||
|
OnClicked = (button, userData) =>
|
||||||
|
{
|
||||||
|
if (RenameCharacter(characterInfo, nameBox.Text?.Trim()))
|
||||||
|
{
|
||||||
|
parentComponent.RemoveChild(outerGlowFrame);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nameBox.Flash(color: Color.Red);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
new GUIButton(new RectTransform(groupElementSize, layoutGroup.RectTransform), text: TextManager.Get("cancel"))
|
||||||
|
{
|
||||||
|
OnClicked = (button, userData) =>
|
||||||
|
{
|
||||||
|
parentComponent.RemoveChild(outerGlowFrame);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
layoutGroup.Recalculate();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RenameCharacter(CharacterInfo characterInfo, string newName)
|
||||||
|
{
|
||||||
|
if (characterInfo == null || string.IsNullOrEmpty(newName)) { return false; }
|
||||||
|
if (newName == characterInfo.Name) { return false; }
|
||||||
|
if (GameMain.IsMultiplayer)
|
||||||
|
{
|
||||||
|
SendCrewState(false, renameCharacter: (characterInfo, newName));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var crewComponent = crewList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo);
|
||||||
|
if (crewComponent != null)
|
||||||
|
{
|
||||||
|
crewList.Content.RemoveChild(crewComponent);
|
||||||
|
campaign.CrewManager.RenameCharacter(characterInfo, newName);
|
||||||
|
CreateCharacterFrame(characterInfo, crewList);
|
||||||
|
SortCharacters(crewList, SortingMethod.JobAsc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var pendingComponent = pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo);
|
||||||
|
if (pendingComponent != null)
|
||||||
|
{
|
||||||
|
pendingList.Content.RemoveChild(pendingComponent);
|
||||||
|
campaign.Map.CurrentLocation.HireManager.RenameCharacter(characterInfo, newName);
|
||||||
|
CreateCharacterFrame(characterInfo, pendingList);
|
||||||
|
SortCharacters(pendingList, SortingMethod.JobAsc);
|
||||||
|
SetTotalHireCost();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private bool FireCharacter(GUIButton button, object selection)
|
private bool FireCharacter(GUIButton button, object selection)
|
||||||
{
|
{
|
||||||
if (!(selection is CharacterInfo characterInfo)) { return false; }
|
if (!(selection is CharacterInfo characterInfo)) { return false; }
|
||||||
@@ -649,9 +780,10 @@ namespace Barotrauma
|
|||||||
UpdateLocationView(campaign.Map.CurrentLocation, false);
|
UpdateLocationView(campaign.Map.CurrentLocation, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((GUI.MouseOn?.UserData as Tuple<CharacterInfo, float>)?.Item1 is CharacterInfo characterInfo)
|
(GUIComponent highlightedFrame, CharacterInfo highlightedInfo) = FindHighlightedCharacter(GUI.MouseOn);
|
||||||
|
if (highlightedFrame != null && highlightedInfo != null)
|
||||||
{
|
{
|
||||||
if (characterPreviewFrame == null || characterInfo != characterPreviewFrame.UserData)
|
if (characterPreviewFrame == null || highlightedInfo != characterPreviewFrame.UserData)
|
||||||
{
|
{
|
||||||
GUIComponent component = GUI.MouseOn;
|
GUIComponent component = GUI.MouseOn;
|
||||||
GUIListBox listBox = null;
|
GUIListBox listBox = null;
|
||||||
@@ -674,7 +806,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (listBox != null)
|
if (listBox != null)
|
||||||
{
|
{
|
||||||
SelectCharacter(listBox, GUI.MouseOn as GUIFrame, characterInfo);
|
SelectCharacter(listBox, highlightedFrame as GUIFrame, highlightedInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -688,6 +820,27 @@ namespace Barotrauma
|
|||||||
characterPreviewFrame.Parent?.RemoveChild(characterPreviewFrame);
|
characterPreviewFrame.Parent?.RemoveChild(characterPreviewFrame);
|
||||||
characterPreviewFrame = null;
|
characterPreviewFrame = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static (GUIComponent, CharacterInfo) FindHighlightedCharacter(GUIComponent c)
|
||||||
|
{
|
||||||
|
if (c == null)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
if (c.UserData is Tuple<CharacterInfo, float> highlightedData)
|
||||||
|
{
|
||||||
|
return (c, highlightedData.Item1);
|
||||||
|
}
|
||||||
|
if (c.Parent != null)
|
||||||
|
{
|
||||||
|
if (c.Parent is GUIListBox)
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
return FindHighlightedCharacter(c.Parent);
|
||||||
|
}
|
||||||
|
return default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetPendingHires(List<int> characterInfos, Location location)
|
public void SetPendingHires(List<int> characterInfos, Location location)
|
||||||
@@ -700,7 +853,7 @@ namespace Barotrauma
|
|||||||
PendingHires.Clear();
|
PendingHires.Clear();
|
||||||
foreach (int identifier in characterInfos)
|
foreach (int identifier in characterInfos)
|
||||||
{
|
{
|
||||||
CharacterInfo match = location.HireManager.AvailableCharacters.Find(info => info.GetIdentifier() == identifier);
|
CharacterInfo match = location.HireManager.AvailableCharacters.Find(info => info.GetIdentifierUsingOriginalName() == identifier);
|
||||||
if (match != null)
|
if (match != null)
|
||||||
{
|
{
|
||||||
PendingHires.Add(match);
|
PendingHires.Add(match);
|
||||||
@@ -717,9 +870,10 @@ namespace Barotrauma
|
|||||||
/// Notify the server of crew changes
|
/// Notify the server of crew changes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="updatePending">When set to true will tell the server to update the pending hires</param>
|
/// <param name="updatePending">When set to true will tell the server to update the pending hires</param>
|
||||||
|
/// <param name="renameCharacter">When not null tell the server to rename this character. Item1 is the character to rename, Item2 is the new name, Item3 indicates whether the renamed character is already a part of the crew.</param>
|
||||||
/// <param name="firedCharacter">When not null tell the server to fire this character</param>
|
/// <param name="firedCharacter">When not null tell the server to fire this character</param>
|
||||||
/// <param name="validateHires">When set to true will tell the server to validate pending hires</param>
|
/// <param name="validateHires">When set to true will tell the server to validate pending hires</param>
|
||||||
public void SendCrewState(bool updatePending, CharacterInfo firedCharacter = null, bool validateHires = false)
|
public void SendCrewState(bool updatePending, (CharacterInfo info, string newName) renameCharacter = default, CharacterInfo firedCharacter = null, bool validateHires = false)
|
||||||
{
|
{
|
||||||
if (campaign is MultiPlayerCampaign)
|
if (campaign is MultiPlayerCampaign)
|
||||||
{
|
{
|
||||||
@@ -732,12 +886,23 @@ namespace Barotrauma
|
|||||||
msg.Write((ushort)PendingHires.Count);
|
msg.Write((ushort)PendingHires.Count);
|
||||||
foreach (CharacterInfo pendingHire in PendingHires)
|
foreach (CharacterInfo pendingHire in PendingHires)
|
||||||
{
|
{
|
||||||
msg.Write(pendingHire.GetIdentifier());
|
msg.Write(pendingHire.GetIdentifierUsingOriginalName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Write(validateHires);
|
msg.Write(validateHires);
|
||||||
|
|
||||||
|
bool validRenaming = renameCharacter.info != null && !string.IsNullOrEmpty(renameCharacter.newName);
|
||||||
|
msg.Write(validRenaming);
|
||||||
|
if (validRenaming)
|
||||||
|
{
|
||||||
|
int identifier = renameCharacter.info.GetIdentifierUsingOriginalName();
|
||||||
|
msg.Write(identifier);
|
||||||
|
msg.Write(renameCharacter.newName);
|
||||||
|
bool existingCrewMember = campaign.CrewManager?.GetCharacterInfos().Any(ci => ci.GetIdentifierUsingOriginalName() == identifier) ?? false;
|
||||||
|
msg.Write(existingCrewMember);
|
||||||
|
}
|
||||||
|
|
||||||
msg.Write(firedCharacter != null);
|
msg.Write(firedCharacter != null);
|
||||||
if (firedCharacter != null)
|
if (firedCharacter != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1338,9 +1338,9 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawLine(SpriteBatch sb, Vector2 start, Vector2 end, Color clr, float depth = 0.0f, int width = 1)
|
public static void DrawLine(SpriteBatch sb, Vector2 start, Vector2 end, Color clr, float depth = 0.0f, float width = 1)
|
||||||
{
|
{
|
||||||
DrawLine(sb, t, start, end, clr, depth, width);
|
DrawLine(sb, t, start, end, clr, depth, (int)width);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawLine(SpriteBatch sb, Sprite sprite, Vector2 start, Vector2 end, Color clr, float depth = 0.0f, int width = 1)
|
public static void DrawLine(SpriteBatch sb, Sprite sprite, Vector2 start, Vector2 end, Color clr, float depth = 0.0f, int width = 1)
|
||||||
@@ -1407,7 +1407,7 @@ namespace Barotrauma
|
|||||||
font.DrawStringWithColors(sb, text, pos, color, 0.0f, Vector2.Zero, 1f, SpriteEffects.None, depth, richTextData);
|
font.DrawStringWithColors(sb, text, pos, color, 0.0f, Vector2.Zero, 1f, SpriteEffects.None, depth, richTextData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawRectangle(SpriteBatch sb, Vector2 start, Vector2 size, Color clr, bool isFilled = false, float depth = 0.0f, int thickness = 1)
|
public static void DrawRectangle(SpriteBatch sb, Vector2 start, Vector2 size, Color clr, bool isFilled = false, float depth = 0.0f, float thickness = 1)
|
||||||
{
|
{
|
||||||
if (size.X < 0)
|
if (size.X < 0)
|
||||||
{
|
{
|
||||||
@@ -1422,7 +1422,7 @@ namespace Barotrauma
|
|||||||
DrawRectangle(sb, new Rectangle((int)start.X, (int)start.Y, (int)size.X, (int)size.Y), clr, isFilled, depth, thickness);
|
DrawRectangle(sb, new Rectangle((int)start.X, (int)start.Y, (int)size.X, (int)size.Y), clr, isFilled, depth, thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawRectangle(SpriteBatch sb, Rectangle rect, Color clr, bool isFilled = false, float depth = 0.0f, int thickness = 1)
|
public static void DrawRectangle(SpriteBatch sb, Rectangle rect, Color clr, bool isFilled = false, float depth = 0.0f, float thickness = 1)
|
||||||
{
|
{
|
||||||
if (isFilled)
|
if (isFilled)
|
||||||
{
|
{
|
||||||
@@ -1430,15 +1430,15 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
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);
|
Rectangle srcRect = new Rectangle(0, 0, 1, 1);
|
||||||
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);
|
sb.Draw(t, new Vector2(rect.X, rect.Y), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(thickness, rect.Height), SpriteEffects.None, depth);
|
||||||
|
sb.Draw(t, new Vector2(rect.X + thickness, rect.Y), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(rect.Width - thickness, thickness), SpriteEffects.None, depth);
|
||||||
sb.Draw(t, new Rectangle(rect.X, rect.Y, thickness, rect.Height), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
sb.Draw(t, new Vector2(rect.X + thickness, rect.Bottom - thickness), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(rect.Width - thickness, thickness), SpriteEffects.None, depth);
|
||||||
sb.Draw(t, new Rectangle(rect.X + rect.Width - thickness, rect.Y, thickness, rect.Height), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
sb.Draw(t, new Vector2(rect.Right - thickness, rect.Y + thickness), srcRect, clr, 0.0f, Vector2.Zero, new Vector2(thickness, rect.Height - thickness * 2f), SpriteEffects.None, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawRectangle(SpriteBatch sb, Vector2 center, float width, float height, float rotation, Color clr, float depth = 0.0f, int thickness = 1)
|
public static void DrawRectangle(SpriteBatch sb, Vector2 center, float width, float height, float rotation, Color clr, float depth = 0.0f, float thickness = 1)
|
||||||
{
|
{
|
||||||
Matrix rotate = Matrix.CreateRotationZ(rotation);
|
Matrix rotate = Matrix.CreateRotationZ(rotation);
|
||||||
|
|
||||||
@@ -1455,7 +1455,7 @@ namespace Barotrauma
|
|||||||
DrawLine(sb, bottomLeft, topLeft, clr, depth, thickness);
|
DrawLine(sb, bottomLeft, topLeft, clr, depth, thickness);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void DrawRectangle(SpriteBatch sb, Vector2[] corners, Color clr, float depth = 0.0f, int thickness = 1)
|
public static void DrawRectangle(SpriteBatch sb, Vector2[] corners, Color clr, float depth = 0.0f, float thickness = 1)
|
||||||
{
|
{
|
||||||
if (corners.Length != 4)
|
if (corners.Length != 4)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -705,6 +705,29 @@ namespace Barotrauma
|
|||||||
if (!Visible) return;
|
if (!Visible) return;
|
||||||
DrawToolTip(spriteBatch, ToolTip, GUI.MouseOn.Rect, TooltipRichTextData);
|
DrawToolTip(spriteBatch, ToolTip, GUI.MouseOn.Rect, TooltipRichTextData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Vector2 pos, List<RichTextData> richTextData = null)
|
||||||
|
{
|
||||||
|
if (Tutorials.Tutorial.ContentRunning) { return; }
|
||||||
|
|
||||||
|
int width = (int)(400 * GUI.Scale);
|
||||||
|
int height = (int)(18 * GUI.Scale);
|
||||||
|
Point padding = new Point((int)(10 * GUI.Scale));
|
||||||
|
|
||||||
|
if (toolTipBlock == null || (string)toolTipBlock.userData != toolTip)
|
||||||
|
{
|
||||||
|
toolTipBlock = new GUITextBlock(new RectTransform(new Point(width, height), null), richTextData, toolTip, font: GUI.SmallFont, wrap: true, style: "GUIToolTip");
|
||||||
|
toolTipBlock.RectTransform.NonScaledSize = new Point(
|
||||||
|
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).X + padding.X + toolTipBlock.Padding.X + toolTipBlock.Padding.Z),
|
||||||
|
(int)(GUI.SmallFont.MeasureString(toolTipBlock.WrappedText).Y + padding.Y + toolTipBlock.Padding.Y + toolTipBlock.Padding.W));
|
||||||
|
toolTipBlock.userData = toolTip;
|
||||||
|
}
|
||||||
|
|
||||||
|
toolTipBlock.RectTransform.AbsoluteOffset = pos.ToPoint();
|
||||||
|
toolTipBlock.SetTextPos();
|
||||||
|
|
||||||
|
toolTipBlock.DrawManually(spriteBatch);
|
||||||
|
}
|
||||||
|
|
||||||
public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle targetElement, List<RichTextData> richTextData = null)
|
public static void DrawToolTip(SpriteBatch spriteBatch, string toolTip, Rectangle targetElement, List<RichTextData> richTextData = null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Barotrauma.Networking;
|
using Barotrauma.Networking;
|
||||||
|
using Barotrauma.Extensions;
|
||||||
|
|
||||||
namespace Barotrauma
|
namespace Barotrauma
|
||||||
{
|
{
|
||||||
@@ -22,11 +23,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Default,
|
Default,
|
||||||
InGame,
|
InGame,
|
||||||
Vote
|
Vote,
|
||||||
|
Hint
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<GUIButton> Buttons { get; private set; } = new List<GUIButton>();
|
public List<GUIButton> Buttons { get; private set; } = new List<GUIButton>();
|
||||||
//public GUIFrame BackgroundFrame { get; private set; }
|
|
||||||
public GUILayoutGroup Content { get; private set; }
|
public GUILayoutGroup Content { get; private set; }
|
||||||
public GUIFrame InnerFrame { get; private set; }
|
public GUIFrame InnerFrame { get; private set; }
|
||||||
public GUITextBlock Header { get; private set; }
|
public GUITextBlock Header { get; private set; }
|
||||||
@@ -58,8 +59,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool AutoClose;
|
public bool AutoClose;
|
||||||
|
|
||||||
private readonly bool alwaysVisible;
|
|
||||||
|
|
||||||
private float openState;
|
private float openState;
|
||||||
private float iconState;
|
private float iconState;
|
||||||
private bool iconSwitching;
|
private bool iconSwitching;
|
||||||
@@ -77,10 +76,17 @@ namespace Barotrauma
|
|||||||
this.Buttons[0].OnClicked = Close;
|
this.Buttons[0].OnClicked = Close;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GUIMessageBox(string headerText, string text, string[] buttons, Vector2? relativeSize = null, Point? minSize = null, Alignment textAlignment = Alignment.TopLeft, Type type = Type.Default, string tag = "", Sprite icon = null, string iconStyle = "", Sprite backgroundIcon = null)
|
public GUIMessageBox(string headerText, string text, string[] buttons, Vector2? relativeSize = null, Point? minSize = null, Alignment textAlignment = Alignment.TopLeft, Type type = Type.Default, string tag = "", Sprite icon = null, string iconStyle = "", Sprite backgroundIcon = null, bool parseRichText = false)
|
||||||
: base(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
|
: base(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: GUI.Style.GetComponentStyle("GUIMessageBox." + type) != null ? "GUIMessageBox." + type : "GUIMessageBox")
|
||||||
{
|
{
|
||||||
int width = (int)(DefaultWidth * (type == Type.Default ? 1.0f : 1.5f)), height = 0;
|
int width = (int)(DefaultWidth * type switch
|
||||||
|
{
|
||||||
|
Type.Default => 1.0f,
|
||||||
|
Type.Hint => 1.25f,
|
||||||
|
_ => 1.5f
|
||||||
|
});
|
||||||
|
int height = 0;
|
||||||
|
|
||||||
if (relativeSize.HasValue)
|
if (relativeSize.HasValue)
|
||||||
{
|
{
|
||||||
width = (int)(GameMain.GraphicsWidth * relativeSize.Value.X);
|
width = (int)(GameMain.GraphicsWidth * relativeSize.Value.X);
|
||||||
@@ -107,6 +113,7 @@ namespace Barotrauma
|
|||||||
Anchor anchor = type switch
|
Anchor anchor = type switch
|
||||||
{
|
{
|
||||||
Type.InGame => Anchor.TopCenter,
|
Type.InGame => Anchor.TopCenter,
|
||||||
|
Type.Hint => Anchor.TopRight,
|
||||||
Type.Vote => Anchor.TopRight,
|
Type.Vote => Anchor.TopRight,
|
||||||
_ => Anchor.Center
|
_ => Anchor.Center
|
||||||
};
|
};
|
||||||
@@ -127,13 +134,13 @@ namespace Barotrauma
|
|||||||
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
|
Content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.85f), InnerFrame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 5 };
|
||||||
|
|
||||||
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
|
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform),
|
||||||
headerText, font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true);
|
headerText, font: GUI.SubHeadingFont, textAlignment: Alignment.Center, wrap: true, parseRichText: parseRichText);
|
||||||
GUI.Style.Apply(Header, "", this);
|
GUI.Style.Apply(Header, "", this);
|
||||||
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(text))
|
if (!string.IsNullOrWhiteSpace(text))
|
||||||
{
|
{
|
||||||
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
|
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true, parseRichText: parseRichText);
|
||||||
GUI.Style.Apply(Text, "", this);
|
GUI.Style.Apply(Text, "", this);
|
||||||
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
||||||
new Point(Text.Rect.Width, Text.Rect.Height);
|
new Point(Text.Rect.Width, Text.Rect.Height);
|
||||||
@@ -180,7 +187,6 @@ namespace Barotrauma
|
|||||||
else if (type == Type.InGame)
|
else if (type == Type.InGame)
|
||||||
{
|
{
|
||||||
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
|
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
|
||||||
alwaysVisible = true;
|
|
||||||
CanBeFocused = false;
|
CanBeFocused = false;
|
||||||
AutoClose = true;
|
AutoClose = true;
|
||||||
GUI.Style.Apply(InnerFrame, "", this);
|
GUI.Style.Apply(InnerFrame, "", this);
|
||||||
@@ -235,13 +241,13 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
|
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true, parseRichText: parseRichText);
|
||||||
GUI.Style.Apply(Header, "", this);
|
GUI.Style.Apply(Header, "", this);
|
||||||
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(text))
|
if (!string.IsNullOrWhiteSpace(text))
|
||||||
{
|
{
|
||||||
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
|
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true, parseRichText: parseRichText);
|
||||||
GUI.Style.Apply(Text, "", this);
|
GUI.Style.Apply(Text, "", this);
|
||||||
Content.Recalculate();
|
Content.Recalculate();
|
||||||
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
||||||
@@ -266,30 +272,204 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
Buttons[0].RectTransform.MaxSize = new Point((int)(0.4f * Buttons[0].Rect.Y), Buttons[0].Rect.Y);
|
Buttons[0].RectTransform.MaxSize = new Point((int)(0.4f * Buttons[0].Rect.Y), Buttons[0].Rect.Y);
|
||||||
}
|
}
|
||||||
|
else if (type == Type.Hint)
|
||||||
|
{
|
||||||
|
CanBeFocused = false;
|
||||||
|
GUI.Style.Apply(InnerFrame, "", this);
|
||||||
|
|
||||||
|
Point absoluteSpacing = GUIStyle.ItemFrameMargin.Multiply(1.0f / 5.0f);
|
||||||
|
var verticalLayoutGroup = new GUILayoutGroup(new RectTransform(GetVerticalLayoutGroupSize(), parent: InnerFrame.RectTransform, anchor: Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = absoluteSpacing.Y,
|
||||||
|
Stretch = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var topHorizontalLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.7f), verticalLayoutGroup.RectTransform),
|
||||||
|
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
|
{
|
||||||
|
Stretch = true,
|
||||||
|
RelativeSpacing = 0.02f
|
||||||
|
};
|
||||||
|
|
||||||
|
int iconMaxHeight = 0;
|
||||||
|
if (icon != null)
|
||||||
|
{
|
||||||
|
Icon = new GUIImage(new RectTransform(new Vector2(0.15f, 0.95f), topHorizontalLayoutGroup.RectTransform), icon, scaleToFit: true);
|
||||||
|
iconMaxHeight = (int)Icon.Sprite.size.Y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool iconStyleDefined = !string.IsNullOrEmpty(iconStyle);
|
||||||
|
Icon = new GUIImage(new RectTransform(new Vector2(0.15f, 0.95f), topHorizontalLayoutGroup.RectTransform),
|
||||||
|
iconStyleDefined ? iconStyle : "GUIButtonInfo", scaleToFit: true);
|
||||||
|
if (!iconStyleDefined)
|
||||||
|
{
|
||||||
|
Icon.Color = Color.Orange;
|
||||||
|
}
|
||||||
|
iconMaxHeight = (int)(Icon.Style.GetDefaultSprite()?.size.Y ?? GUI.yScale * 40);
|
||||||
|
}
|
||||||
|
|
||||||
|
iconMaxHeight = Math.Min((int)(GUI.yScale * 40), iconMaxHeight);
|
||||||
|
int iconMinHeight = Math.Min((int)(GUI.yScale * 40), iconMaxHeight);
|
||||||
|
Icon.RectTransform.MinSize = new Point(Icon.Rect.Width, iconMinHeight);
|
||||||
|
Icon.RectTransform.MaxSize = new Point(Icon.Rect.Width, iconMaxHeight);
|
||||||
|
|
||||||
|
Content = new GUILayoutGroup(new RectTransform(new Vector2(Icon != null ? 0.85f : 1.0f, 1.0f), topHorizontalLayoutGroup.RectTransform))
|
||||||
|
{
|
||||||
|
AbsoluteSpacing = absoluteSpacing.Y,
|
||||||
|
};
|
||||||
|
|
||||||
|
var bottomContainer = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.3f), verticalLayoutGroup.RectTransform), style: null);
|
||||||
|
|
||||||
|
var tickBoxLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.67f, 1.0f), bottomContainer.RectTransform, anchor: Anchor.CenterLeft),
|
||||||
|
isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
|
{
|
||||||
|
Stretch = true,
|
||||||
|
RelativeSpacing = 0.02f
|
||||||
|
};
|
||||||
|
|
||||||
|
var dontShowAgainTickBox = new GUITickBox(new RectTransform(new Vector2(0.5f, 1.0f), tickBoxLayoutGroup.RectTransform),
|
||||||
|
TextManager.Get("hintmessagebox.dontshowagain"))
|
||||||
|
{
|
||||||
|
ToolTip = TextManager.Get("hintmessagebox.dontshowagaintooltip"),
|
||||||
|
UserData = "dontshowagain"
|
||||||
|
};
|
||||||
|
|
||||||
|
//var disableHintsTickBox = new GUITickBox(new RectTransform(new Vector2(0.33f, 1.0f), tickBoxLayoutGroup.RectTransform),
|
||||||
|
// TextManager.Get("hintmessagebox.disablehints"))
|
||||||
|
//{
|
||||||
|
// ToolTip = TextManager.Get("hintmessagebox.disablehintstooltip"),
|
||||||
|
// UserData = "disablehints"
|
||||||
|
//};
|
||||||
|
|
||||||
|
Buttons = new List<GUIButton>(1)
|
||||||
|
{
|
||||||
|
new GUIButton(new RectTransform(new Vector2(0.33f, 1.0f), bottomContainer.RectTransform, Anchor.CenterRight),
|
||||||
|
text: TextManager.Get("hintmessagebox.dismiss"), style: "GUIButtonSmall")
|
||||||
|
{
|
||||||
|
OnClicked = Close
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
InputType? closeInput = null;
|
||||||
|
if (GameMain.Config.KeyBind(InputType.Use).MouseButton == MouseButton.None)
|
||||||
|
{
|
||||||
|
closeInput = InputType.Use;
|
||||||
|
}
|
||||||
|
else if (GameMain.Config.KeyBind(InputType.Select).MouseButton == MouseButton.None)
|
||||||
|
{
|
||||||
|
closeInput = InputType.Select;
|
||||||
|
}
|
||||||
|
if (closeInput.HasValue)
|
||||||
|
{
|
||||||
|
Buttons[0].ToolTip = TextManager.ParseInputTypes($"{TextManager.Get("hintmessagebox.dismiss")} ([InputType.{closeInput.Value}])");
|
||||||
|
Buttons[0].OnAddedToGUIUpdateList += (GUIComponent component) =>
|
||||||
|
{
|
||||||
|
if (!closing && openState >= 1.0f && PlayerInput.KeyHit(closeInput.Value))
|
||||||
|
{
|
||||||
|
GUIButton btn = component as GUIButton;
|
||||||
|
btn?.OnClicked(btn, btn.UserData);
|
||||||
|
btn?.Flash(GUI.Style.Green);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
Header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), headerText, wrap: true);
|
||||||
|
GUI.Style.Apply(Header, "", this);
|
||||||
|
Header.RectTransform.MinSize = new Point(0, Header.Rect.Height);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(text))
|
||||||
|
{
|
||||||
|
Text = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), Content.RectTransform), text, textAlignment: textAlignment, wrap: true);
|
||||||
|
GUI.Style.Apply(Text, "", this);
|
||||||
|
Content.Recalculate();
|
||||||
|
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
||||||
|
new Point(Text.Rect.Width, Text.Rect.Height);
|
||||||
|
Text.RectTransform.IsFixedSize = true;
|
||||||
|
if (string.IsNullOrWhiteSpace(headerText))
|
||||||
|
{
|
||||||
|
Header.RectTransform.Parent = null;
|
||||||
|
Content.ChildAnchor = Anchor.Center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height == 0)
|
||||||
|
{
|
||||||
|
height = absoluteSpacing.Y;
|
||||||
|
int upperContainerHeight = absoluteSpacing.Y;
|
||||||
|
if (Header.Rect.Height > 0) { upperContainerHeight += Header.Rect.Height + Content.AbsoluteSpacing; }
|
||||||
|
if (Text != null) { upperContainerHeight += Text.Rect.Height + Content.AbsoluteSpacing; }
|
||||||
|
upperContainerHeight = Math.Max(upperContainerHeight, Icon.Rect.Height);
|
||||||
|
height += upperContainerHeight;
|
||||||
|
height += absoluteSpacing.Y;
|
||||||
|
height += (int)((bottomContainer.RectTransform.RelativeSize.Y / topHorizontalLayoutGroup.RectTransform.RelativeSize.Y) * upperContainerHeight);
|
||||||
|
height += absoluteSpacing.Y;
|
||||||
|
if (minSize.HasValue) { height = Math.Max(height, minSize.Value.Y); }
|
||||||
|
|
||||||
|
InnerFrame.RectTransform.NonScaledSize = new Point(InnerFrame.Rect.Width, height);
|
||||||
|
verticalLayoutGroup.RectTransform.NonScaledSize = GetVerticalLayoutGroupSize();
|
||||||
|
verticalLayoutGroup.Recalculate();
|
||||||
|
topHorizontalLayoutGroup.Recalculate();
|
||||||
|
Content.Recalculate();
|
||||||
|
tickBoxLayoutGroup.Recalculate();
|
||||||
|
}
|
||||||
|
|
||||||
|
InnerFrame.RectTransform.AbsoluteOffset = new Point(GUI.IntScale(64), -InnerFrame.Rect.Height);
|
||||||
|
|
||||||
|
Point GetVerticalLayoutGroupSize()
|
||||||
|
{
|
||||||
|
return InnerFrame.Rect.Size - absoluteSpacing.Multiply(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MessageBoxes.Add(this);
|
MessageBoxes.Add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Use to create a message box of Hint type
|
||||||
|
/// </summary>
|
||||||
|
public GUIMessageBox(string hintIdentifier, string text, Sprite icon) : this("", text, new string[0], textAlignment: Alignment.CenterLeft, type: Type.Hint, icon: icon)
|
||||||
|
{
|
||||||
|
if (InnerFrame.FindChild("dontshowagain", recursive: true) is GUITickBox dontShowAgainTickBox)
|
||||||
|
{
|
||||||
|
dontShowAgainTickBox.OnSelected = HintManager.OnDontShowAgain;
|
||||||
|
dontShowAgainTickBox.UserData = hintIdentifier;
|
||||||
|
}
|
||||||
|
if (InnerFrame.FindChild("disablehints", recursive: true) is GUITickBox disableHintsTickBox)
|
||||||
|
{
|
||||||
|
disableHintsTickBox.OnSelected = HintManager.OnDisableHints;
|
||||||
|
disableHintsTickBox.UserData = hintIdentifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Type[] messageBoxTypes;
|
||||||
|
|
||||||
public static void AddActiveToGUIUpdateList()
|
public static void AddActiveToGUIUpdateList()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MessageBoxes.Count; i++)
|
messageBoxTypes ??= (Type[])Enum.GetValues(typeof(Type));
|
||||||
|
|
||||||
|
foreach (var type in messageBoxTypes)
|
||||||
{
|
{
|
||||||
if (MessageBoxes[i] is GUIMessageBox alwaysVisibleMsgBox && alwaysVisibleMsgBox.alwaysVisible)
|
for (int i = 0; i < MessageBoxes.Count; i++)
|
||||||
{
|
{
|
||||||
alwaysVisibleMsgBox.AddToGUIUpdateList();
|
if (MessageBoxes[i] == null) { continue; }
|
||||||
break;
|
if (!(MessageBoxes[i] is GUIMessageBox messageBox))
|
||||||
}
|
{
|
||||||
}
|
if (type == Type.Default)
|
||||||
for (int i = MessageBoxes.Count - 1; i >= 0; i--)
|
{
|
||||||
{
|
// Message box not of type GUIMessageBox is likely the round summary
|
||||||
if (MessageBoxes[i].UserData as string == "verificationprompt" ||
|
MessageBoxes[i].AddToGUIUpdateList();
|
||||||
MessageBoxes[i].UserData as string == "bugreporter")
|
break;
|
||||||
{
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!(MessageBoxes[i] is GUIMessageBox msgBox) || !msgBox.alwaysVisible)
|
if (messageBox.type != type) { continue; }
|
||||||
{
|
|
||||||
MessageBoxes[i].AddToGUIUpdateList();
|
// These are handled separately in GUI.HandlePersistingElements()
|
||||||
|
if (MessageBoxes[i].UserData as string == "verificationprompt") { continue; }
|
||||||
|
if (MessageBoxes[i].UserData as string == "bugreporter") { continue; }
|
||||||
|
|
||||||
|
messageBox.AddToGUIUpdateList();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,11 +517,21 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == Type.InGame)
|
if (type == Type.InGame || type == Type.Hint)
|
||||||
{
|
{
|
||||||
Vector2 initialPos = new Vector2(0.0f, GameMain.GraphicsHeight);
|
Vector2 initialPos, defaultPos, endPos;
|
||||||
Vector2 defaultPos = new Vector2(0.0f, HUDLayoutSettings.InventoryAreaLower.Y - InnerFrame.Rect.Height - 20 * GUI.Scale);
|
if (type == Type.InGame)
|
||||||
Vector2 endPos = new Vector2(GameMain.GraphicsWidth, defaultPos.Y);
|
{
|
||||||
|
initialPos = new Vector2(0.0f, GameMain.GraphicsHeight);
|
||||||
|
defaultPos = new Vector2(0.0f, HUDLayoutSettings.InventoryAreaLower.Y - InnerFrame.Rect.Height - 20 * GUI.Scale);
|
||||||
|
endPos = new Vector2(GameMain.GraphicsWidth, defaultPos.Y);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
initialPos = new Vector2(GUI.IntScale(64), -InnerFrame.Rect.Height);
|
||||||
|
defaultPos = new Vector2(initialPos.X, HUDLayoutSettings.MessageAreaTop.Height + GUI.IntScale(64));
|
||||||
|
endPos = new Vector2(-InnerFrame.Rect.Width, defaultPos.Y);
|
||||||
|
}
|
||||||
|
|
||||||
if (!closing)
|
if (!closing)
|
||||||
{
|
{
|
||||||
@@ -428,7 +618,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void Close()
|
public void Close()
|
||||||
{
|
{
|
||||||
if (type == Type.InGame)
|
if (type == Type.InGame || type == Type.Hint)
|
||||||
{
|
{
|
||||||
closing = true;
|
closing = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ namespace Barotrauma
|
|||||||
public readonly Sprite[] CursorSprite = new Sprite[7];
|
public readonly Sprite[] CursorSprite = new Sprite[7];
|
||||||
|
|
||||||
public UISprite RadiationSprite { get; private set; }
|
public UISprite RadiationSprite { get; private set; }
|
||||||
|
public SpriteSheet RadiationAnimSpriteSheet { get; private set; }
|
||||||
|
|
||||||
public UISprite UIGlow { get; private set; }
|
public UISprite UIGlow { get; private set; }
|
||||||
public UISprite UIGlowCircular { get; private set; }
|
public UISprite UIGlowCircular { get; private set; }
|
||||||
@@ -214,6 +215,9 @@ namespace Barotrauma
|
|||||||
case "radiation":
|
case "radiation":
|
||||||
RadiationSprite = new UISprite(subElement);
|
RadiationSprite = new UISprite(subElement);
|
||||||
break;
|
break;
|
||||||
|
case "radiationanimspritesheet":
|
||||||
|
RadiationAnimSpriteSheet = new SpriteSheet(subElement);
|
||||||
|
break;
|
||||||
case "uiglowcircular":
|
case "uiglowcircular":
|
||||||
UIGlowCircular = new UISprite(subElement);
|
UIGlowCircular = new UISprite(subElement);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -279,7 +279,8 @@ namespace Barotrauma
|
|||||||
/// If the rectT height is set 0, the height is calculated from the text.
|
/// If the rectT height is set 0, the height is calculated from the text.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public GUITextBlock(RectTransform rectT, string text, Color? textColor = null, ScalableFont font = null,
|
public GUITextBlock(RectTransform rectT, string text, Color? textColor = null, ScalableFont font = null,
|
||||||
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null, bool playerInput = false)
|
Alignment textAlignment = Alignment.Left, bool wrap = false, string style = "", Color? color = null,
|
||||||
|
bool playerInput = false, bool parseRichText = false)
|
||||||
: base(style, rectT)
|
: base(style, rectT)
|
||||||
{
|
{
|
||||||
if (color.HasValue)
|
if (color.HasValue)
|
||||||
@@ -289,7 +290,13 @@ namespace Barotrauma
|
|||||||
if (textColor.HasValue)
|
if (textColor.HasValue)
|
||||||
{
|
{
|
||||||
OverrideTextColor(textColor.Value);
|
OverrideTextColor(textColor.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (parseRichText)
|
||||||
|
{
|
||||||
|
richTextData = RichTextData.GetRichTextData(text, out text);
|
||||||
|
hasColorHighlight = richTextData != null;
|
||||||
|
}
|
||||||
|
|
||||||
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
|
//if the text is in chinese/korean/japanese and we're not using a CJK-compatible font,
|
||||||
//use the default CJK font as a fallback
|
//use the default CJK font as a fallback
|
||||||
|
|||||||
@@ -70,6 +70,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
private string selectedTip;
|
private string selectedTip;
|
||||||
|
private List<RichTextData> selectedTipRichTextData;
|
||||||
|
private bool selectedTipRichTextUnparsed;
|
||||||
|
private void SetSelectedTip(string tip)
|
||||||
|
{
|
||||||
|
selectedTip = tip;
|
||||||
|
selectedTipRichTextData = null;
|
||||||
|
selectedTipRichTextUnparsed = true;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly object loadMutex = new object();
|
private readonly object loadMutex = new object();
|
||||||
private float? loadState;
|
private float? loadState;
|
||||||
@@ -115,7 +123,7 @@ namespace Barotrauma
|
|||||||
overlay = TextureLoader.FromFile("Content/UI/LoadingScreenOverlay.png");
|
overlay = TextureLoader.FromFile("Content/UI/LoadingScreenOverlay.png");
|
||||||
noiseSprite = new Sprite("Content/UI/noise.png", Vector2.Zero);
|
noiseSprite = new Sprite("Content/UI/noise.png", Vector2.Zero);
|
||||||
DrawLoadingText = true;
|
DrawLoadingText = true;
|
||||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
|
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
|
||||||
@@ -215,14 +223,34 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (GUI.Font != null && selectedTip != null)
|
if (GUI.Font != null && selectedTip != null)
|
||||||
{
|
{
|
||||||
|
if (selectedTipRichTextUnparsed)
|
||||||
|
{
|
||||||
|
selectedTipRichTextData = RichTextData.GetRichTextData(selectedTip, out selectedTip);
|
||||||
|
selectedTipRichTextUnparsed = false;
|
||||||
|
}
|
||||||
|
|
||||||
string wrappedTip = ToolBox.WrapText(selectedTip, GameMain.GraphicsWidth * 0.5f, GUI.Font);
|
string wrappedTip = ToolBox.WrapText(selectedTip, GameMain.GraphicsWidth * 0.5f, GUI.Font);
|
||||||
string[] lines = wrappedTip.Split('\n');
|
string[] lines = wrappedTip.Split('\n');
|
||||||
float lineHeight = GUI.Font.MeasureString(selectedTip).Y;
|
float lineHeight = GUI.Font.MeasureString(selectedTip).Y;
|
||||||
|
|
||||||
for (int i = 0; i < lines.Length; i++)
|
if (selectedTipRichTextData != null)
|
||||||
{
|
{
|
||||||
GUI.Font.DrawString(spriteBatch, lines[i],
|
int rtdOffset = 0;
|
||||||
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White);
|
for (int i = 0; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
GUI.Font.DrawStringWithColors(spriteBatch, lines[i],
|
||||||
|
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White,
|
||||||
|
0f, Vector2.Zero, 1f, SpriteEffects.None, 0f, selectedTipRichTextData, rtdOffset);
|
||||||
|
rtdOffset += lines[i].Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < lines.Length; i++)
|
||||||
|
{
|
||||||
|
GUI.Font.DrawString(spriteBatch, lines[i],
|
||||||
|
new Vector2((int)(GameMain.GraphicsWidth / 2.0f - GUI.Font.MeasureString(lines[i]).X / 2.0f), (int)(GameMain.GraphicsHeight * 0.8f + i * lineHeight)), Color.White);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,7 +330,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
GameMain.Config.Language = language;
|
GameMain.Config.Language = language;
|
||||||
//reload tip in the selected language
|
//reload tip in the selected language
|
||||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
||||||
GameMain.Config.SetDefaultBindings(legacy: false);
|
GameMain.Config.SetDefaultBindings(legacy: false);
|
||||||
GameMain.Config.CheckBindings(useDefaults: true);
|
GameMain.Config.CheckBindings(useDefaults: true);
|
||||||
WaitForLanguageSelection = false;
|
WaitForLanguageSelection = false;
|
||||||
@@ -364,7 +392,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
drawn = false;
|
drawn = false;
|
||||||
LoadState = null;
|
LoadState = null;
|
||||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
||||||
currentBackgroundTexture = LocationType.List.GetRandom()?.GetPortrait(Rand.Int(int.MaxValue))?.Texture;
|
currentBackgroundTexture = LocationType.List.GetRandom()?.GetPortrait(Rand.Int(int.MaxValue))?.Texture;
|
||||||
|
|
||||||
while (!drawn)
|
while (!drawn)
|
||||||
|
|||||||
@@ -1284,7 +1284,8 @@ namespace Barotrauma
|
|||||||
// Add items on the sub(s)
|
// Add items on the sub(s)
|
||||||
Submarine.MainSub?.GetItems(true)
|
Submarine.MainSub?.GetItems(true)
|
||||||
.Where(i => i.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached) &&
|
.Where(i => i.Components.All(c => !(c is Holdable h) || !h.Attachable || !h.Attached) &&
|
||||||
i.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null)))
|
i.Components.All(c => !(c is Wire w) || w.Connections.All(c => c == null)) &&
|
||||||
|
ItemAndAllContainersInteractable(i))
|
||||||
.ForEach(i => AddToOwnedItems(i.Prefab));
|
.ForEach(i => AddToOwnedItems(i.Prefab));
|
||||||
|
|
||||||
// Add items in character inventories
|
// Add items in character inventories
|
||||||
@@ -1302,6 +1303,16 @@ namespace Barotrauma
|
|||||||
|
|
||||||
ownedItemsUpdateTimer = 0.0f;
|
ownedItemsUpdateTimer = 0.0f;
|
||||||
|
|
||||||
|
static bool ItemAndAllContainersInteractable(Item item)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (!item.IsPlayerTeamInteractable) { return false; }
|
||||||
|
item = item.Container;
|
||||||
|
} while (item != null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void AddToOwnedItems(ItemPrefab itemPrefab, int amount = 1)
|
void AddToOwnedItems(ItemPrefab itemPrefab, int amount = 1)
|
||||||
{
|
{
|
||||||
if (OwnedItems.ContainsKey(itemPrefab))
|
if (OwnedItems.ContainsKey(itemPrefab))
|
||||||
|
|||||||
@@ -882,10 +882,15 @@ namespace Barotrauma
|
|||||||
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(Vector2.One, missionList.Content.RectTransform), style: null);
|
GUIFrame missionDescriptionHolder = new GUIFrame(new RectTransform(Vector2.One, missionList.Content.RectTransform), style: null);
|
||||||
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft);
|
GUILayoutGroup missionTextGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.744f, 0f), missionDescriptionHolder.RectTransform, Anchor.CenterLeft) { RelativeOffset = new Vector2(0.225f, 0f) }, false, childAnchor: Anchor.TopLeft);
|
||||||
|
|
||||||
string missionNameString = ToolBox.WrapText(mission.Name, missionTextGroup.Rect.Width, GUI.LargeFont);
|
|
||||||
string missionDescriptionString = ToolBox.WrapText(mission.Description, missionTextGroup.Rect.Width, GUI.Font);
|
|
||||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", mission.Reward));
|
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", mission.Reward));
|
||||||
string missionRewardString = ToolBox.WrapText(TextManager.GetWithVariable("MissionReward", "[reward]", rewardText), missionTextGroup.Rect.Width, GUI.Font);
|
|
||||||
|
var missionNameRichTextData = RichTextData.GetRichTextData(mission.Name, out string missionNameString);
|
||||||
|
var missionDescriptionRichTextData = RichTextData.GetRichTextData(mission.Description, out string missionDescriptionString);
|
||||||
|
var missionRewardRichTextData = RichTextData.GetRichTextData(TextManager.GetWithVariable("MissionReward", "[reward]", rewardText), out string missionRewardString);
|
||||||
|
|
||||||
|
missionNameString = ToolBox.WrapText(missionNameString, missionTextGroup.Rect.Width, GUI.LargeFont);
|
||||||
|
missionDescriptionString = ToolBox.WrapText(missionDescriptionString, missionTextGroup.Rect.Width, GUI.Font);
|
||||||
|
missionRewardString = ToolBox.WrapText(missionRewardString, missionTextGroup.Rect.Width, GUI.Font);
|
||||||
|
|
||||||
Vector2 missionNameSize = GUI.LargeFont.MeasureString(missionNameString);
|
Vector2 missionNameSize = GUI.LargeFont.MeasureString(missionNameString);
|
||||||
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
|
Vector2 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
|
||||||
@@ -901,12 +906,12 @@ namespace Barotrauma
|
|||||||
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
||||||
Point iconSize = new Point(iconWidth, iconHeight);
|
Point iconSize = new Point(iconWidth, iconHeight);
|
||||||
|
|
||||||
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true) { Color = mission.Prefab.IconColor, HoverColor = mission.Prefab.IconColor };
|
new GUIImage(new RectTransform(iconSize, missionDescriptionHolder.RectTransform), mission.Prefab.Icon, null, true) { Color = mission.Prefab.IconColor };
|
||||||
}
|
}
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameString, font: GUI.LargeFont);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardString);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionRewardRichTextData, missionRewardString);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionString);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextGroup.RectTransform), missionDescriptionRichTextData, missionDescriptionString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -465,7 +465,28 @@ namespace Barotrauma
|
|||||||
|
|
||||||
while (Config.WaitingForAutoUpdate) { yield return CoroutineStatus.Running; }
|
while (Config.WaitingForAutoUpdate) { yield return CoroutineStatus.Running; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
if (Config.ModBreakerMode)
|
||||||
|
{
|
||||||
|
Config.SelectCorePackage(ContentPackage.CorePackages.GetRandom());
|
||||||
|
foreach (var regularPackage in ContentPackage.RegularPackages)
|
||||||
|
{
|
||||||
|
if (Rand.Range(0.0, 1.0) <= 0.5)
|
||||||
|
{
|
||||||
|
Config.EnableRegularPackage(regularPackage);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Config.DisableRegularPackage(regularPackage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ContentPackage.SortContentPackages(p =>
|
||||||
|
{
|
||||||
|
return Rand.Int(int.MaxValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (Config.AllEnabledPackages.None())
|
if (Config.AllEnabledPackages.None())
|
||||||
{
|
{
|
||||||
@@ -535,6 +556,7 @@ namespace Barotrauma
|
|||||||
Order.Init();
|
Order.Init();
|
||||||
EventManagerSettings.Init();
|
EventManagerSettings.Init();
|
||||||
BallastFloraPrefab.LoadAll(GetFilesOfType(ContentType.MapCreature));
|
BallastFloraPrefab.LoadAll(GetFilesOfType(ContentType.MapCreature));
|
||||||
|
HintManager.Init();
|
||||||
TitleScreen.LoadState = 50.0f;
|
TitleScreen.LoadState = 50.0f;
|
||||||
yield return CoroutineStatus.Running;
|
yield return CoroutineStatus.Running;
|
||||||
|
|
||||||
@@ -920,6 +942,8 @@ namespace Barotrauma
|
|||||||
Client.AddToGUIUpdateList();
|
Client.AddToGUIUpdateList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SubmarinePreview.AddToGUIUpdateList();
|
||||||
|
|
||||||
FileSelection.AddToGUIUpdateList();
|
FileSelection.AddToGUIUpdateList();
|
||||||
|
|
||||||
DebugConsole.AddToGUIUpdateList();
|
DebugConsole.AddToGUIUpdateList();
|
||||||
|
|||||||
@@ -330,7 +330,10 @@ namespace Barotrauma
|
|||||||
if (removeInfo) { characterInfos.Remove(character.Info); }
|
if (removeInfo) { characterInfos.Remove(character.Info); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private void AddCharacterToCrewList(Character character)
|
/// <summary>
|
||||||
|
/// Add character to the list without actually adding it to the crew
|
||||||
|
/// </summary>
|
||||||
|
public void AddCharacterToCrewList(Character character)
|
||||||
{
|
{
|
||||||
if (character == null) { return; }
|
if (character == null) { return; }
|
||||||
|
|
||||||
@@ -416,7 +419,8 @@ namespace Barotrauma
|
|||||||
font: font,
|
font: font,
|
||||||
textColor: character.Info?.Job?.Prefab?.UIColor)
|
textColor: character.Info?.Job?.Prefab?.UIColor)
|
||||||
{
|
{
|
||||||
CanBeFocused = false
|
CanBeFocused = false,
|
||||||
|
UserData = "name"
|
||||||
};
|
};
|
||||||
nameBlock.Text = ToolBox.LimitString(character.Name, font, (int)nameBlock.Rect.Width);
|
nameBlock.Text = ToolBox.LimitString(character.Name, font, (int)nameBlock.Rect.Width);
|
||||||
|
|
||||||
@@ -429,22 +433,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
UserData = character
|
UserData = character
|
||||||
};
|
};
|
||||||
|
SetCharacterButtonTooltip(characterButton);
|
||||||
// Only create a tooltip if the name doesn't fit the name block
|
|
||||||
if (nameBlock.Text.EndsWith("..."))
|
|
||||||
{
|
|
||||||
var characterTooltip = character.Name;
|
|
||||||
if (character.Info?.Job?.Name != null) { characterTooltip += " (" + character.Info.Job.Name + ")"; };
|
|
||||||
characterButton.ToolTip = characterTooltip;
|
|
||||||
if (character.Info?.Job?.Prefab != null)
|
|
||||||
{
|
|
||||||
characterButton.TooltipRichTextData = new List<RichTextData>() { new RichTextData()
|
|
||||||
{
|
|
||||||
Color = character.Info.Job.Prefab.UIColor,
|
|
||||||
EndIndex = characterTooltip.Length - 1
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsSinglePlayer)
|
if (IsSinglePlayer)
|
||||||
{
|
{
|
||||||
@@ -482,6 +471,14 @@ namespace Barotrauma
|
|||||||
UserData = character
|
UserData = character
|
||||||
};
|
};
|
||||||
currentOrderList.RectTransform.IsFixedSize = true;
|
currentOrderList.RectTransform.IsFixedSize = true;
|
||||||
|
currentOrderList.OnAddedToGUIUpdateList += (component) =>
|
||||||
|
{
|
||||||
|
if (component is GUIListBox list)
|
||||||
|
{
|
||||||
|
list.CanBeFocused = CanIssueOrders;
|
||||||
|
list.CanDragElements = CanIssueOrders && list.Content.CountChildren > 1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Previous orders
|
// Previous orders
|
||||||
new GUILayoutGroup(new RectTransform(Vector2.One, parent: orderGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
new GUILayoutGroup(new RectTransform(Vector2.One, parent: orderGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
|
||||||
@@ -526,14 +523,26 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SetCharacterButtonTooltip(GUIButton characterButton)
|
||||||
|
{
|
||||||
|
var character = (Character)characterButton.UserData;
|
||||||
|
if (character?.Info?.Job?.Prefab == null) { return; }
|
||||||
|
string color = XMLExtensions.ColorToString(character.Info.Job.Prefab.UIColor);
|
||||||
|
string tooltip = $"‖color:{color}‖{character.Name} ({character.Info.Job.Name})‖color:end‖";
|
||||||
|
var richTextData = RichTextData.GetRichTextData(tooltip, out string sanitizedTooltip);
|
||||||
|
characterButton.ToolTip = sanitizedTooltip;
|
||||||
|
characterButton.TooltipRichTextData = richTextData;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Sets which character is selected in the crew UI (highlight effect etc)
|
/// Sets which character is selected in the crew UI (highlight effect etc)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool CharacterClicked(GUIComponent component, object selection)
|
public bool CharacterClicked(GUIComponent component, object selection)
|
||||||
{
|
{
|
||||||
if (!AllowCharacterSwitch) { return false; }
|
if (!AllowCharacterSwitch) { return false; }
|
||||||
Character character = selection as Character;
|
if (!(selection is Character character) || character.IsDead || character.IsUnconscious) { return false; }
|
||||||
if (character == null || character.IsDead || character.IsUnconscious) { return false; }
|
if (!character.IsOnPlayerTeam) { return false; }
|
||||||
|
|
||||||
SelectCharacter(character);
|
SelectCharacter(character);
|
||||||
if (GUI.KeyboardDispatcher.Subscriber == crewList) { GUI.KeyboardDispatcher.Subscriber = null; }
|
if (GUI.KeyboardDispatcher.Subscriber == crewList) { GUI.KeyboardDispatcher.Subscriber = null; }
|
||||||
return true;
|
return true;
|
||||||
@@ -588,6 +597,15 @@ namespace Barotrauma
|
|||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void RenameCharacterProjSpecific(CharacterInfo characterInfo)
|
||||||
|
{
|
||||||
|
if (!(crewList.Content.GetChildByUserData(characterInfo?.Character) is GUIComponent characterComponent)) { return; }
|
||||||
|
if (!(characterComponent.FindChild("name", recursive: true) is GUITextBlock nameBlock)) { return; }
|
||||||
|
nameBlock.Text = ToolBox.LimitString(characterInfo.Name, nameBlock.Font, nameBlock.Rect.Width);
|
||||||
|
if (!(characterComponent.FindChild(c => c is GUIButton && c.UserData == characterInfo?.Character) is GUIButton characterButton)) { return; }
|
||||||
|
SetCharacterButtonTooltip(characterButton);
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Dialog
|
#region Dialog
|
||||||
@@ -835,7 +853,6 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (order == null || order.Identifier == dismissedOrderPrefab.Identifier || updatedExistingIcon)
|
if (order == null || order.Identifier == dismissedOrderPrefab.Identifier || updatedExistingIcon)
|
||||||
{
|
{
|
||||||
currentOrderIconList.CanDragElements = currentOrderIconList.Content.CountChildren > 1;
|
|
||||||
RearrangeIcons();
|
RearrangeIcons();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -874,7 +891,6 @@ namespace Barotrauma
|
|||||||
nodeIcon.RectTransform.RepositionChildInHierarchy(hierarchyIndex);
|
nodeIcon.RectTransform.RepositionChildInHierarchy(hierarchyIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentOrderIconList.CanDragElements = currentOrderIconList.Content.CountChildren > 1;
|
|
||||||
RearrangeIcons();
|
RearrangeIcons();
|
||||||
|
|
||||||
void RearrangeIcons()
|
void RearrangeIcons()
|
||||||
@@ -1276,6 +1292,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
DisableCommandUI();
|
DisableCommandUI();
|
||||||
Character.Controlled = character;
|
Character.Controlled = character;
|
||||||
|
HintManager.OnChangeCharacter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private int TryAdjustIndex(int amount)
|
private int TryAdjustIndex(int amount)
|
||||||
@@ -1537,6 +1554,11 @@ namespace Barotrauma
|
|||||||
if (characterComponent.UserData is Character character)
|
if (characterComponent.UserData is Character character)
|
||||||
{
|
{
|
||||||
characterComponent.Visible = Character.Controlled == null || Character.Controlled.TeamID == character.TeamID;
|
characterComponent.Visible = Character.Controlled == null || Character.Controlled.TeamID == character.TeamID;
|
||||||
|
if (character.TeamID == CharacterTeamType.FriendlyNPC && Character.Controlled != null &&
|
||||||
|
(character.CurrentHull == Character.Controlled.CurrentHull || Vector2.DistanceSquared(Character.Controlled.WorldPosition, character.WorldPosition) < 500.0f * 500.0f))
|
||||||
|
{
|
||||||
|
characterComponent.Visible = true;
|
||||||
|
}
|
||||||
if (characterComponent.Visible)
|
if (characterComponent.Visible)
|
||||||
{
|
{
|
||||||
if (character == Character.Controlled && characterComponent.State != GUIComponent.ComponentState.Selected)
|
if (character == Character.Controlled && characterComponent.State != GUIComponent.ComponentState.Selected)
|
||||||
@@ -1817,6 +1839,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Character.Controlled.dontFollowCursor = true;
|
Character.Controlled.dontFollowCursor = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HintManager.OnShowCommandInterface();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ToggleCommandUI()
|
private void ToggleCommandUI()
|
||||||
@@ -3218,14 +3242,14 @@ namespace Barotrauma
|
|||||||
#endif
|
#endif
|
||||||
if (order.Identifier == dismissedOrderPrefab.Identifier)
|
if (order.Identifier == dismissedOrderPrefab.Identifier)
|
||||||
{
|
{
|
||||||
return characters.FindAll(c => !c.IsDismissed).OrderBy(c => c.Info.DisplayName).ToList();
|
return characters.Union(GetOrderableFriendlyNPCs()).Where(c => !c.IsDismissed).OrderBy(c => c.Info.DisplayName).ToList();
|
||||||
}
|
}
|
||||||
return GetCharactersSortedForOrder(order, order.Identifier != "follow").ToList();
|
return GetCharactersSortedForOrder(order, order.Identifier != "follow").ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<Character> GetCharactersSortedForOrder(Order order, bool includeSelf)
|
private IEnumerable<Character> GetCharactersSortedForOrder(Order order, bool includeSelf)
|
||||||
{
|
{
|
||||||
return characters.FindAll(c => Character.Controlled == null || ((includeSelf || c != Character.Controlled) && c.TeamID == Character.Controlled.TeamID))
|
return characters.Where(c => Character.Controlled == null || ((includeSelf || c != Character.Controlled) && c.TeamID == Character.Controlled.TeamID)).Union(GetOrderableFriendlyNPCs())
|
||||||
// 1. Prioritize those who are on the same submarine than the controlled character
|
// 1. Prioritize those who are on the same submarine than the controlled character
|
||||||
.OrderByDescending(c => Character.Controlled == null || c.Submarine == Character.Controlled.Submarine)
|
.OrderByDescending(c => Character.Controlled == null || c.Submarine == Character.Controlled.Submarine)
|
||||||
// 2. Prioritize those who are already ordered to operate the item target of the new 'operate' order, or given the same maintenance order as now issued
|
// 2. Prioritize those who are already ordered to operate the item target of the new 'operate' order, or given the same maintenance order as now issued
|
||||||
@@ -3242,6 +3266,12 @@ namespace Barotrauma
|
|||||||
.ThenByDescending(c => c.GetSkillLevel(order.AppropriateSkill));
|
.ThenByDescending(c => c.GetSkillLevel(order.AppropriateSkill));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IEnumerable<Character> GetOrderableFriendlyNPCs()
|
||||||
|
{
|
||||||
|
return crewList.Content.Children.Where(c => c.UserData is Character character && character.TeamID == CharacterTeamType.FriendlyNPC).Select(c => (Character)c.UserData);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
new GUIMessageBox(
|
new GUIMessageBox(
|
||||||
mission.Prefab.IsSideObjective ? TextManager.AddPunctuation(':', TextManager.Get("sideobjective"), mission.Name) : mission.Name,
|
mission.Prefab.IsSideObjective ? TextManager.AddPunctuation(':', TextManager.Get("sideobjective"), mission.Name) : mission.Name,
|
||||||
mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon)
|
mission.Description, new string[0], type: GUIMessageBox.Type.InGame, icon: mission.Prefab.Icon, parseRichText: true)
|
||||||
{
|
{
|
||||||
IconColor = mission.Prefab.IconColor,
|
IconColor = mission.Prefab.IconColor,
|
||||||
UserData = "missionstartmessage"
|
UserData = "missionstartmessage"
|
||||||
|
|||||||
+26
-11
@@ -437,8 +437,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ShowCampaignUI = false;
|
ShowCampaignUI = false;
|
||||||
}
|
}
|
||||||
|
HintManager.OnAvailableTransition(transitionType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void End(TransitionType transitionType = TransitionType.None)
|
public override void End(TransitionType transitionType = TransitionType.None)
|
||||||
{
|
{
|
||||||
base.End(transitionType);
|
base.End(transitionType);
|
||||||
@@ -649,7 +651,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer);
|
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer);
|
||||||
|
|
||||||
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, mapSeed);
|
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, CampaignSettings.Unsure, mapSeed);
|
||||||
campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode;
|
campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode;
|
||||||
campaign.CampaignID = campaignID;
|
campaign.CampaignID = campaignID;
|
||||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||||
@@ -777,16 +779,29 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
pendingHires.Add(msg.ReadInt32());
|
pendingHires.Add(msg.ReadInt32());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validateHires = msg.ReadBoolean();
|
ushort hiredLength = msg.ReadUInt16();
|
||||||
|
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
|
||||||
|
for (int i = 0; i < hiredLength; i++)
|
||||||
|
{
|
||||||
|
CharacterInfo hired = CharacterInfo.ClientRead("human", msg);
|
||||||
|
hired.Salary = msg.ReadInt32();
|
||||||
|
hiredCharacters.Add(hired);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool renameCrewMember = msg.ReadBoolean();
|
||||||
|
if (renameCrewMember)
|
||||||
|
{
|
||||||
|
int renamedIdentifier = msg.ReadInt32();
|
||||||
|
string newName = msg.ReadString();
|
||||||
|
CharacterInfo renamedCharacter = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == renamedIdentifier);
|
||||||
|
if (renamedCharacter != null) { CrewManager.RenameCharacter(renamedCharacter, newName); }
|
||||||
|
}
|
||||||
|
|
||||||
bool fireCharacter = msg.ReadBoolean();
|
bool fireCharacter = msg.ReadBoolean();
|
||||||
|
|
||||||
int firedIdentifier = -1;
|
|
||||||
if (fireCharacter) { firedIdentifier = msg.ReadInt32(); }
|
|
||||||
|
|
||||||
if (fireCharacter)
|
if (fireCharacter)
|
||||||
{
|
{
|
||||||
|
int firedIdentifier = msg.ReadInt32();
|
||||||
CharacterInfo firedCharacter = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifier() == firedIdentifier);
|
CharacterInfo firedCharacter = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifier() == firedIdentifier);
|
||||||
// this one might and is allowed to be null since the character is already fired on the original sender's game
|
// this one might and is allowed to be null since the character is already fired on the original sender's game
|
||||||
if (firedCharacter != null) { CrewManager.FireCharacter(firedCharacter); }
|
if (firedCharacter != null) { CrewManager.FireCharacter(firedCharacter); }
|
||||||
@@ -794,10 +809,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (map?.CurrentLocation?.HireManager != null && CampaignUI?.CrewManagement != null)
|
if (map?.CurrentLocation?.HireManager != null && CampaignUI?.CrewManagement != null)
|
||||||
{
|
{
|
||||||
CampaignUI?.CrewManagement?.SetHireables(map.CurrentLocation, availableHires);
|
CampaignUI.CrewManagement.SetHireables(map.CurrentLocation, availableHires);
|
||||||
if (validateHires) { CampaignUI?.CrewManagement.ValidatePendingHires(); }
|
if (hiredCharacters.Any()) { CampaignUI.CrewManagement.ValidateHires(hiredCharacters); }
|
||||||
CampaignUI?.CrewManagement?.SetPendingHires(pendingHires, map?.CurrentLocation);
|
CampaignUI.CrewManagement.SetPendingHires(pendingHires, map.CurrentLocation);
|
||||||
if (fireCharacter) { CampaignUI?.CrewManagement.UpdateCrew(); }
|
if (renameCrewMember || fireCharacter) { CampaignUI.CrewManagement.UpdateCrew(); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-6
@@ -57,11 +57,12 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Instantiates a new single player campaign
|
/// Instantiates a new single player campaign
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private SinglePlayerCampaign(string mapSeed) : base(GameModePreset.SinglePlayerCampaign)
|
private SinglePlayerCampaign(string mapSeed, CampaignSettings settings) : base(GameModePreset.SinglePlayerCampaign)
|
||||||
{
|
{
|
||||||
CampaignMetadata = new CampaignMetadata(this);
|
CampaignMetadata = new CampaignMetadata(this);
|
||||||
UpgradeManager = new UpgradeManager(this);
|
UpgradeManager = new UpgradeManager(this);
|
||||||
map = new Map(this, mapSeed);
|
map = new Map(this, mapSeed, settings);
|
||||||
|
Settings = settings;
|
||||||
foreach (JobPrefab jobPrefab in JobPrefab.Prefabs)
|
foreach (JobPrefab jobPrefab in JobPrefab.Prefabs)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < jobPrefab.InitialCount; i++)
|
for (int i = 0; i < jobPrefab.InitialCount; i++)
|
||||||
@@ -85,11 +86,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
{
|
{
|
||||||
|
case "campaignsettings":
|
||||||
|
Settings = new CampaignSettings(subElement);
|
||||||
|
break;
|
||||||
case "crew":
|
case "crew":
|
||||||
GameMain.GameSession.CrewManager = new CrewManager(subElement, true);
|
GameMain.GameSession.CrewManager = new CrewManager(subElement, true);
|
||||||
break;
|
break;
|
||||||
case "map":
|
case "map":
|
||||||
map = Map.Load(this, subElement);
|
map = Map.Load(this, subElement, Settings);
|
||||||
break;
|
break;
|
||||||
case "metadata":
|
case "metadata":
|
||||||
CampaignMetadata = new CampaignMetadata(this, subElement);
|
CampaignMetadata = new CampaignMetadata(this, subElement);
|
||||||
@@ -141,9 +145,9 @@ namespace Barotrauma
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Start a completely new single player campaign
|
/// Start a completely new single player campaign
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static SinglePlayerCampaign StartNew(string mapSeed, SubmarineInfo selectedSub)
|
public static SinglePlayerCampaign StartNew(string mapSeed, SubmarineInfo selectedSub, CampaignSettings settings)
|
||||||
{
|
{
|
||||||
var campaign = new SinglePlayerCampaign(mapSeed);
|
var campaign = new SinglePlayerCampaign(mapSeed, settings);
|
||||||
return campaign;
|
return campaign;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,6 +612,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
ShowCampaignUI = false;
|
ShowCampaignUI = false;
|
||||||
}
|
}
|
||||||
|
HintManager.OnAvailableTransition(transitionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!crewDead)
|
if (!crewDead)
|
||||||
@@ -629,9 +634,9 @@ namespace Barotrauma
|
|||||||
if (nextLevel == null)
|
if (nextLevel == null)
|
||||||
{
|
{
|
||||||
//no level selected -> force the player to select one
|
//no level selected -> force the player to select one
|
||||||
|
ForceMapUI = true;
|
||||||
CampaignUI.SelectTab(InteractionType.Map);
|
CampaignUI.SelectTab(InteractionType.Map);
|
||||||
map.SelectLocation(-1);
|
map.SelectLocation(-1);
|
||||||
ForceMapUI = true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (transitionType == TransitionType.ProgressToNextEmptyLocation)
|
else if (transitionType == TransitionType.ProgressToNextEmptyLocation)
|
||||||
@@ -704,6 +709,7 @@ namespace Barotrauma
|
|||||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
||||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||||
new XAttribute("cheatsenabled", CheatsEnabled));
|
new XAttribute("cheatsenabled", CheatsEnabled));
|
||||||
|
modeElement.Add(Settings.Save());
|
||||||
|
|
||||||
//save and remove all items that are in someone's inventory so they don't get included in the sub file as well
|
//save and remove all items that are in someone's inventory so they don't get included in the sub file as well
|
||||||
foreach (Character c in Character.CharacterList)
|
foreach (Character c in Character.CharacterList)
|
||||||
|
|||||||
+4
-4
@@ -99,7 +99,7 @@ namespace Barotrauma.Tutorials
|
|||||||
captain_medicSpawnPos = Item.ItemList.Find(i => i.HasTag("captain_medicspawnpos")).WorldPosition;
|
captain_medicSpawnPos = Item.ItemList.Find(i => i.HasTag("captain_medicspawnpos")).WorldPosition;
|
||||||
tutorial_submarineDoor = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoor")).GetComponent<Door>();
|
tutorial_submarineDoor = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoor")).GetComponent<Door>();
|
||||||
tutorial_submarineDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoorlight")).GetComponent<LightComponent>();
|
tutorial_submarineDoorLight = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoorlight")).GetComponent<LightComponent>();
|
||||||
var medicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("medicaldoctor"));
|
var medicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("medicaldoctor"));
|
||||||
captain_medic = Character.Create(medicInfo, captain_medicSpawnPos, "medicaldoctor");
|
captain_medic = Character.Create(medicInfo, captain_medicSpawnPos, "medicaldoctor");
|
||||||
captain_medic.TeamID = CharacterTeamType.Team1;
|
captain_medic.TeamID = CharacterTeamType.Team1;
|
||||||
captain_medic.GiveJobItems(null);
|
captain_medic.GiveJobItems(null);
|
||||||
@@ -122,17 +122,17 @@ namespace Barotrauma.Tutorials
|
|||||||
SetDoorAccess(tutorial_lockedDoor_1, null, false);
|
SetDoorAccess(tutorial_lockedDoor_1, null, false);
|
||||||
SetDoorAccess(tutorial_lockedDoor_2, null, false);
|
SetDoorAccess(tutorial_lockedDoor_2, null, false);
|
||||||
|
|
||||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("mechanic"));
|
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("mechanic"));
|
||||||
captain_mechanic = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job, Submarine.MainSub).WorldPosition, "mechanic");
|
captain_mechanic = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job, Submarine.MainSub).WorldPosition, "mechanic");
|
||||||
captain_mechanic.TeamID = CharacterTeamType.Team1;
|
captain_mechanic.TeamID = CharacterTeamType.Team1;
|
||||||
captain_mechanic.GiveJobItems();
|
captain_mechanic.GiveJobItems();
|
||||||
|
|
||||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("securityofficer"));
|
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("securityofficer"));
|
||||||
captain_security = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job, Submarine.MainSub).WorldPosition, "securityofficer");
|
captain_security = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job, Submarine.MainSub).WorldPosition, "securityofficer");
|
||||||
captain_security.TeamID = CharacterTeamType.Team1;
|
captain_security.TeamID = CharacterTeamType.Team1;
|
||||||
captain_security.GiveJobItems();
|
captain_security.GiveJobItems();
|
||||||
|
|
||||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
||||||
captain_engineer = Character.Create(engineerInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job, Submarine.MainSub).WorldPosition, "engineer");
|
captain_engineer = Character.Create(engineerInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job, Submarine.MainSub).WorldPosition, "engineer");
|
||||||
captain_engineer.TeamID = CharacterTeamType.Team1;
|
captain_engineer.TeamID = CharacterTeamType.Team1;
|
||||||
captain_engineer.GiveJobItems();
|
captain_engineer.GiveJobItems();
|
||||||
|
|||||||
+5
-5
@@ -78,7 +78,7 @@ namespace Barotrauma.Tutorials
|
|||||||
var patientHull2 = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "airlock").CurrentHull;
|
var patientHull2 = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "airlock").CurrentHull;
|
||||||
medBay = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "medbay").CurrentHull;
|
medBay = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "medbay").CurrentHull;
|
||||||
|
|
||||||
var assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("assistant"));
|
var assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("assistant"));
|
||||||
patient1 = Character.Create(assistantInfo, patientHull1.WorldPosition, "1");
|
patient1 = Character.Create(assistantInfo, patientHull1.WorldPosition, "1");
|
||||||
patient1.TeamID = CharacterTeamType.Team1;
|
patient1.TeamID = CharacterTeamType.Team1;
|
||||||
patient1.GiveJobItems(null);
|
patient1.GiveJobItems(null);
|
||||||
@@ -86,26 +86,26 @@ namespace Barotrauma.Tutorials
|
|||||||
patient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 15.0f) }, stun: 0, playSound: false);
|
patient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 15.0f) }, stun: 0, playSound: false);
|
||||||
patient1.AIController.Enabled = false;
|
patient1.AIController.Enabled = false;
|
||||||
|
|
||||||
assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("assistant"));
|
assistantInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("assistant"));
|
||||||
patient2 = Character.Create(assistantInfo, patientHull2.WorldPosition, "2");
|
patient2 = Character.Create(assistantInfo, patientHull2.WorldPosition, "2");
|
||||||
patient2.TeamID = CharacterTeamType.Team1;
|
patient2.TeamID = CharacterTeamType.Team1;
|
||||||
patient2.GiveJobItems(null);
|
patient2.GiveJobItems(null);
|
||||||
patient2.CanSpeak = false;
|
patient2.CanSpeak = false;
|
||||||
patient2.AIController.Enabled = false;
|
patient2.AIController.Enabled = false;
|
||||||
|
|
||||||
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
var mechanicInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
||||||
var subPatient1 = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
var subPatient1 = Character.Create(mechanicInfo, WayPoint.GetRandom(SpawnType.Human, mechanicInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||||
subPatient1.TeamID = CharacterTeamType.Team1;
|
subPatient1.TeamID = CharacterTeamType.Team1;
|
||||||
subPatient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 40.0f) }, stun: 0, playSound: false);
|
subPatient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 40.0f) }, stun: 0, playSound: false);
|
||||||
subPatients.Add(subPatient1);
|
subPatients.Add(subPatient1);
|
||||||
|
|
||||||
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("securityofficer"));
|
var securityInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("securityofficer"));
|
||||||
var subPatient2 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
var subPatient2 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, securityInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||||
subPatient2.TeamID = CharacterTeamType.Team1;
|
subPatient2.TeamID = CharacterTeamType.Team1;
|
||||||
subPatient2.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.InternalDamage, 40.0f) }, stun: 0, playSound: false);
|
subPatient2.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.InternalDamage, 40.0f) }, stun: 0, playSound: false);
|
||||||
subPatients.Add(subPatient2);
|
subPatients.Add(subPatient2);
|
||||||
|
|
||||||
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer"));
|
var engineerInfo = new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer"));
|
||||||
var subPatient3 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
var subPatient3 = Character.Create(securityInfo, WayPoint.GetRandom(SpawnType.Human, engineerInfo.Job, Submarine.MainSub).WorldPosition, "3");
|
||||||
subPatient3.TeamID = CharacterTeamType.Team1;
|
subPatient3.TeamID = CharacterTeamType.Team1;
|
||||||
subPatient3.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 20.0f) }, stun: 0, playSound: false);
|
subPatient3.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 20.0f) }, stun: 0, playSound: false);
|
||||||
|
|||||||
+1
-1
@@ -110,7 +110,7 @@ namespace Barotrauma.Tutorials
|
|||||||
}
|
}
|
||||||
|
|
||||||
CharacterInfo charInfo = configElement.Element("Character") == null ?
|
CharacterInfo charInfo = configElement.Element("Character") == null ?
|
||||||
new CharacterInfo(CharacterPrefab.HumanSpeciesName, "", JobPrefab.Get("engineer")) :
|
new CharacterInfo(CharacterPrefab.HumanSpeciesName, jobPrefab: JobPrefab.Get("engineer")) :
|
||||||
new CharacterInfo(configElement.Element("Character"));
|
new CharacterInfo(configElement.Element("Character"));
|
||||||
|
|
||||||
WayPoint wayPoint = GetSpawnPoint(charInfo);
|
WayPoint wayPoint = GetSpawnPoint(charInfo);
|
||||||
|
|||||||
+3
-3
@@ -535,15 +535,15 @@ namespace Barotrauma.Tutorials
|
|||||||
titleBlock.RectTransform.IsFixedSize = true;
|
titleBlock.RectTransform.IsFixedSize = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RichTextData> richTextData = RichTextData.GetRichTextData(text, out text);
|
List<RichTextData> richTextData = RichTextData.GetRichTextData(" " + text, out text);
|
||||||
GUITextBlock textBlock;
|
GUITextBlock textBlock;
|
||||||
if (richTextData == null)
|
if (richTextData == null)
|
||||||
{
|
{
|
||||||
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), " " + text, wrap: true);
|
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), text, wrap: true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), richTextData, " " + text, wrap: true);
|
textBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), richTextData, text, wrap: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
textBlock.RectTransform.IsFixedSize = true;
|
textBlock.RectTransform.IsFixedSize = true;
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HintManager.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch)
|
public void Draw(SpriteBatch spriteBatch)
|
||||||
|
|||||||
@@ -336,7 +336,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", displayedMission.Reward));
|
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", displayedMission.Reward));
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||||
TextManager.GetWithVariable("MissionReward", "[reward]", rewardText));
|
TextManager.GetWithVariable("MissionReward", "[reward]", rewardText), parseRichText: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayedMission != missionsToDisplay.Last())
|
if (displayedMission != missionsToDisplay.Last())
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace Barotrauma
|
|||||||
Audio,
|
Audio,
|
||||||
VoiceChat,
|
VoiceChat,
|
||||||
Controls,
|
Controls,
|
||||||
|
Gameplay,
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Debug
|
Debug
|
||||||
#endif
|
#endif
|
||||||
@@ -532,29 +533,19 @@ namespace Barotrauma
|
|||||||
UserData = tab
|
UserData = tab
|
||||||
};
|
};
|
||||||
|
|
||||||
float tabWidth = 0.25f;
|
float tabWidth = 1.0f / tabs.Length;
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
tabWidth = 0.2f;
|
string buttonText = tab != Tab.Debug ? TextManager.Get("SettingsTab." + tab.ToString()) : "Debug";
|
||||||
if (tab != Tab.Debug)
|
#else
|
||||||
{
|
string buttonText = TextManager.Get("SettingsTab." + tab.ToString());
|
||||||
#endif
|
#endif
|
||||||
tabButtons[(int)tab] = new GUIButton(new RectTransform(new Vector2(tabWidth, 1.0f), tabButtonHolder.RectTransform),
|
|
||||||
TextManager.Get("SettingsTab." + tab.ToString()), style: "GUITabButton")
|
tabButtons[(int)tab] = new GUIButton(new RectTransform(new Vector2(tabWidth, 1.0f), tabButtonHolder.RectTransform), style: "GUITabButton")
|
||||||
{
|
|
||||||
UserData = tab,
|
|
||||||
OnClicked = (bt, userdata) => { SelectTab((Tab)userdata); return true; }
|
|
||||||
};
|
|
||||||
#if DEBUG
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
tabButtons[(int)tab] = new GUIButton(new RectTransform(new Vector2(tabWidth, 1.0f), tabButtonHolder.RectTransform), "Debug", style: "GUITabButton")
|
UserData = tab,
|
||||||
{
|
OnClicked = (bt, userdata) => { SelectTab((Tab)userdata); return true; }
|
||||||
UserData = tab,
|
};
|
||||||
OnClicked = (bt, userdata) => { SelectTab((Tab)userdata); return true; }
|
tabButtons[(int)tab].Text = ToolBox.LimitString(buttonText, tabButtons[(int)tab].Font, (int)(0.75f * tabWidth * tabButtonHolder.Rect.Width));
|
||||||
};
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new GUIButton(new RectTransform(new Vector2(0.05f, 0.75f), tabButtonHolder.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.0f, 0.2f) }, style: "GUIBugButton")
|
new GUIButton(new RectTransform(new Vector2(0.05f, 0.75f), tabButtonHolder.RectTransform, Anchor.BottomRight) { RelativeOffset = new Vector2(0.0f, 0.2f) }, style: "GUIBugButton")
|
||||||
@@ -669,19 +660,6 @@ namespace Barotrauma
|
|||||||
Selected = TextureCompressionEnabled
|
Selected = TextureCompressionEnabled
|
||||||
};
|
};
|
||||||
|
|
||||||
GUITickBox pauseOnFocusLostBox = new GUITickBox(new RectTransform(tickBoxScale, leftColumn.RectTransform),
|
|
||||||
TextManager.Get("PauseOnFocusLost"))
|
|
||||||
{
|
|
||||||
Selected = PauseOnFocusLost,
|
|
||||||
ToolTip = TextManager.Get("PauseOnFocusLostToolTip"),
|
|
||||||
OnSelected = (tickBox) =>
|
|
||||||
{
|
|
||||||
PauseOnFocusLost = tickBox.Selected;
|
|
||||||
UnsavedSettings = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
GUITextBlock particleLimitText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("ParticleLimit"), font: GUI.SubHeadingFont, wrap: true);
|
GUITextBlock particleLimitText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("ParticleLimit"), font: GUI.SubHeadingFont, wrap: true);
|
||||||
GUIScrollBar particleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), style: "GUISlider",
|
GUIScrollBar particleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), style: "GUISlider",
|
||||||
barSize: 0.1f)
|
barSize: 0.1f)
|
||||||
@@ -773,56 +751,6 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
GUITextBlock HUDScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("HUDScale"), font: GUI.SubHeadingFont, wrap: true);
|
|
||||||
GUIScrollBar HUDScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
|
|
||||||
style: "GUISlider", barSize: 0.1f)
|
|
||||||
{
|
|
||||||
UserData = HUDScaleText,
|
|
||||||
BarScroll = (HUDScale - MinHUDScale) / (MaxHUDScale - MinHUDScale),
|
|
||||||
OnMoved = (scrollBar, scroll) =>
|
|
||||||
{
|
|
||||||
HUDScale = MathHelper.Lerp(MinHUDScale, MaxHUDScale, scroll);
|
|
||||||
ChangeSliderText(scrollBar, HUDScale);
|
|
||||||
OnHUDScaleChanged?.Invoke();
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
Step = 0.02f
|
|
||||||
};
|
|
||||||
HUDScaleScrollBar.OnMoved(HUDScaleScrollBar, HUDScaleScrollBar.BarScroll);
|
|
||||||
|
|
||||||
GUITextBlock inventoryScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("InventoryScale"), font: GUI.SubHeadingFont);
|
|
||||||
GUIScrollBar inventoryScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
|
|
||||||
style: "GUISlider", barSize: 0.1f)
|
|
||||||
{
|
|
||||||
UserData = inventoryScaleText,
|
|
||||||
BarScroll = (InventoryScale - MinInventoryScale) / (MaxInventoryScale - MinInventoryScale),
|
|
||||||
OnMoved = (scrollBar, scroll) =>
|
|
||||||
{
|
|
||||||
InventoryScale = MathHelper.Lerp(MinInventoryScale, MaxInventoryScale, scroll);
|
|
||||||
ChangeSliderText(scrollBar, InventoryScale);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
Step = 0.02f
|
|
||||||
};
|
|
||||||
inventoryScaleScrollBar.OnMoved(inventoryScaleScrollBar, inventoryScaleScrollBar.BarScroll);
|
|
||||||
|
|
||||||
GUITextBlock textScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), TextManager.Get("TextScale"), font: GUI.SubHeadingFont);
|
|
||||||
GUIScrollBar textScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform),
|
|
||||||
style: "GUISlider", barSize: 0.1f)
|
|
||||||
{
|
|
||||||
UserData = textScaleText,
|
|
||||||
BarScroll = (TextScale - MinTextScale) / (MaxTextScale - MinTextScale),
|
|
||||||
OnMoved = (scrollBar, scroll) =>
|
|
||||||
{
|
|
||||||
TextScale = MathHelper.Lerp(MinTextScale, MaxTextScale, scroll);
|
|
||||||
textScaleDirty = true;
|
|
||||||
ChangeSliderText(scrollBar, TextScale);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
Step = 0.01f
|
|
||||||
};
|
|
||||||
textScaleScrollBar.OnMoved(textScaleScrollBar, textScaleScrollBar.BarScroll);
|
|
||||||
|
|
||||||
/// Audio tab ----------------------------------------------------------------
|
/// Audio tab ----------------------------------------------------------------
|
||||||
|
|
||||||
var audioContent = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 0.97f), tabs[(int)Tab.Audio].RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
|
var audioContent = new GUILayoutGroup(new RectTransform(new Vector2(0.97f, 0.97f), tabs[(int)Tab.Audio].RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
|
||||||
@@ -1380,6 +1308,88 @@ namespace Barotrauma
|
|||||||
GUITextBlock.AutoScaleAndNormalize(defaultBindingsButton.TextBlock, legacyBindingsButton.TextBlock);
|
GUITextBlock.AutoScaleAndNormalize(defaultBindingsButton.TextBlock, legacyBindingsButton.TextBlock);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Gameplay tab -------------------------------------------------------------
|
||||||
|
var gameplaySettingsGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.46f, 0.95f), tabs[(int)Tab.Gameplay].RectTransform, Anchor.TopLeft)
|
||||||
|
{ RelativeOffset = new Vector2(0.025f, 0.02f) })
|
||||||
|
{ RelativeSpacing = 0.01f };
|
||||||
|
|
||||||
|
GUITickBox pauseOnFocusLostBox = new GUITickBox(new RectTransform(tickBoxScale, gameplaySettingsGroup.RectTransform),
|
||||||
|
TextManager.Get("PauseOnFocusLost"))
|
||||||
|
{
|
||||||
|
Selected = PauseOnFocusLost,
|
||||||
|
ToolTip = TextManager.Get("PauseOnFocusLostToolTip"),
|
||||||
|
OnSelected = (tickBox) =>
|
||||||
|
{
|
||||||
|
PauseOnFocusLost = tickBox.Selected;
|
||||||
|
UnsavedSettings = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GUITickBox disableInGameHintsBox = new GUITickBox(new RectTransform(tickBoxScale, gameplaySettingsGroup.RectTransform),
|
||||||
|
TextManager.Get("DisableInGameHints"))
|
||||||
|
{
|
||||||
|
Selected = DisableInGameHints,
|
||||||
|
ToolTip = TextManager.Get("DisableInGameHintsToolTip"),
|
||||||
|
OnSelected = (tickBox) =>
|
||||||
|
{
|
||||||
|
DisableInGameHints = tickBox.Selected;
|
||||||
|
UnsavedSettings = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GUITextBlock HUDScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform), TextManager.Get("HUDScale"), font: GUI.SubHeadingFont, wrap: true);
|
||||||
|
GUIScrollBar HUDScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform),
|
||||||
|
style: "GUISlider", barSize: 0.1f)
|
||||||
|
{
|
||||||
|
UserData = HUDScaleText,
|
||||||
|
BarScroll = (HUDScale - MinHUDScale) / (MaxHUDScale - MinHUDScale),
|
||||||
|
OnMoved = (scrollBar, scroll) =>
|
||||||
|
{
|
||||||
|
HUDScale = MathHelper.Lerp(MinHUDScale, MaxHUDScale, scroll);
|
||||||
|
ChangeSliderText(scrollBar, HUDScale);
|
||||||
|
OnHUDScaleChanged?.Invoke();
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
Step = 0.02f
|
||||||
|
};
|
||||||
|
HUDScaleScrollBar.OnMoved(HUDScaleScrollBar, HUDScaleScrollBar.BarScroll);
|
||||||
|
|
||||||
|
GUITextBlock inventoryScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform), TextManager.Get("InventoryScale"), font: GUI.SubHeadingFont);
|
||||||
|
GUIScrollBar inventoryScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform),
|
||||||
|
style: "GUISlider", barSize: 0.1f)
|
||||||
|
{
|
||||||
|
UserData = inventoryScaleText,
|
||||||
|
BarScroll = (InventoryScale - MinInventoryScale) / (MaxInventoryScale - MinInventoryScale),
|
||||||
|
OnMoved = (scrollBar, scroll) =>
|
||||||
|
{
|
||||||
|
InventoryScale = MathHelper.Lerp(MinInventoryScale, MaxInventoryScale, scroll);
|
||||||
|
ChangeSliderText(scrollBar, InventoryScale);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
Step = 0.02f
|
||||||
|
};
|
||||||
|
inventoryScaleScrollBar.OnMoved(inventoryScaleScrollBar, inventoryScaleScrollBar.BarScroll);
|
||||||
|
|
||||||
|
GUITextBlock textScaleText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform), TextManager.Get("TextScale"), font: GUI.SubHeadingFont);
|
||||||
|
GUIScrollBar textScaleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), gameplaySettingsGroup.RectTransform),
|
||||||
|
style: "GUISlider", barSize: 0.1f)
|
||||||
|
{
|
||||||
|
UserData = textScaleText,
|
||||||
|
BarScroll = (TextScale - MinTextScale) / (MaxTextScale - MinTextScale),
|
||||||
|
OnMoved = (scrollBar, scroll) =>
|
||||||
|
{
|
||||||
|
TextScale = MathHelper.Lerp(MinTextScale, MaxTextScale, scroll);
|
||||||
|
textScaleDirty = true;
|
||||||
|
ChangeSliderText(scrollBar, TextScale);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
Step = 0.01f
|
||||||
|
};
|
||||||
|
textScaleScrollBar.OnMoved(textScaleScrollBar, textScaleScrollBar.BarScroll);
|
||||||
|
|
||||||
|
/// Bottom buttons -------------------------------------------------------------
|
||||||
new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonArea.RectTransform, Anchor.BottomLeft),
|
new GUIButton(new RectTransform(new Vector2(0.3f, 1.0f), buttonArea.RectTransform, Anchor.BottomLeft),
|
||||||
TextManager.Get("Cancel"))
|
TextManager.Get("Cancel"))
|
||||||
{
|
{
|
||||||
@@ -1465,55 +1475,54 @@ namespace Barotrauma
|
|||||||
{ RelativeOffset = new Vector2(0.02f, 0.02f) })
|
{ RelativeOffset = new Vector2(0.02f, 0.02f) })
|
||||||
{ RelativeSpacing = 0.01f };
|
{ RelativeSpacing = 0.01f };
|
||||||
|
|
||||||
var automaticQuickStartTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "Automatic quickstart enabled", style: "GUITickBox");
|
void addDebugTickBox(bool initialValue, Action<bool> set, string label, string tooltip)
|
||||||
automaticQuickStartTickBox.Selected = AutomaticQuickStartEnabled;
|
|
||||||
automaticQuickStartTickBox.ToolTip = "Will the game automatically move on to Quickstart when the game is launched";
|
|
||||||
automaticQuickStartTickBox.OnSelected = (tickBox) =>
|
|
||||||
{
|
{
|
||||||
AutomaticQuickStartEnabled = tickBox.Selected;
|
var tickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), label, style: "GUITickBox");
|
||||||
UnsavedSettings = true;
|
tickBox.Selected = initialValue;
|
||||||
return true;
|
tickBox.ToolTip = tooltip;
|
||||||
};
|
tickBox.OnSelected = (tickBox) =>
|
||||||
|
{
|
||||||
|
set(tickBox.Selected);
|
||||||
|
UnsavedSettings = true;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var automaticCampaignLoadTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "Automatic campaign load enabled", style: "GUITickBox");
|
addDebugTickBox(
|
||||||
automaticCampaignLoadTickBox.Selected = AutomaticCampaignLoadEnabled;
|
AutomaticQuickStartEnabled,
|
||||||
automaticCampaignLoadTickBox.ToolTip = "Will the game automatically load the latest campaign save when the game is launched";
|
(b) => AutomaticQuickStartEnabled = b,
|
||||||
automaticCampaignLoadTickBox.OnSelected = (tickBox) =>
|
"Automatic quickstart enabled",
|
||||||
{
|
"Will the game automatically move on to Quickstart when the game is launched");
|
||||||
AutomaticCampaignLoadEnabled = tickBox.Selected;
|
|
||||||
UnsavedSettings = true;
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var showSplashScreenTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "Splash screen enabled", style: "GUITickBox");
|
addDebugTickBox(
|
||||||
showSplashScreenTickBox.Selected = EnableSplashScreen;
|
AutomaticCampaignLoadEnabled,
|
||||||
showSplashScreenTickBox.ToolTip = "Are the splash screens shown when the game is launched";
|
(b) => AutomaticCampaignLoadEnabled = b,
|
||||||
showSplashScreenTickBox.OnSelected = (tickBox) =>
|
"Automatic campaign load enabled",
|
||||||
{
|
"Will the game automatically load the latest campaign save when the game is launched");
|
||||||
EnableSplashScreen = tickBox.Selected;
|
|
||||||
UnsavedSettings = true;
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var verboseLoggingTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "Verbose logging enabled", style: "GUITickBox");
|
addDebugTickBox(
|
||||||
verboseLoggingTickBox.Selected = VerboseLogging;
|
EnableSplashScreen,
|
||||||
verboseLoggingTickBox.ToolTip = "Should verbose logging be used";
|
(b) => EnableSplashScreen = b,
|
||||||
verboseLoggingTickBox.OnSelected = (tickBox) =>
|
"Splash screen enabled",
|
||||||
{
|
"Are the splash screens shown when the game is launched");
|
||||||
VerboseLogging = tickBox.Selected;
|
|
||||||
UnsavedSettings = true;
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
var textManagerDebugModeTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "TextManager debug mode enabled", style: "GUITickBox");
|
addDebugTickBox(
|
||||||
textManagerDebugModeTickBox.Selected = TextManagerDebugModeEnabled;
|
VerboseLogging,
|
||||||
textManagerDebugModeTickBox.ToolTip = "Does the TextManager return the text tags for debug purposes?";
|
(b) => VerboseLogging = b,
|
||||||
textManagerDebugModeTickBox.OnSelected = (tickBox) =>
|
"Verbose logging enabled",
|
||||||
{
|
"Should verbose logging be used");
|
||||||
TextManagerDebugModeEnabled = tickBox.Selected;
|
|
||||||
UnsavedSettings = true;
|
addDebugTickBox(
|
||||||
return true;
|
TextManagerDebugModeEnabled,
|
||||||
};
|
(b) => TextManagerDebugModeEnabled = b,
|
||||||
|
"TextManager debug mode enabled",
|
||||||
|
"Does the TextManager return the text tags for debug purposes?");
|
||||||
|
|
||||||
|
addDebugTickBox(
|
||||||
|
ModBreakerMode,
|
||||||
|
(b) => ModBreakerMode = b,
|
||||||
|
"Mod breaker mode enabled",
|
||||||
|
"Do horrible things when loading mods to see if it breaks?");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
UnsavedSettings = false; // Reset unsaved settings to false once the UI has been created
|
UnsavedSettings = false; // Reset unsaved settings to false once the UI has been created
|
||||||
|
|||||||
@@ -639,7 +639,13 @@ namespace Barotrauma
|
|||||||
foreach (Item doubleClickedItem in doubleClickedItems)
|
foreach (Item doubleClickedItem in doubleClickedItems)
|
||||||
{
|
{
|
||||||
QuickUseItem(doubleClickedItem, true, true, true, quickUseAction, playSound: doubleClickedItem == doubleClickedItems.First());
|
QuickUseItem(doubleClickedItem, true, true, true, quickUseAction, playSound: doubleClickedItem == doubleClickedItems.First());
|
||||||
if (quickUseAction == QuickUseAction.Equip || quickUseAction == QuickUseAction.UseTreatment || !IsInLimbSlot(doubleClickedItem, InvSlotType.Any))
|
//only use one item if we're equipping or using it as a treatment
|
||||||
|
if (quickUseAction == QuickUseAction.Equip || quickUseAction == QuickUseAction.UseTreatment)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//if the item was put in a limb slot, only put one item from the stack
|
||||||
|
if (doubleClickedItem.ParentInventory == this && !IsInLimbSlot(doubleClickedItem, InvSlotType.Any))
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -810,6 +816,8 @@ namespace Barotrauma
|
|||||||
highlightedSubInventorySlot.Inventory.HideTimer = 0.0f;
|
highlightedSubInventorySlot.Inventory.HideTimer = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HintManager.OnShowSubInventory(slotRef?.Item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AssignQuickUseNumKeys()
|
public void AssignQuickUseNumKeys()
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
private Pair<Rectangle, string> tooltip;
|
private Pair<Rectangle, string> tooltip;
|
||||||
|
|
||||||
|
private GUITextBlock requiredTimeBlock;
|
||||||
|
|
||||||
partial void InitProjSpecific()
|
partial void InitProjSpecific()
|
||||||
{
|
{
|
||||||
CreateGUI();
|
CreateGUI();
|
||||||
@@ -522,7 +524,7 @@ namespace Barotrauma.Items.Components
|
|||||||
AutoScaleHorizontal = true,
|
AutoScaleHorizontal = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), ToolBox.SecondsToReadableTime(requiredTime),
|
requiredTimeBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedReqFrame.RectTransform), ToolBox.SecondsToReadableTime(requiredTime),
|
||||||
font: GUI.SmallFont);
|
font: GUI.SmallFont);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -606,6 +608,12 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
partial void UpdateRequiredTimeProjSpecific()
|
||||||
|
{
|
||||||
|
if (requiredTimeBlock == null) { return; }
|
||||||
|
requiredTimeBlock.Text = ToolBox.SecondsToReadableTime(timeUntilReady > 0.0f ? timeUntilReady : requiredTime);
|
||||||
|
}
|
||||||
|
|
||||||
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
public void ClientWrite(IWriteMessage msg, object[] extraData = null)
|
||||||
{
|
{
|
||||||
int itemIndex = pendingFabricatedItem == null ? -1 : fabricationRecipes.IndexOf(pendingFabricatedItem);
|
int itemIndex = pendingFabricatedItem == null ? -1 : fabricationRecipes.IndexOf(pendingFabricatedItem);
|
||||||
|
|||||||
@@ -1380,6 +1380,7 @@ namespace Barotrauma.Items.Components
|
|||||||
MathHelper.Clamp(c.Mass * 0.03f, 0.1f, 2.0f));
|
MathHelper.Clamp(c.Mass * 0.03f, 0.1f, 2.0f));
|
||||||
if (!passive && !CheckBlipVisibility(blip, transducerPos)) { continue; }
|
if (!passive && !CheckBlipVisibility(blip, transducerPos)) { continue; }
|
||||||
sonarBlips.Add(blip);
|
sonarBlips.Add(blip);
|
||||||
|
HintManager.OnSonarSpottedCharacter(Item, c);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1399,6 +1400,7 @@ namespace Barotrauma.Items.Components
|
|||||||
MathHelper.Clamp(limb.Mass * 0.1f, 0.1f, 2.0f));
|
MathHelper.Clamp(limb.Mass * 0.1f, 0.1f, 2.0f));
|
||||||
if (!passive && !CheckBlipVisibility(blip, transducerPos)) { continue; }
|
if (!passive && !CheckBlipVisibility(blip, transducerPos)) { continue; }
|
||||||
sonarBlips.Add(blip);
|
sonarBlips.Add(blip);
|
||||||
|
HintManager.OnSonarSpottedCharacter(Item, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -357,8 +357,8 @@ namespace Barotrauma.Items.Components
|
|||||||
DockingSources.Any(d => d.Docked && (d.DockingTarget?.Item.Submarine?.Info?.IsOutpost ?? false)))
|
DockingSources.Any(d => d.Docked && (d.DockingTarget?.Item.Submarine?.Info?.IsOutpost ?? false)))
|
||||||
{
|
{
|
||||||
// Undocking from an outpost
|
// Undocking from an outpost
|
||||||
campaign.CampaignUI.SelectTab(CampaignMode.InteractionType.Map);
|
|
||||||
campaign.ShowCampaignUI = true;
|
campaign.ShowCampaignUI = true;
|
||||||
|
campaign.CampaignUI.SelectTab(CampaignMode.InteractionType.Map);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (!Level.IsLoadedOutpost && DockingModeEnabled && ActiveDockingSource != null &&
|
else if (!Level.IsLoadedOutpost && DockingModeEnabled && ActiveDockingSource != null &&
|
||||||
@@ -748,7 +748,7 @@ namespace Barotrauma.Items.Components
|
|||||||
}
|
}
|
||||||
if (!AutoPilot && Character.DisableControls && GUI.KeyboardDispatcher.Subscriber == null)
|
if (!AutoPilot && Character.DisableControls && GUI.KeyboardDispatcher.Subscriber == null)
|
||||||
{
|
{
|
||||||
steeringAdjustSpeed = character == null ? 0.2f : MathHelper.Lerp(0.2f, 1.0f, character.GetSkillLevel("helm") / 100.0f);
|
steeringAdjustSpeed = character == null ? DefaultSteeringAdjustSpeed : MathHelper.Lerp(0.2f, 1.0f, character.GetSkillLevel("helm") / 100.0f);
|
||||||
Vector2 input = Vector2.Zero;
|
Vector2 input = Vector2.Zero;
|
||||||
if (PlayerInput.KeyDown(InputType.Left)) { input -= Vector2.UnitX; }
|
if (PlayerInput.KeyDown(InputType.Left)) { input -= Vector2.UnitX; }
|
||||||
if (PlayerInput.KeyDown(InputType.Right)) { input += Vector2.UnitX; }
|
if (PlayerInput.KeyDown(InputType.Right)) { input += Vector2.UnitX; }
|
||||||
|
|||||||
@@ -98,8 +98,11 @@ namespace Barotrauma.Items.Components
|
|||||||
|
|
||||||
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
public override void UpdateHUD(Character character, float deltaTime, Camera cam)
|
||||||
{
|
{
|
||||||
float chargeRatio = charge / capacity;
|
if (chargeIndicator != null)
|
||||||
chargeIndicator.Color = ToolBox.GradientLerp(chargeRatio, Color.Red, Color.Orange, Color.Green);
|
{
|
||||||
|
float chargeRatio = charge / capacity;
|
||||||
|
chargeIndicator.Color = ToolBox.GradientLerp(chargeRatio, Color.Red, Color.Orange, Color.Green);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
public void Draw(SpriteBatch spriteBatch, bool editing = false, float itemDepth = -1)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ namespace Barotrauma.Items.Components
|
|||||||
SpriteEffects.None,
|
SpriteEffects.None,
|
||||||
depth);
|
depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private static Sprite defaultWireSprite;
|
private static Sprite defaultWireSprite;
|
||||||
private Sprite overrideSprite;
|
private Sprite overrideSprite;
|
||||||
private Sprite wireSprite;
|
private Sprite wireSprite;
|
||||||
|
|||||||
@@ -167,11 +167,11 @@ namespace Barotrauma.Items.Components
|
|||||||
{
|
{
|
||||||
if (DockingTarget.joint != null)
|
if (DockingTarget.joint != null)
|
||||||
{
|
{
|
||||||
DockingTarget.Lock(isNetworkMessage: true, forcePosition: true);
|
DockingTarget.Lock(isNetworkMessage: true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Lock(isNetworkMessage: true, forcePosition: true);
|
Lock(isNetworkMessage: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -327,10 +327,11 @@ namespace Barotrauma
|
|||||||
Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom;
|
Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom;
|
||||||
if (!rect.Contains(pos)) { continue; }
|
if (!rect.Contains(pos)) { continue; }
|
||||||
|
|
||||||
float iconScale = generationParams.LocationIconSize / location.Type.Sprite.size.X;
|
Sprite locationSprite = location.IsCriticallyRadiated() ? location.Type.RadiationSprite ?? location.Type.Sprite : location.Type.Sprite;
|
||||||
|
float iconScale = generationParams.LocationIconSize / locationSprite.size.X;
|
||||||
if (location == CurrentDisplayLocation) { iconScale *= 1.2f; }
|
if (location == CurrentDisplayLocation) { iconScale *= 1.2f; }
|
||||||
|
|
||||||
Rectangle drawRect = location.Type.Sprite.SourceRect;
|
Rectangle drawRect = locationSprite.SourceRect;
|
||||||
drawRect.Width = (int)(drawRect.Width * iconScale * zoom * 1.4f);
|
drawRect.Width = (int)(drawRect.Width * iconScale * zoom * 1.4f);
|
||||||
drawRect.Height = (int)(drawRect.Height * iconScale * zoom * 1.4f);
|
drawRect.Height = (int)(drawRect.Height * iconScale * zoom * 1.4f);
|
||||||
drawRect.X = (int)pos.X - drawRect.Width / 2;
|
drawRect.X = (int)pos.X - drawRect.Width / 2;
|
||||||
@@ -375,13 +376,18 @@ namespace Barotrauma
|
|||||||
foreach (LocationConnection connection in Connections)
|
foreach (LocationConnection connection in Connections)
|
||||||
{
|
{
|
||||||
if (HighlightedLocation != CurrentDisplayLocation &&
|
if (HighlightedLocation != CurrentDisplayLocation &&
|
||||||
connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(CurrentDisplayLocation))
|
connection.Locations.Contains(HighlightedLocation) &&
|
||||||
|
connection.Locations.Contains(CurrentDisplayLocation))
|
||||||
{
|
{
|
||||||
if (PlayerInput.PrimaryMouseButtonClicked() &&
|
if (PlayerInput.PrimaryMouseButtonClicked() &&
|
||||||
SelectedLocation != HighlightedLocation && HighlightedLocation != null)
|
SelectedLocation != HighlightedLocation && HighlightedLocation != null)
|
||||||
{
|
{
|
||||||
|
if (connection.Locked)
|
||||||
|
{
|
||||||
|
new GUIMessageBox(string.Empty, TextManager.Get("LockedPathTooltip"));
|
||||||
|
}
|
||||||
//clients aren't allowed to select the location without a permission
|
//clients aren't allowed to select the location without a permission
|
||||||
if ((GameMain.GameSession?.GameMode as CampaignMode)?.AllowedToManageCampaign() ?? false)
|
else if ((GameMain.GameSession?.GameMode as CampaignMode)?.AllowedToManageCampaign() ?? false)
|
||||||
{
|
{
|
||||||
connectionHighlightState = 0.0f;
|
connectionHighlightState = 0.0f;
|
||||||
SelectedConnection = connection;
|
SelectedConnection = connection;
|
||||||
@@ -517,8 +523,6 @@ namespace Barotrauma
|
|||||||
float rawNoiseScale = 1.0f + PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1));
|
float rawNoiseScale = 1.0f + PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1));
|
||||||
cameraNoiseStrength = PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1));
|
cameraNoiseStrength = PerlinNoise.GetPerlin((int)(Timing.TotalTime * 1 - 1), (int)(Timing.TotalTime * 1 - 1));
|
||||||
|
|
||||||
Radiation.Draw(spriteBatch, rect, zoom);
|
|
||||||
|
|
||||||
noiseOverlay.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(),
|
noiseOverlay.DrawTiled(spriteBatch, rect.Location.ToVector2(), rect.Size.ToVector2(),
|
||||||
startOffset: new Vector2(Rand.Range(0.0f, noiseOverlay.SourceRect.Width), Rand.Range(0.0f, noiseOverlay.SourceRect.Height)),
|
startOffset: new Vector2(Rand.Range(0.0f, noiseOverlay.SourceRect.Width), Rand.Range(0.0f, noiseOverlay.SourceRect.Height)),
|
||||||
color : Color.White * cameraNoiseStrength * 0.1f,
|
color : Color.White * cameraNoiseStrength * 0.1f,
|
||||||
@@ -534,6 +538,8 @@ namespace Barotrauma
|
|||||||
color: Color.White * cameraNoiseStrength * 0.1f,
|
color: Color.White * cameraNoiseStrength * 0.1f,
|
||||||
textureScale: Vector2.One * noiseScale);
|
textureScale: Vector2.One * noiseScale);
|
||||||
|
|
||||||
|
Radiation.Draw(spriteBatch, rect, zoom);
|
||||||
|
|
||||||
Pair<Rectangle, string> tooltip = null;
|
Pair<Rectangle, string> tooltip = null;
|
||||||
if (generationParams.ShowLocations)
|
if (generationParams.ShowLocations)
|
||||||
{
|
{
|
||||||
@@ -548,8 +554,10 @@ namespace Barotrauma
|
|||||||
Location location = Locations[i];
|
Location location = Locations[i];
|
||||||
if (IsInFogOfWar(location)) { continue; }
|
if (IsInFogOfWar(location)) { continue; }
|
||||||
Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom;
|
Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom;
|
||||||
|
|
||||||
Rectangle drawRect = location.Type.Sprite.SourceRect;
|
Sprite locationSprite = location.IsCriticallyRadiated() ? location.Type.RadiationSprite ?? location.Type.Sprite : location.Type.Sprite;
|
||||||
|
|
||||||
|
Rectangle drawRect = locationSprite.SourceRect;
|
||||||
drawRect.X = (int)pos.X - drawRect.Width / 2;
|
drawRect.X = (int)pos.X - drawRect.Width / 2;
|
||||||
drawRect.Y = (int)pos.Y - drawRect.Width / 2;
|
drawRect.Y = (int)pos.Y - drawRect.Width / 2;
|
||||||
|
|
||||||
@@ -562,20 +570,14 @@ namespace Barotrauma
|
|||||||
color *= 0.5f;
|
color *= 0.5f;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO proper visualization of this
|
|
||||||
if (location.Type.HasOutpost && !location.HasOutpost())
|
|
||||||
{
|
|
||||||
color = GUI.Style.Red;
|
|
||||||
}
|
|
||||||
|
|
||||||
float iconScale = location == CurrentDisplayLocation ? 1.2f : 1.0f;
|
float iconScale = location == CurrentDisplayLocation ? 1.2f : 1.0f;
|
||||||
if (location == HighlightedLocation)
|
if (location == HighlightedLocation)
|
||||||
{
|
{
|
||||||
iconScale *= 1.2f;
|
iconScale *= 1.2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
location.Type.Sprite.Draw(spriteBatch, pos, color,
|
locationSprite.Draw(spriteBatch, pos, color,
|
||||||
scale: generationParams.LocationIconSize / location.Type.Sprite.size.X * iconScale * zoom);
|
scale: generationParams.LocationIconSize / locationSprite.size.X * iconScale * zoom);
|
||||||
|
|
||||||
if (location == CurrentDisplayLocation)
|
if (location == CurrentDisplayLocation)
|
||||||
{
|
{
|
||||||
@@ -657,8 +659,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
DrawDecorativeHUD(spriteBatch, rect);
|
DrawDecorativeHUD(spriteBatch, rect);
|
||||||
|
|
||||||
|
bool drawRadiationTooltip = true;
|
||||||
|
|
||||||
if (HighlightedLocation != null)
|
if (HighlightedLocation != null)
|
||||||
{
|
{
|
||||||
|
drawRadiationTooltip = false;
|
||||||
Vector2 pos = rectCenter + (HighlightedLocation.MapPosition + viewOffset) * zoom;
|
Vector2 pos = rectCenter + (HighlightedLocation.MapPosition + viewOffset) * zoom;
|
||||||
pos.X += 50 * zoom;
|
pos.X += 50 * zoom;
|
||||||
Vector2 nameSize = GUI.LargeFont.MeasureString(HighlightedLocation.Name);
|
Vector2 nameSize = GUI.LargeFont.MeasureString(HighlightedLocation.Name);
|
||||||
@@ -693,14 +698,23 @@ namespace Barotrauma
|
|||||||
GUI.DrawString(spriteBatch, new Vector2(repBarRect.Right + 4, repBarRect.Top), repValueText, GUI.Style.TextColor);
|
GUI.DrawString(spriteBatch, new Vector2(repBarRect.Right + 4, repBarRect.Top), repValueText, GUI.Style.TextColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tooltip != null)
|
if (tooltip != null)
|
||||||
{
|
{
|
||||||
GUIComponent.DrawToolTip(spriteBatch, tooltip.Second, tooltip.First);
|
GUIComponent.DrawToolTip(spriteBatch, tooltip.Second, tooltip.First);
|
||||||
|
drawRadiationTooltip = false;
|
||||||
}
|
}
|
||||||
if (connectionTooltip != null)
|
if (connectionTooltip != null)
|
||||||
{
|
{
|
||||||
GUIComponent.DrawToolTip(spriteBatch, connectionTooltip.Second, connectionTooltip.First);
|
GUIComponent.DrawToolTip(spriteBatch, connectionTooltip.Second, connectionTooltip.First);
|
||||||
|
drawRadiationTooltip = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (drawRadiationTooltip)
|
||||||
|
{
|
||||||
|
Radiation.DrawFront(spriteBatch);
|
||||||
|
}
|
||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
||||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
||||||
@@ -827,6 +841,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (connection.LevelData.HasBeaconStation) { iconCount++; }
|
if (connection.LevelData.HasBeaconStation) { iconCount++; }
|
||||||
if (connection.LevelData.HasHuntingGrounds) { iconCount++; }
|
if (connection.LevelData.HasHuntingGrounds) { iconCount++; }
|
||||||
|
if (connection.Locked) { iconCount++; }
|
||||||
string tooltip = null;
|
string tooltip = null;
|
||||||
var subCrushDepth = Submarine.MainSub?.RealWorldCrushDepth ?? Level.DefaultRealWorldCrushDepth;
|
var subCrushDepth = Submarine.MainSub?.RealWorldCrushDepth ?? Level.DefaultRealWorldCrushDepth;
|
||||||
if (GameMain.GameSession?.Campaign?.UpgradeManager != null)
|
if (GameMain.GameSession?.Campaign?.UpgradeManager != null)
|
||||||
@@ -867,6 +882,11 @@ namespace Barotrauma
|
|||||||
DrawIcon(beaconStationIconStyle, (int)(28 * zoom), TextManager.Get(connection.LevelData.IsBeaconActive ? "BeaconStationActiveTooltip" : "BeaconStationInactiveTooltip"));
|
DrawIcon(beaconStationIconStyle, (int)(28 * zoom), TextManager.Get(connection.LevelData.IsBeaconActive ? "BeaconStationActiveTooltip" : "BeaconStationInactiveTooltip"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (connection.Locked)
|
||||||
|
{
|
||||||
|
DrawIcon("LockIcon", (int)(28 * zoom), TextManager.Get("LockedPathTooltip"));
|
||||||
|
}
|
||||||
|
|
||||||
if (connection.LevelData.HasHuntingGrounds)
|
if (connection.LevelData.HasHuntingGrounds)
|
||||||
{
|
{
|
||||||
DrawIcon("HuntingGrounds", (int)(28 * zoom), TextManager.Get("HuntingGroundsTooltip"));
|
DrawIcon("HuntingGrounds", (int)(28 * zoom), TextManager.Get("HuntingGroundsTooltip"));
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#nullable enable
|
#nullable enable
|
||||||
|
using System;
|
||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
|
|
||||||
@@ -6,6 +7,13 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
internal partial class Radiation
|
internal partial class Radiation
|
||||||
{
|
{
|
||||||
|
private static readonly string radiationTooltip = TextManager.Get("RadiationTooltip");
|
||||||
|
private static float spriteIndex;
|
||||||
|
private readonly SpriteSheet sheet = GUI.Style.RadiationAnimSpriteSheet;
|
||||||
|
private int maxFrames => sheet.FrameCount + 1;
|
||||||
|
|
||||||
|
private bool isHovingOver;
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, Rectangle container, float zoom)
|
public void Draw(SpriteBatch spriteBatch, Rectangle container, float zoom)
|
||||||
{
|
{
|
||||||
if (!Enabled) { return; }
|
if (!Enabled) { return; }
|
||||||
@@ -19,16 +27,38 @@ namespace Barotrauma
|
|||||||
Vector2 size = new Vector2((Amount - increasedAmount) * zoom + halfSizeX, viewBottom - topLeft.Y);
|
Vector2 size = new Vector2((Amount - increasedAmount) * zoom + halfSizeX, viewBottom - topLeft.Y);
|
||||||
if (size.X < 0) { return; }
|
if (size.X < 0) { return; }
|
||||||
|
|
||||||
uiSprite.Sprite.DrawTiled(spriteBatch, topLeft, size, GUI.Style.Red * 0.33f, Vector2.Zero, textureScale: new Vector2(zoom));
|
Vector2 spriteScale = new Vector2(zoom);
|
||||||
|
|
||||||
if (container.Contains(PlayerInput.MousePosition) && PlayerInput.MousePosition.X < topLeft.X + size.X)
|
uiSprite.Sprite.DrawTiled(spriteBatch, topLeft, size, Params.RadiationAreaColor, Vector2.Zero, textureScale: spriteScale);
|
||||||
|
|
||||||
|
Vector2 topRight = topLeft + Vector2.UnitX * size.X;
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
for (float i = 0; i <= size.Y; i += sheet.FrameSize.Y / 2f * zoom)
|
||||||
{
|
{
|
||||||
// TODO tooltip?
|
bool isEven = ++index % 2 == 0;
|
||||||
|
Vector2 origin = new Vector2(0.5f, 0) * sheet.FrameSize.X;
|
||||||
|
// every other sprite's animation is reversed to make it seem more chaotic
|
||||||
|
int sprite = (int) MathF.Floor(isEven ? spriteIndex : maxFrames - spriteIndex);
|
||||||
|
sheet.Draw(spriteBatch, sprite, topRight + new Vector2(0, i), Params.RadiationBorderTint, origin, 0f, spriteScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
isHovingOver = container.Contains(PlayerInput.MousePosition) && PlayerInput.MousePosition.X < topLeft.X + size.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DrawFront(SpriteBatch spriteBatch)
|
||||||
|
{
|
||||||
|
if (isHovingOver)
|
||||||
|
{
|
||||||
|
GUIComponent.DrawToolTip(spriteBatch, radiationTooltip, PlayerInput.MousePosition + new Vector2(18 * GUI.Scale));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void MapUpdate(float deltaTime)
|
public void MapUpdate(float deltaTime)
|
||||||
{
|
{
|
||||||
|
float spriteStep = Params.BorderAnimationSpeed * deltaTime;
|
||||||
|
spriteIndex = (spriteIndex + spriteStep) % maxFrames;
|
||||||
|
|
||||||
if (increasedAmount > 0)
|
if (increasedAmount > 0)
|
||||||
{
|
{
|
||||||
increasedAmount -= (lastIncrease / Params.AnimationSpeed) * deltaTime;
|
increasedAmount -= (lastIncrease / Params.AnimationSpeed) * deltaTime;
|
||||||
|
|||||||
@@ -805,7 +805,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (selectionPos != null && selectionPos != Vector2.Zero)
|
if (selectionPos != null && selectionPos != Vector2.Zero)
|
||||||
{
|
{
|
||||||
GUI.DrawRectangle(spriteBatch, new Vector2(selectionPos.X, -selectionPos.Y), selectionSize, Color.DarkRed, false, 0, (int)Math.Max(1.5f / GameScreen.Selected.Cam.Zoom, 1.0f));
|
GUI.DrawRectangle(spriteBatch, new Vector2(selectionPos.X, -selectionPos.Y), selectionSize, Color.DarkRed, false, 0, 2f / GameScreen.Selected.Cam.Zoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void CreatePreviewWindow(GUIComponent parent)
|
public void CreatePreviewWindow(GUIComponent parent)
|
||||||
{
|
{
|
||||||
var content = new GUIFrame(new RectTransform(Vector2.One, parent.RectTransform), style: null);
|
var content = new GUIButton(new RectTransform(Vector2.One, parent.RectTransform), style: null)
|
||||||
|
{
|
||||||
|
OnClicked = (btn, obj) => { SubmarinePreview.Create(this); return false; }
|
||||||
|
};
|
||||||
|
|
||||||
if (PreviewImage == null)
|
if (PreviewImage == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2064,6 +2064,8 @@ namespace Barotrauma.Networking
|
|||||||
bool autoRestartEnabled = inc.ReadBoolean();
|
bool autoRestartEnabled = inc.ReadBoolean();
|
||||||
float autoRestartTimer = autoRestartEnabled ? inc.ReadSingle() : 0.0f;
|
float autoRestartTimer = autoRestartEnabled ? inc.ReadSingle() : 0.0f;
|
||||||
|
|
||||||
|
bool radiationEnabled = inc.ReadBoolean();
|
||||||
|
|
||||||
//ignore the message if we already a more up-to-date one
|
//ignore the message if we already a more up-to-date one
|
||||||
//or if we're still waiting for the initial update
|
//or if we're still waiting for the initial update
|
||||||
if (NetIdUtils.IdMoreRecent(updateID, GameMain.NetLobbyScreen.LastUpdateID) &&
|
if (NetIdUtils.IdMoreRecent(updateID, GameMain.NetLobbyScreen.LastUpdateID) &&
|
||||||
@@ -2119,7 +2121,7 @@ namespace Barotrauma.Networking
|
|||||||
GameMain.NetLobbyScreen.SetAllowSpectating(allowSpectating);
|
GameMain.NetLobbyScreen.SetAllowSpectating(allowSpectating);
|
||||||
GameMain.NetLobbyScreen.LevelSeed = levelSeed;
|
GameMain.NetLobbyScreen.LevelSeed = levelSeed;
|
||||||
GameMain.NetLobbyScreen.SetLevelDifficulty(levelDifficulty);
|
GameMain.NetLobbyScreen.SetLevelDifficulty(levelDifficulty);
|
||||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
GameMain.NetLobbyScreen.SetRadiationEnabled(radiationEnabled);
|
||||||
GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode);
|
GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode);
|
||||||
GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer);
|
GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer);
|
||||||
|
|
||||||
@@ -2564,7 +2566,7 @@ namespace Barotrauma.Networking
|
|||||||
if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaign.CampaignID != campaignID)
|
if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaign.CampaignID != campaignID)
|
||||||
{
|
{
|
||||||
string savePath = transfer.FilePath;
|
string savePath = transfer.FilePath;
|
||||||
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign);
|
GameMain.GameSession = new GameSession(null, savePath, GameModePreset.MultiPlayerCampaign, CampaignSettings.Unsure);
|
||||||
campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode;
|
campaign = (MultiPlayerCampaign)GameMain.GameSession.GameMode;
|
||||||
campaign.CampaignID = campaignID;
|
campaign.CampaignID = campaignID;
|
||||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||||
@@ -2912,7 +2914,7 @@ namespace Barotrauma.Networking
|
|||||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetupNewCampaign(SubmarineInfo sub, string saveName, string mapSeed)
|
public void SetupNewCampaign(SubmarineInfo sub, string saveName, string mapSeed, CampaignSettings settings)
|
||||||
{
|
{
|
||||||
GameMain.NetLobbyScreen.CampaignSetupFrame.Visible = false;
|
GameMain.NetLobbyScreen.CampaignSetupFrame.Visible = false;
|
||||||
GameMain.NetLobbyScreen.CampaignFrame.Visible = false;
|
GameMain.NetLobbyScreen.CampaignFrame.Visible = false;
|
||||||
@@ -2927,6 +2929,7 @@ namespace Barotrauma.Networking
|
|||||||
msg.Write(mapSeed);
|
msg.Write(mapSeed);
|
||||||
msg.Write(sub.Name);
|
msg.Write(sub.Name);
|
||||||
msg.Write(sub.MD5Hash.Hash);
|
msg.Write(sub.MD5Hash.Hash);
|
||||||
|
settings.Serialize(msg);
|
||||||
|
|
||||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -147,13 +147,36 @@ namespace Barotrauma.Networking
|
|||||||
if (missingPackages.Count > 0)
|
if (missingPackages.Count > 0)
|
||||||
{
|
{
|
||||||
var nonDownloadable = missingPackages.Where(p => p.WorkshopId == 0);
|
var nonDownloadable = missingPackages.Where(p => p.WorkshopId == 0);
|
||||||
|
var mismatchedButDownloaded = missingPackages.Where(p =>
|
||||||
|
{
|
||||||
|
var localMatching = ContentPackage.RegularPackages.Find(l => l.SteamWorkshopId != 0 && p.WorkshopId == l.SteamWorkshopId);
|
||||||
|
localMatching ??= ContentPackage.CorePackages.Find(l => l.SteamWorkshopId != 0 && p.WorkshopId == l.SteamWorkshopId);
|
||||||
|
|
||||||
if (nonDownloadable.Any())
|
return localMatching != null;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (mismatchedButDownloaded.Any())
|
||||||
|
{
|
||||||
|
string disconnectMsg;
|
||||||
|
if (mismatchedButDownloaded.Count() == 1)
|
||||||
|
{
|
||||||
|
disconnectMsg = $"DisconnectMessage.MismatchedWorkshopMod~[incompatiblecontentpackage]={GetPackageStr(mismatchedButDownloaded.First())}";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<string> packageStrs = new List<string>();
|
||||||
|
mismatchedButDownloaded.ForEach(cp => packageStrs.Add(GetPackageStr(cp)));
|
||||||
|
disconnectMsg = $"DisconnectMessage.MismatchedWorkshopMods~[incompatiblecontentpackages]={string.Join(", ", packageStrs)}";
|
||||||
|
}
|
||||||
|
Close(disconnectMsg, disableReconnect: true);
|
||||||
|
OnDisconnectMessageReceived?.Invoke(DisconnectReason.MissingContentPackage + "/" + disconnectMsg);
|
||||||
|
}
|
||||||
|
else if (nonDownloadable.Any())
|
||||||
{
|
{
|
||||||
string disconnectMsg;
|
string disconnectMsg;
|
||||||
if (nonDownloadable.Count() == 1)
|
if (nonDownloadable.Count() == 1)
|
||||||
{
|
{
|
||||||
disconnectMsg = $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(missingPackages[0])}";
|
disconnectMsg = $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(nonDownloadable.First())}";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
+1
@@ -56,6 +56,7 @@ namespace Barotrauma.Networking
|
|||||||
Steamworks.SteamNetworking.AllowP2PPacketRelay(true);
|
Steamworks.SteamNetworking.AllowP2PPacketRelay(true);
|
||||||
|
|
||||||
ServerConnection = new SteamP2PConnection("Server", hostSteamId);
|
ServerConnection = new SteamP2PConnection("Server", hostSteamId);
|
||||||
|
ServerConnection.SetOwnerSteamIDIfUnknown(hostSteamId);
|
||||||
|
|
||||||
incomingInitializationMessages = new List<IReadMessage>();
|
incomingInitializationMessages = new List<IReadMessage>();
|
||||||
incomingDataMessages = new List<IReadMessage>();
|
incomingDataMessages = new List<IReadMessage>();
|
||||||
|
|||||||
+32
-25
@@ -17,6 +17,7 @@ namespace Barotrauma.Networking
|
|||||||
class RemotePeer
|
class RemotePeer
|
||||||
{
|
{
|
||||||
public UInt64 SteamID;
|
public UInt64 SteamID;
|
||||||
|
public UInt64 OwnerSteamID;
|
||||||
public double? DisconnectTime;
|
public double? DisconnectTime;
|
||||||
public bool Authenticating;
|
public bool Authenticating;
|
||||||
public bool Authenticated;
|
public bool Authenticated;
|
||||||
@@ -31,6 +32,7 @@ namespace Barotrauma.Networking
|
|||||||
public RemotePeer(UInt64 steamId)
|
public RemotePeer(UInt64 steamId)
|
||||||
{
|
{
|
||||||
SteamID = steamId;
|
SteamID = steamId;
|
||||||
|
OwnerSteamID = 0;
|
||||||
DisconnectTime = null;
|
DisconnectTime = null;
|
||||||
Authenticating = false;
|
Authenticating = false;
|
||||||
Authenticated = false;
|
Authenticated = false;
|
||||||
@@ -90,10 +92,19 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (status == Steamworks.AuthResponse.OK)
|
if (status == Steamworks.AuthResponse.OK)
|
||||||
{
|
{
|
||||||
|
remotePeer.OwnerSteamID = ownerID;
|
||||||
remotePeer.Authenticated = true;
|
remotePeer.Authenticated = true;
|
||||||
remotePeer.Authenticating = false;
|
remotePeer.Authenticating = false;
|
||||||
foreach (var msg in remotePeer.UnauthedMessages)
|
foreach (var msg in remotePeer.UnauthedMessages)
|
||||||
{
|
{
|
||||||
|
//rewrite the owner id before
|
||||||
|
//forwarding the messages to
|
||||||
|
//the server, since it's only
|
||||||
|
//known now
|
||||||
|
int prevBitPosition = msg.Message.BitPosition;
|
||||||
|
msg.Message.BitPosition = sizeof(ulong) * 8;
|
||||||
|
msg.Message.Write(ownerID);
|
||||||
|
msg.Message.BitPosition = prevBitPosition;
|
||||||
byte[] msgToSend = (byte[])msg.Message.Buffer.Clone();
|
byte[] msgToSend = (byte[])msg.Message.Buffer.Clone();
|
||||||
Array.Resize(ref msgToSend, msg.Message.LengthBytes);
|
Array.Resize(ref msgToSend, msg.Message.LengthBytes);
|
||||||
ChildServerRelay.Write(msgToSend);
|
ChildServerRelay.Write(msgToSend);
|
||||||
@@ -131,6 +142,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||||
outMsg.Write(steamId);
|
outMsg.Write(steamId);
|
||||||
|
outMsg.Write(remotePeer.OwnerSteamID);
|
||||||
outMsg.Write(data, 1, dataLength - 1);
|
outMsg.Write(data, 1, dataLength - 1);
|
||||||
|
|
||||||
DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];
|
DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];
|
||||||
@@ -142,34 +154,27 @@ namespace Barotrauma.Networking
|
|||||||
bool isServerMessage = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
|
bool isServerMessage = (incByte & (byte)PacketHeader.IsServerMessage) != 0;
|
||||||
bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;
|
bool isHeartbeatMessage = (incByte & (byte)PacketHeader.IsHeartbeatMessage) != 0;
|
||||||
|
|
||||||
if (!remotePeer.Authenticated)
|
if (!remotePeer.Authenticated & !remotePeer.Authenticating && isConnectionInitializationStep)
|
||||||
{
|
{
|
||||||
if (!remotePeer.Authenticating)
|
remotePeer.DisconnectTime = null;
|
||||||
|
|
||||||
|
IReadMessage authMsg = new ReadOnlyMessage(data, isCompressed, 2, dataLength - 2, null);
|
||||||
|
ConnectionInitialization initializationStep = (ConnectionInitialization)authMsg.ReadByte();
|
||||||
|
if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
|
||||||
{
|
{
|
||||||
if (isConnectionInitializationStep)
|
remotePeer.Authenticating = true;
|
||||||
|
|
||||||
|
authMsg.ReadString(); //skip name
|
||||||
|
authMsg.ReadInt32(); //skip owner key
|
||||||
|
authMsg.ReadUInt64(); //skip steamid
|
||||||
|
UInt16 ticketLength = authMsg.ReadUInt16();
|
||||||
|
byte[] ticket = authMsg.ReadBytes(ticketLength);
|
||||||
|
|
||||||
|
Steamworks.BeginAuthResult authSessionStartState = Steam.SteamManager.StartAuthSession(ticket, steamId);
|
||||||
|
if (authSessionStartState != Steamworks.BeginAuthResult.OK)
|
||||||
{
|
{
|
||||||
remotePeer.DisconnectTime = null;
|
DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam auth session failed to start: " + authSessionStartState.ToString());
|
||||||
|
return;
|
||||||
IReadMessage authMsg = new ReadOnlyMessage(data, isCompressed, 2, dataLength - 2, null);
|
|
||||||
ConnectionInitialization initializationStep = (ConnectionInitialization)authMsg.ReadByte();
|
|
||||||
//Console.WriteLine("received init step from "+steamId.ToString()+" ("+initializationStep.ToString()+")");
|
|
||||||
if (initializationStep == ConnectionInitialization.SteamTicketAndVersion)
|
|
||||||
{
|
|
||||||
remotePeer.Authenticating = true;
|
|
||||||
|
|
||||||
authMsg.ReadString(); //skip name
|
|
||||||
authMsg.ReadInt32(); //skip owner key
|
|
||||||
authMsg.ReadUInt64(); //skip steamid
|
|
||||||
UInt16 ticketLength = authMsg.ReadUInt16();
|
|
||||||
byte[] ticket = authMsg.ReadBytes(ticketLength);
|
|
||||||
|
|
||||||
Steamworks.BeginAuthResult authSessionStartState = Steam.SteamManager.StartAuthSession(ticket, steamId);
|
|
||||||
if (authSessionStartState != Steamworks.BeginAuthResult.OK)
|
|
||||||
{
|
|
||||||
DisconnectPeer(remotePeer, DisconnectReason.SteamAuthenticationFailed.ToString() + "/ Steam auth session failed to start: " + authSessionStartState.ToString());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,6 +341,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||||
outMsg.Write(selfSteamID);
|
outMsg.Write(selfSteamID);
|
||||||
|
outMsg.Write(selfSteamID);
|
||||||
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
|
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
|
||||||
outMsg.Write(Name);
|
outMsg.Write(Name);
|
||||||
|
|
||||||
@@ -428,6 +434,7 @@ namespace Barotrauma.Networking
|
|||||||
byte[] msgData = new byte[msg.LengthBytes];
|
byte[] msgData = new byte[msg.LengthBytes];
|
||||||
msg.PrepareForSending(ref msgData, out bool isCompressed, out int length);
|
msg.PrepareForSending(ref msgData, out bool isCompressed, out int length);
|
||||||
msgToSend.Write(selfSteamID);
|
msgToSend.Write(selfSteamID);
|
||||||
|
msgToSend.Write(selfSteamID);
|
||||||
msgToSend.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
|
msgToSend.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
|
||||||
msgToSend.Write((UInt16)length);
|
msgToSend.Write((UInt16)length);
|
||||||
msgToSend.Write(msgData, 0, length);
|
msgToSend.Write(msgData, 0, length);
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClientAdminWrite(NetFlags dataToSend, int? missionTypeOr = null, int? missionTypeAnd = null, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? useRespawnShuttle = null)
|
public void ClientAdminWrite(NetFlags dataToSend, int? missionTypeOr = null, int? missionTypeAnd = null, float? levelDifficulty = null, bool? autoRestart = null, int traitorSetting = 0, int botCount = 0, int botSpawnMode = 0, bool? radiationEnabled = null, bool? useRespawnShuttle = null)
|
||||||
{
|
{
|
||||||
if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return;
|
if (!GameMain.Client.HasPermission(Networking.ClientPermissions.ManageSettings)) return;
|
||||||
|
|
||||||
@@ -212,6 +212,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
outMsg.Write(autoRestart != null);
|
outMsg.Write(autoRestart != null);
|
||||||
outMsg.Write(autoRestart ?? false);
|
outMsg.Write(autoRestart ?? false);
|
||||||
|
outMsg.Write(radiationEnabled ?? RadiationEnabled);
|
||||||
outMsg.WritePadBits();
|
outMsg.WritePadBits();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -274,7 +275,7 @@ namespace Barotrauma.Networking
|
|||||||
if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) { ToggleSettingsFrame(btn, userData); }
|
if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) { ToggleSettingsFrame(btn, userData); }
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
new GUIButton(new RectTransform(Vector2.One, settingsFrame.RectTransform), "", style: null)
|
new GUIButton(new RectTransform(Vector2.One, settingsFrame.RectTransform), "", style: null)
|
||||||
{
|
{
|
||||||
OnClicked = ToggleSettingsFrame
|
OnClicked = ToggleSettingsFrame
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private GUIButton loadGameButton, deleteMpSaveButton;
|
private GUIButton loadGameButton, deleteMpSaveButton;
|
||||||
|
|
||||||
public Action<SubmarineInfo, string, string> StartNewGame;
|
public Action<SubmarineInfo, string, string, CampaignSettings> StartNewGame;
|
||||||
public Action<string> LoadGame;
|
public Action<string> LoadGame;
|
||||||
|
|
||||||
private enum CategoryFilter { All = 0, Vanilla = 1, Custom = 2 };
|
private enum CategoryFilter { All = 0, Vanilla = 1, Custom = 2 };
|
||||||
@@ -40,6 +40,8 @@ namespace Barotrauma
|
|||||||
get;
|
get;
|
||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GUITickBox EnableRadiationToggle { get; set; }
|
||||||
|
|
||||||
private readonly bool isMultiplayer;
|
private readonly bool isMultiplayer;
|
||||||
|
|
||||||
@@ -171,6 +173,8 @@ namespace Barotrauma
|
|||||||
string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text);
|
string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text);
|
||||||
bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;
|
bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;
|
||||||
|
|
||||||
|
CampaignSettings settings = new CampaignSettings { RadiationEnabled = EnableRadiationToggle?.Selected ?? GameMain.NetLobbyScreen.IsRadiationEnabled() };
|
||||||
|
|
||||||
if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages)
|
if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages)
|
||||||
{
|
{
|
||||||
if (!hasRequiredContentPackages)
|
if (!hasRequiredContentPackages)
|
||||||
@@ -184,7 +188,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (GUIMessageBox.MessageBoxes.Count == 0)
|
if (GUIMessageBox.MessageBoxes.Count == 0)
|
||||||
{
|
{
|
||||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
|
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
|
||||||
if (isMultiplayer)
|
if (isMultiplayer)
|
||||||
{
|
{
|
||||||
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
||||||
@@ -204,7 +208,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
msgBox.Buttons[0].OnClicked = (button, obj) =>
|
msgBox.Buttons[0].OnClicked = (button, obj) =>
|
||||||
{
|
{
|
||||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
|
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
|
||||||
if (isMultiplayer)
|
if (isMultiplayer)
|
||||||
{
|
{
|
||||||
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
||||||
@@ -219,7 +223,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
|
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
|
||||||
if (isMultiplayer)
|
if (isMultiplayer)
|
||||||
{
|
{
|
||||||
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
||||||
@@ -230,8 +234,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), buttonContainer.RectTransform), "",
|
InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(isMultiplayer ? 0.6f : 0.3f, 1f), buttonContainer.RectTransform), "", font: isMultiplayer ? GUI.Style.SmallFont : GUI.Style.Font, textColor: GUI.Style.Green)
|
||||||
font: isMultiplayer ? GUI.Style.SmallFont : GUI.Style.Font, textColor: GUI.Style.Green)
|
|
||||||
{
|
{
|
||||||
TextGetter = () =>
|
TextGetter = () =>
|
||||||
{
|
{
|
||||||
@@ -254,6 +257,12 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (!isMultiplayer)
|
if (!isMultiplayer)
|
||||||
{
|
{
|
||||||
|
EnableRadiationToggle = new GUITickBox(new RectTransform(new Vector2(0.3f, 1f), buttonContainer.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font)
|
||||||
|
{
|
||||||
|
Selected = true,
|
||||||
|
ToolTip = TextManager.Get("campaignoption.enableradiation.tooltip")
|
||||||
|
};
|
||||||
|
|
||||||
var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point(5) }, style: "GUINotificationButton")
|
var disclaimerBtn = new GUIButton(new RectTransform(new Vector2(1.0f, 0.8f), rightColumn.RectTransform, Anchor.TopRight) { AbsoluteOffset = new Point(5) }, style: "GUINotificationButton")
|
||||||
{
|
{
|
||||||
IgnoreLayoutGroups = true,
|
IgnoreLayoutGroups = true,
|
||||||
|
|||||||
@@ -477,8 +477,8 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", mission.Reward));
|
string rewardText = TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", mission.Reward));
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform),
|
||||||
TextManager.GetWithVariable("missionreward", "[reward]", rewardText), wrap: true);
|
TextManager.GetWithVariable("missionreward", "[reward]", rewardText), wrap: true, parseRichText: true);
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.Description, wrap: true);
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.Description, wrap: true, parseRichText: true);
|
||||||
}
|
}
|
||||||
missionPanel.RectTransform.MinSize = new Point(0, (int)(missionTextContent.Children.Sum(c => c.Rect.Height) / missionTextContent.RectTransform.RelativeSize.Y) + GUI.IntScale(20));
|
missionPanel.RectTransform.MinSize = new Point(0, (int)(missionTextContent.Children.Sum(c => c.Rect.Height) / missionTextContent.RectTransform.RelativeSize.Y) + GUI.IntScale(20));
|
||||||
foreach (GUIComponent child in missionTextContent.Children)
|
foreach (GUIComponent child in missionTextContent.Children)
|
||||||
@@ -562,6 +562,11 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public void SelectTab(CampaignMode.InteractionType tab)
|
public void SelectTab(CampaignMode.InteractionType tab)
|
||||||
{
|
{
|
||||||
|
if (Campaign.ShowCampaignUI || (Campaign.ForceMapUI && tab == CampaignMode.InteractionType.Map))
|
||||||
|
{
|
||||||
|
HintManager.OnShowCampaignInterface(tab);
|
||||||
|
}
|
||||||
|
|
||||||
selectedTab = tab;
|
selectedTab = tab;
|
||||||
for (int i = 0; i < tabs.Length; i++)
|
for (int i = 0; i < tabs.Length; i++)
|
||||||
{
|
{
|
||||||
|
|||||||
+2
-2
@@ -1761,9 +1761,9 @@ namespace Barotrauma.CharacterEditor
|
|||||||
#endif
|
#endif
|
||||||
// Add to the selected content package
|
// Add to the selected content package
|
||||||
contentPackage.AddFile(configFilePath, ContentType.Character);
|
contentPackage.AddFile(configFilePath, ContentType.Character);
|
||||||
Barotrauma.IO.Validation.DevException = true;
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
contentPackage.Save(contentPackage.Path);
|
contentPackage.Save(contentPackage.Path);
|
||||||
Barotrauma.IO.Validation.DevException = false;
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
DebugConsole.NewMessage(GetCharacterEditorTranslation("ContentPackageSaved").Replace("[path]", contentPackage.Path));
|
DebugConsole.NewMessage(GetCharacterEditorTranslation("ContentPackageSaved").Replace("[path]", contentPackage.Path));
|
||||||
|
|
||||||
// Ragdoll
|
// Ragdoll
|
||||||
|
|||||||
@@ -882,7 +882,7 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameSession gameSession = new GameSession(subInfo, "", GameModePreset.TestMode, null);
|
GameSession gameSession = new GameSession(subInfo, "", GameModePreset.TestMode, CampaignSettings.Empty, null);
|
||||||
TestGameMode gameMode = (TestGameMode) gameSession.GameMode;
|
TestGameMode gameMode = (TestGameMode) gameSession.GameMode;
|
||||||
|
|
||||||
gameMode.SpawnOutpost = true;
|
gameMode.SpawnOutpost = true;
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ namespace Barotrauma
|
|||||||
subInfo ??= SubmarineInfo.SavedSubmarines.GetRandom(s =>
|
subInfo ??= SubmarineInfo.SavedSubmarines.GetRandom(s =>
|
||||||
s.IsPlayer && !s.HasTag(SubmarineTag.Shuttle) &&
|
s.IsPlayer && !s.HasTag(SubmarineTag.Shuttle) &&
|
||||||
!nonPlayerFiles.Any(f => f.Path.CleanUpPath().Equals(s.FilePath.CleanUpPath(), StringComparison.InvariantCultureIgnoreCase)));
|
!nonPlayerFiles.Any(f => f.Path.CleanUpPath().Equals(s.FilePath.CleanUpPath(), StringComparison.InvariantCultureIgnoreCase)));
|
||||||
GameSession gameSession = new GameSession(subInfo, "", GameModePreset.TestMode, null);
|
GameSession gameSession = new GameSession(subInfo, "", GameModePreset.TestMode, CampaignSettings.Empty, null);
|
||||||
gameSession.StartRound(Level.Loaded.LevelData);
|
gameSession.StartRound(Level.Loaded.LevelData);
|
||||||
(gameSession.GameMode as TestGameMode).OnRoundEnd = () =>
|
(gameSession.GameMode as TestGameMode).OnRoundEnd = () =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1043,7 +1043,7 @@ namespace Barotrauma
|
|||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartGame(SubmarineInfo selectedSub, string saveName, string mapSeed)
|
private void StartGame(SubmarineInfo selectedSub, string saveName, string mapSeed, CampaignSettings settings)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(saveName)) return;
|
if (string.IsNullOrEmpty(saveName)) return;
|
||||||
|
|
||||||
@@ -1082,7 +1082,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
selectedSub = new SubmarineInfo(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"));
|
selectedSub = new SubmarineInfo(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"));
|
||||||
|
|
||||||
GameMain.GameSession = new GameSession(selectedSub, saveName, GameModePreset.SinglePlayerCampaign, mapSeed);
|
GameMain.GameSession = new GameSession(selectedSub, saveName, GameModePreset.SinglePlayerCampaign, settings, mapSeed);
|
||||||
((SinglePlayerCampaign)GameMain.GameSession.GameMode).LoadNewLevel();
|
((SinglePlayerCampaign)GameMain.GameSession.GameMode).LoadNewLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1134,6 +1134,7 @@ namespace Barotrauma
|
|||||||
(int)(campaignSetupUI.StartButton.TextBlock.TextSize.X * 1.5f),
|
(int)(campaignSetupUI.StartButton.TextBlock.TextSize.X * 1.5f),
|
||||||
campaignSetupUI.StartButton.RectTransform.MinSize.Y);
|
campaignSetupUI.StartButton.RectTransform.MinSize.Y);
|
||||||
startButtonContainer.RectTransform.MinSize = new Point(0, campaignSetupUI.StartButton.RectTransform.MinSize.Y);
|
startButtonContainer.RectTransform.MinSize = new Point(0, campaignSetupUI.StartButton.RectTransform.MinSize.Y);
|
||||||
|
campaignSetupUI.EnableRadiationToggle.RectTransform.Parent = startButtonContainer.RectTransform;
|
||||||
campaignSetupUI.InitialMoneyText.RectTransform.Parent = startButtonContainer.RectTransform;
|
campaignSetupUI.InitialMoneyText.RectTransform.Parent = startButtonContainer.RectTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private GUIComponent jobVariantTooltip;
|
private GUIComponent jobVariantTooltip;
|
||||||
|
|
||||||
|
private SubmarinePreview submarinePreview;
|
||||||
|
|
||||||
private readonly GUITextBox chatInput;
|
private readonly GUITextBox chatInput;
|
||||||
private readonly GUITextBox serverLogFilter;
|
private readonly GUITextBox serverLogFilter;
|
||||||
public GUITextBox ChatInput
|
public GUITextBox ChatInput
|
||||||
@@ -41,6 +43,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private readonly GUIScrollBar levelDifficultyScrollBar;
|
private readonly GUIScrollBar levelDifficultyScrollBar;
|
||||||
|
|
||||||
|
private readonly GUITickBox radiationEnabledTickBox;
|
||||||
|
|
||||||
private readonly GUIButton[] traitorProbabilityButtons;
|
private readonly GUIButton[] traitorProbabilityButtons;
|
||||||
private readonly GUITextBlock traitorProbabilityText;
|
private readonly GUITextBlock traitorProbabilityText;
|
||||||
|
|
||||||
@@ -1095,6 +1099,16 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
radiationEnabledTickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.1f), settingsContent.RectTransform), TextManager.Get("CampaignOption.EnableRadiation"), font: GUI.Style.Font)
|
||||||
|
{
|
||||||
|
Selected = true,
|
||||||
|
OnSelected = box =>
|
||||||
|
{
|
||||||
|
GameMain.Client.ServerSettings.ClientAdminWrite(ServerSettings.NetFlags.Misc, radiationEnabled: box.Selected);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
List<GUIComponent> settingsElements = settingsContent.Children.ToList();
|
List<GUIComponent> settingsElements = settingsContent.Children.ToList();
|
||||||
for (int i = 0; i < settingsElements.Count; i++)
|
for (int i = 0; i < settingsElements.Count; i++)
|
||||||
{
|
{
|
||||||
@@ -1238,6 +1252,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
SeedBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
SeedBox.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||||
levelDifficultyScrollBar.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
levelDifficultyScrollBar.Enabled = !CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||||
|
radiationEnabledTickBox.Enabled = CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||||
traitorProbabilityButtons[0].Enabled = traitorProbabilityButtons[1].Enabled = traitorProbabilityText.Enabled =
|
traitorProbabilityButtons[0].Enabled = traitorProbabilityButtons[1].Enabled = traitorProbabilityText.Enabled =
|
||||||
!CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
!CampaignFrame.Visible && !CampaignSetupFrame.Visible && GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||||
botCountButtons[0].Enabled = botCountButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
botCountButtons[0].Enabled = botCountButtons[1].Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageSettings);
|
||||||
@@ -2533,8 +2548,14 @@ namespace Barotrauma
|
|||||||
chatBox.RemoveChild(chatBox.Content.Children.First());
|
chatBox.RemoveChild(chatBox.Content.Children.First());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string textWithSender = message.TextWithSender;
|
||||||
|
if (message.Type == ChatMessageType.Server)
|
||||||
|
{
|
||||||
|
RichTextData.GetRichTextData(textWithSender, out textWithSender);
|
||||||
|
}
|
||||||
|
|
||||||
GUITextBlock msg = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), chatBox.Content.RectTransform),
|
GUITextBlock msg = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), chatBox.Content.RectTransform),
|
||||||
text: ChatMessage.GetTimeStamp() + (message.Type == ChatMessageType.Private ? TextManager.Get("PrivateMessageTag") + " " : "") + message.TextWithSender,
|
text: ChatMessage.GetTimeStamp() + (message.Type == ChatMessageType.Private ? TextManager.Get("PrivateMessageTag") + " " : "") + textWithSender,
|
||||||
textColor: message.Color,
|
textColor: message.Color,
|
||||||
color: ((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f,
|
color: ((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f,
|
||||||
wrap: true, font: GUI.SmallFont)
|
wrap: true, font: GUI.SmallFont)
|
||||||
|
|||||||
@@ -43,6 +43,13 @@ namespace Barotrauma
|
|||||||
private Dictionary<ulong, Steamworks.Ugc.Item?> pendingWorkshopDownloads = null;
|
private Dictionary<ulong, Steamworks.Ugc.Item?> pendingWorkshopDownloads = null;
|
||||||
private string autoConnectName; private string autoConnectEndpoint;
|
private string autoConnectName; private string autoConnectEndpoint;
|
||||||
|
|
||||||
|
private enum TernaryOption
|
||||||
|
{
|
||||||
|
Any,
|
||||||
|
Enabled,
|
||||||
|
Disabled
|
||||||
|
}
|
||||||
|
|
||||||
private class FriendInfo
|
private class FriendInfo
|
||||||
{
|
{
|
||||||
public UInt64 SteamID;
|
public UInt64 SteamID;
|
||||||
@@ -146,16 +153,19 @@ namespace Barotrauma
|
|||||||
private GUITickBox filterFull;
|
private GUITickBox filterFull;
|
||||||
private GUITickBox filterEmpty;
|
private GUITickBox filterEmpty;
|
||||||
private GUITickBox filterWhitelisted;
|
private GUITickBox filterWhitelisted;
|
||||||
private GUITickBox filterFriendlyFire;
|
private Dictionary<string, GUIDropDown> ternaryFilters;
|
||||||
private GUITickBox filterKarma;
|
|
||||||
private GUITickBox filterTraitor;
|
|
||||||
private GUITickBox filterModded;
|
|
||||||
private GUITickBox filterVoip;
|
|
||||||
private Dictionary<string, GUITickBox> filterTickBoxes;
|
private Dictionary<string, GUITickBox> filterTickBoxes;
|
||||||
private Dictionary<string, GUITickBox> playStyleTickBoxes;
|
private Dictionary<string, GUITickBox> playStyleTickBoxes;
|
||||||
private Dictionary<string, GUITickBox> gameModeTickBoxes;
|
private Dictionary<string, GUITickBox> gameModeTickBoxes;
|
||||||
private GUITickBox filterOffensive;
|
private GUITickBox filterOffensive;
|
||||||
|
|
||||||
|
//GUIDropDown sends the OnSelected event before SelectedData is set, so we have to cache it manually.
|
||||||
|
private TernaryOption filterFriendlyFireValue = TernaryOption.Any;
|
||||||
|
private TernaryOption filterKarmaValue = TernaryOption.Any;
|
||||||
|
private TernaryOption filterTraitorValue = TernaryOption.Any;
|
||||||
|
private TernaryOption filterVoipValue = TernaryOption.Any;
|
||||||
|
private TernaryOption filterModdedValue = TernaryOption.Any;
|
||||||
|
|
||||||
private string sortedBy;
|
private string sortedBy;
|
||||||
|
|
||||||
private GUIButton serverPreviewToggleButton;
|
private GUIButton serverPreviewToggleButton;
|
||||||
@@ -173,6 +183,49 @@ namespace Barotrauma
|
|||||||
CreateUI();
|
CreateUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void AddTernaryFilter(RectTransform parent, float elementHeight, string tag, Action<TernaryOption> valueSetter)
|
||||||
|
{
|
||||||
|
var filterLayoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, elementHeight), parent), isHorizontal: true)
|
||||||
|
{
|
||||||
|
Stretch = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var box = new GUIFrame(new RectTransform(Vector2.One, filterLayoutGroup.RectTransform, Anchor.CenterLeft, scaleBasis: ScaleBasis.BothHeight)
|
||||||
|
{
|
||||||
|
IsFixedSize = true,
|
||||||
|
}, null)
|
||||||
|
{
|
||||||
|
HoverColor = Color.Gray,
|
||||||
|
SelectedColor = Color.DarkGray,
|
||||||
|
CanBeFocused = false
|
||||||
|
};
|
||||||
|
if (box.RectTransform.MinSize.Y > 0)
|
||||||
|
{
|
||||||
|
box.RectTransform.MinSize = new Point(box.RectTransform.MinSize.Y);
|
||||||
|
box.RectTransform.Resize(box.RectTransform.MinSize);
|
||||||
|
}
|
||||||
|
Vector2 textBlockScale = new Vector2((float)(filterLayoutGroup.Rect.Width - filterLayoutGroup.Rect.Height) / (float)Math.Max(filterLayoutGroup.Rect.Width, 1.0), 1.0f);
|
||||||
|
|
||||||
|
var filterLabel = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1.0f) * textBlockScale, filterLayoutGroup.RectTransform, Anchor.CenterLeft), TextManager.Get("servertag." + tag + ".label"), textAlignment: Alignment.CenterLeft)
|
||||||
|
{
|
||||||
|
UserData = TextManager.Get("servertag." + tag + ".label")
|
||||||
|
};
|
||||||
|
GUI.Style.Apply(filterLabel, "GUITextBlock", null);
|
||||||
|
|
||||||
|
var dropDown = new GUIDropDown(new RectTransform(new Vector2(0.4f, 1.0f) * textBlockScale, filterLayoutGroup.RectTransform, Anchor.CenterLeft), elementCount: 3);
|
||||||
|
dropDown.AddItem(TextManager.Get("any"), TernaryOption.Any);
|
||||||
|
dropDown.AddItem(TextManager.Get("servertag." + tag + ".true"), TernaryOption.Enabled, TextManager.Get("servertagdescription." + tag + ".true"));
|
||||||
|
dropDown.AddItem(TextManager.Get("servertag." + tag + ".false"), TernaryOption.Disabled, TextManager.Get("servertagdescription." + tag + ".false"));
|
||||||
|
dropDown.SelectItem(TernaryOption.Any);
|
||||||
|
dropDown.OnSelected = (_, data) => {
|
||||||
|
valueSetter((TernaryOption)data);
|
||||||
|
FilterServers();
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
ternaryFilters.Add(tag, dropDown);
|
||||||
|
}
|
||||||
|
|
||||||
private void CreateUI()
|
private void CreateUI()
|
||||||
{
|
{
|
||||||
menu = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.85f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) });
|
menu = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.85f), GUI.Canvas, Anchor.Center) { MinSize = new Point(GameMain.GraphicsHeight, 0) });
|
||||||
@@ -323,6 +376,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
filterToggle.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipHorizontally);
|
filterToggle.Children.ForEach(c => c.SpriteEffects = SpriteEffects.FlipHorizontally);
|
||||||
|
|
||||||
|
ternaryFilters = new Dictionary<string, GUIDropDown>();
|
||||||
filterTickBoxes = new Dictionary<string, GUITickBox>();
|
filterTickBoxes = new Dictionary<string, GUITickBox>();
|
||||||
|
|
||||||
filterSameVersion = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterSameVersion"))
|
filterSameVersion = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterSameVersion"))
|
||||||
@@ -382,40 +436,11 @@ namespace Barotrauma
|
|||||||
CanBeFocused = false
|
CanBeFocused = false
|
||||||
};
|
};
|
||||||
|
|
||||||
filterKarma = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.karma.true"))
|
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "karma", (value) => { filterKarmaValue = value; });
|
||||||
{
|
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "traitors", (value) => { filterTraitorValue = value; });
|
||||||
UserData = TextManager.Get("servertag.karma.true"),
|
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "friendlyfire", (value) => { filterFriendlyFireValue = value; });
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "voip", (value) => { filterVoipValue = value; });
|
||||||
};
|
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "modded", (value) => { filterModdedValue = value; });
|
||||||
filterTickBoxes.Add("servertag.karma", filterKarma);
|
|
||||||
|
|
||||||
filterTraitor = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.traitors.true"))
|
|
||||||
{
|
|
||||||
UserData = TextManager.Get("servertag.traitors.true"),
|
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
|
||||||
};
|
|
||||||
filterTickBoxes.Add("servertag.traitors", filterTraitor);
|
|
||||||
|
|
||||||
filterFriendlyFire = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.friendlyfire.false"))
|
|
||||||
{
|
|
||||||
UserData = TextManager.Get("servertag.friendlyfire.false"),
|
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
|
||||||
};
|
|
||||||
filterTickBoxes.Add("servertag.friendlyfire", filterFriendlyFire);
|
|
||||||
|
|
||||||
filterVoip = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.voip.false"))
|
|
||||||
{
|
|
||||||
UserData = TextManager.Get("servertag.voip.false"),
|
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
|
||||||
};
|
|
||||||
filterTickBoxes.Add("servertag.voip", filterVoip);
|
|
||||||
|
|
||||||
filterModded = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.modded.true"))
|
|
||||||
{
|
|
||||||
UserData = TextManager.Get("servertag.modded.true"),
|
|
||||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
|
||||||
};
|
|
||||||
filterTickBoxes.Add("servertag.modded", filterModded);
|
|
||||||
|
|
||||||
// Play Style Selection
|
// Play Style Selection
|
||||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get("ServerSettingsPlayStyle"), font: GUI.SubHeadingFont)
|
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get("ServerSettingsPlayStyle"), font: GUI.SubHeadingFont)
|
||||||
@@ -1076,9 +1101,15 @@ namespace Barotrauma
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool incompatible =
|
bool incompatible =
|
||||||
(!serverInfo.ContentPackageHashes.Any() && serverInfo.ContentPackagesMatch()) ||
|
(serverInfo.ContentPackageHashes.Any() && !serverInfo.ContentPackagesMatch()) ||
|
||||||
(remoteVersion != null && !NetworkMember.IsCompatible(GameMain.Version, remoteVersion));
|
(remoteVersion != null && !NetworkMember.IsCompatible(GameMain.Version, remoteVersion));
|
||||||
|
|
||||||
|
var karmaFilterPassed = filterKarmaValue == TernaryOption.Any|| (filterKarmaValue == TernaryOption.Enabled) == serverInfo.KarmaEnabled;
|
||||||
|
var friendlyFireFilterPassed = filterFriendlyFireValue == TernaryOption.Any || (filterFriendlyFireValue == TernaryOption.Enabled) == serverInfo.FriendlyFireEnabled;
|
||||||
|
var traitorsFilterPassed = filterTraitorValue == TernaryOption.Any || (filterTraitorValue == TernaryOption.Enabled) == (serverInfo.TraitorsEnabled == YesNoMaybe.Yes || serverInfo.TraitorsEnabled == YesNoMaybe.Maybe);
|
||||||
|
var voipFilterPassed = filterVoipValue == TernaryOption.Any || (filterVoipValue == TernaryOption.Enabled) == serverInfo.VoipEnabled;
|
||||||
|
var moddedFilterPassed = filterModdedValue == TernaryOption.Any || (filterModdedValue == TernaryOption.Enabled) == serverInfo.GetPlayStyleTags().Any(t => t.Contains("modded.true"));
|
||||||
|
|
||||||
child.Visible =
|
child.Visible =
|
||||||
serverInfo.OwnerVerified &&
|
serverInfo.OwnerVerified &&
|
||||||
serverInfo.ServerName.Contains(searchBox.Text, StringComparison.OrdinalIgnoreCase) &&
|
serverInfo.ServerName.Contains(searchBox.Text, StringComparison.OrdinalIgnoreCase) &&
|
||||||
@@ -1089,11 +1120,11 @@ namespace Barotrauma
|
|||||||
(!filterEmpty.Selected || serverInfo.PlayerCount > 0) &&
|
(!filterEmpty.Selected || serverInfo.PlayerCount > 0) &&
|
||||||
(!filterWhitelisted.Selected || serverInfo.UsingWhiteList == true) &&
|
(!filterWhitelisted.Selected || serverInfo.UsingWhiteList == true) &&
|
||||||
(!filterOffensive.Selected || !ForbiddenWordFilter.IsForbidden(serverInfo.ServerName)) &&
|
(!filterOffensive.Selected || !ForbiddenWordFilter.IsForbidden(serverInfo.ServerName)) &&
|
||||||
(!filterKarma.Selected || serverInfo.KarmaEnabled == true) &&
|
karmaFilterPassed &&
|
||||||
(!filterFriendlyFire.Selected || serverInfo.FriendlyFireEnabled == false) &&
|
friendlyFireFilterPassed &&
|
||||||
(!filterTraitor.Selected || serverInfo.TraitorsEnabled == YesNoMaybe.Yes || serverInfo.TraitorsEnabled == YesNoMaybe.Maybe) &&
|
traitorsFilterPassed &&
|
||||||
(!filterVoip.Selected || serverInfo.VoipEnabled == false) &&
|
voipFilterPassed &&
|
||||||
(!filterModded.Selected || serverInfo.GetPlayStyleTags().Any(t => t.Contains("modded.true"))) &&
|
moddedFilterPassed &&
|
||||||
((selectedTab == ServerListTab.All && (serverInfo.LobbyID != 0 || !string.IsNullOrWhiteSpace(serverInfo.Port))) ||
|
((selectedTab == ServerListTab.All && (serverInfo.LobbyID != 0 || !string.IsNullOrWhiteSpace(serverInfo.Port))) ||
|
||||||
(selectedTab == ServerListTab.Recent && serverInfo.Recent) ||
|
(selectedTab == ServerListTab.Recent && serverInfo.Recent) ||
|
||||||
(selectedTab == ServerListTab.Favorites && serverInfo.Favorite));
|
(selectedTab == ServerListTab.Favorites && serverInfo.Favorite));
|
||||||
@@ -2334,6 +2365,10 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
element.Add(new XAttribute(filterBox.Key, filterBox.Value.Selected.ToString()));
|
element.Add(new XAttribute(filterBox.Key, filterBox.Value.Selected.ToString()));
|
||||||
}
|
}
|
||||||
|
foreach (KeyValuePair<string, GUIDropDown> ternaryFilter in ternaryFilters)
|
||||||
|
{
|
||||||
|
element.Add(new XAttribute(ternaryFilter.Key, ternaryFilter.Value.SelectedData.ToString()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadServerFilters(XElement element)
|
public void LoadServerFilters(XElement element)
|
||||||
@@ -2344,6 +2379,15 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
filterBox.Value.Selected = element.GetAttributeBool(filterBox.Key, filterBox.Value.Selected);
|
filterBox.Value.Selected = element.GetAttributeBool(filterBox.Key, filterBox.Value.Selected);
|
||||||
}
|
}
|
||||||
|
foreach (KeyValuePair<string, GUIDropDown> ternaryFilter in ternaryFilters)
|
||||||
|
{
|
||||||
|
string valueStr = element.GetAttributeString(ternaryFilter.Key, "");
|
||||||
|
TernaryOption ternaryOption = (TernaryOption)ternaryFilter.Value.SelectedData;
|
||||||
|
Enum.TryParse<TernaryOption>(valueStr, true, out ternaryOption);
|
||||||
|
|
||||||
|
var child = ternaryFilter.Value.ListBox.Content.GetChildByUserData(ternaryOption);
|
||||||
|
ternaryFilter.Value.Select(ternaryFilter.Value.ListBox.Content.GetChildIndex(child));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -410,9 +410,9 @@ namespace Barotrauma
|
|||||||
if (sub.HasTag(SubmarineTag.HideInMenus)) { continue; }
|
if (sub.HasTag(SubmarineTag.HideInMenus)) { continue; }
|
||||||
string subPath = Path.GetFullPath(sub.FilePath);
|
string subPath = Path.GetFullPath(sub.FilePath);
|
||||||
|
|
||||||
//ignore subs that are part of the vanilla content package
|
//ignore files that are part of the vanilla content package
|
||||||
if (GameMain.VanillaContent != null &&
|
if (GameMain.VanillaContent != null &&
|
||||||
GameMain.VanillaContent.GetFilesOfType(ContentType.Submarine).Any(s => Path.GetFullPath(s) == subPath))
|
GameMain.VanillaContent.Files.Any(s => Path.GetFullPath(s.Path) == subPath))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -870,7 +870,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
GameMain.GameScreen.Select();
|
GameMain.GameScreen.Select();
|
||||||
|
|
||||||
GameSession gameSession = new GameSession(backedUpSubInfo, "", GameModePreset.TestMode, null);
|
GameSession gameSession = new GameSession(backedUpSubInfo, "", GameModePreset.TestMode, CampaignSettings.Empty, null);
|
||||||
gameSession.StartRound(null, false);
|
gameSession.StartRound(null, false);
|
||||||
(gameSession.GameMode as TestGameMode).OnRoundEnd = () =>
|
(gameSession.GameMode as TestGameMode).OnRoundEnd = () =>
|
||||||
{
|
{
|
||||||
@@ -897,6 +897,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (MapEntityCategory category in Enum.GetValues(typeof(MapEntityCategory)))
|
foreach (MapEntityCategory category in Enum.GetValues(typeof(MapEntityCategory)))
|
||||||
{
|
{
|
||||||
|
string categoryName = TextManager.Get("MapEntityCategory." + category);
|
||||||
|
maxTextWidth = (int)Math.Max(maxTextWidth, GUI.SubHeadingFont.MeasureString(categoryName.Replace(' ', '\n')).X + GUI.IntScale(50));
|
||||||
foreach (MapEntityPrefab ep in MapEntityPrefab.List)
|
foreach (MapEntityPrefab ep in MapEntityPrefab.List)
|
||||||
{
|
{
|
||||||
if (!ep.Category.HasFlag(category)) { continue; }
|
if (!ep.Category.HasFlag(category)) { continue; }
|
||||||
@@ -907,13 +909,14 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
entityLists[category + ep.Subcategory].Add(ep);
|
entityLists[category + ep.Subcategory].Add(ep);
|
||||||
categoryKeys[category + ep.Subcategory] = category;
|
categoryKeys[category + ep.Subcategory] = category;
|
||||||
string categoryName = TextManager.Get("subcategory." + ep.Subcategory, returnNull: true) ?? ep.Subcategory;
|
string subcategoryName = TextManager.Get("subcategory." + ep.Subcategory, returnNull: true) ?? ep.Subcategory;
|
||||||
if (categoryName != null)
|
if (subcategoryName != null)
|
||||||
{
|
{
|
||||||
maxTextWidth = (int)Math.Max(maxTextWidth, GUI.SubHeadingFont.MeasureString(categoryName.Replace(' ', '\n')).X + GUI.IntScale(50));
|
maxTextWidth = (int)Math.Max(maxTextWidth, GUI.SubHeadingFont.MeasureString(subcategoryName.Replace(' ', '\n')).X + GUI.IntScale(50));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
categorizedEntityList.Content.ClampMouseRectToParent = true;
|
categorizedEntityList.Content.ClampMouseRectToParent = true;
|
||||||
int entitiesPerRow = (int)Math.Ceiling(categorizedEntityList.Content.Rect.Width / Math.Max(125 * GUI.Scale, 60));
|
int entitiesPerRow = (int)Math.Ceiling(categorizedEntityList.Content.Rect.Width / Math.Max(125 * GUI.Scale, 60));
|
||||||
foreach (string categoryKey in entityLists.Keys)
|
foreach (string categoryKey in entityLists.Keys)
|
||||||
@@ -926,19 +929,33 @@ namespace Barotrauma
|
|||||||
|
|
||||||
new GUIFrame(new RectTransform(Vector2.One, categoryFrame.RectTransform), style: "HorizontalLine");
|
new GUIFrame(new RectTransform(Vector2.One, categoryFrame.RectTransform), style: "HorizontalLine");
|
||||||
|
|
||||||
string categoryName = entityLists[categoryKey].First().Subcategory;
|
string categoryName = TextManager.Get("MapEntityCategory." + entityLists[categoryKey].First().Category);
|
||||||
categoryName = string.IsNullOrEmpty(categoryName) ?
|
string subCategoryName = entityLists[categoryKey].First().Subcategory;
|
||||||
TextManager.Get("mapentitycategory.misc") :
|
if (string.IsNullOrEmpty(subCategoryName))
|
||||||
(TextManager.Get("subcategory." + categoryName, returnNull: true) ?? categoryName);
|
|
||||||
new GUITextBlock(
|
|
||||||
new RectTransform(new Point(maxTextWidth, categoryFrame.Rect.Height), categoryFrame.RectTransform, Anchor.TopLeft),
|
|
||||||
categoryName,
|
|
||||||
textAlignment: Alignment.TopLeft,
|
|
||||||
font: GUI.SubHeadingFont,
|
|
||||||
wrap: true)
|
|
||||||
{
|
{
|
||||||
Padding = new Vector4(GUI.IntScale(10))
|
new GUITextBlock(new RectTransform(new Point(maxTextWidth, categoryFrame.Rect.Height), categoryFrame.RectTransform, Anchor.TopLeft),
|
||||||
};
|
categoryName, textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont, wrap: true)
|
||||||
|
{
|
||||||
|
Padding = new Vector4(GUI.IntScale(10))
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
subCategoryName = string.IsNullOrEmpty(subCategoryName) ?
|
||||||
|
TextManager.Get("mapentitycategory.misc") :
|
||||||
|
(TextManager.Get("subcategory." + subCategoryName, returnNull: true) ?? subCategoryName);
|
||||||
|
var categoryTitle = new GUITextBlock(new RectTransform(new Point(maxTextWidth, categoryFrame.Rect.Height), categoryFrame.RectTransform, Anchor.TopLeft),
|
||||||
|
categoryName, textAlignment: Alignment.TopLeft, font: GUI.Font, wrap: true)
|
||||||
|
{
|
||||||
|
Padding = new Vector4(GUI.IntScale(10))
|
||||||
|
};
|
||||||
|
new GUITextBlock(new RectTransform(new Point(maxTextWidth, categoryFrame.Rect.Height), categoryFrame.RectTransform, Anchor.TopLeft) { AbsoluteOffset = new Point(0, (int)(categoryTitle.TextSize.Y + GUI.IntScale(10))) },
|
||||||
|
subCategoryName, textAlignment: Alignment.TopLeft, font: GUI.SubHeadingFont, wrap: true)
|
||||||
|
{
|
||||||
|
Padding = new Vector4(GUI.IntScale(10))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var entityListInner = new GUIListBox(new RectTransform(new Point(categoryFrame.Rect.Width - maxTextWidth, categoryFrame.Rect.Height), categoryFrame.RectTransform, Anchor.CenterRight),
|
var entityListInner = new GUIListBox(new RectTransform(new Point(categoryFrame.Rect.Width - maxTextWidth, categoryFrame.Rect.Height), categoryFrame.RectTransform, Anchor.CenterRight),
|
||||||
style: null,
|
style: null,
|
||||||
@@ -959,7 +976,6 @@ namespace Barotrauma
|
|||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
if (ep.HideInMenus) { continue; }
|
if (ep.HideInMenus) { continue; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
CreateEntityElement(ep, entitiesPerRow, entityListInner.Content);
|
CreateEntityElement(ep, entitiesPerRow, entityListInner.Content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -976,6 +992,9 @@ namespace Barotrauma
|
|||||||
|
|
||||||
foreach (MapEntityPrefab ep in MapEntityPrefab.List)
|
foreach (MapEntityPrefab ep in MapEntityPrefab.List)
|
||||||
{
|
{
|
||||||
|
#if !DEBUG
|
||||||
|
if (ep.HideInMenus) { continue; }
|
||||||
|
#endif
|
||||||
CreateEntityElement(ep, entitiesPerRow, allEntityList.Content);
|
CreateEntityElement(ep, entitiesPerRow, allEntityList.Content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1354,7 +1373,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Barotrauma.IO.Validation.DevException = true;
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
TimeSpan time = DateTime.UtcNow - DateTime.MinValue;
|
TimeSpan time = DateTime.UtcNow - DateTime.MinValue;
|
||||||
string filePath = Path.Combine(autoSavePath, $"AutoSave_{(ulong)time.TotalMilliseconds}.sub");
|
string filePath = Path.Combine(autoSavePath, $"AutoSave_{(ulong)time.TotalMilliseconds}.sub");
|
||||||
SaveUtil.CompressStringToFile(filePath, doc.ToString());
|
SaveUtil.CompressStringToFile(filePath, doc.ToString());
|
||||||
@@ -1390,7 +1409,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Barotrauma.IO.Validation.DevException = false;
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
CrossThread.RequestExecutionOnMainThread(DisplayAutoSavePrompt);
|
CrossThread.RequestExecutionOnMainThread(DisplayAutoSavePrompt);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
@@ -1558,9 +1577,9 @@ namespace Barotrauma
|
|||||||
msgBox.Buttons[0].OnClicked = (bt, userdata) =>
|
msgBox.Buttons[0].OnClicked = (bt, userdata) =>
|
||||||
{
|
{
|
||||||
contentPackage.AddFile(savePath, ContentType.OutpostModule);
|
contentPackage.AddFile(savePath, ContentType.OutpostModule);
|
||||||
Barotrauma.IO.Validation.DevException = true;
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
contentPackage.Save(contentPackage.Path, reload: false);
|
contentPackage.Save(contentPackage.Path, reload: false);
|
||||||
Barotrauma.IO.Validation.DevException = false;
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
msgBox.Close();
|
msgBox.Close();
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -1635,7 +1654,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (Submarine.MainSub != null)
|
if (Submarine.MainSub != null)
|
||||||
{
|
{
|
||||||
Barotrauma.IO.Validation.DevException = true;
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||||
if (previewImage?.Sprite?.Texture != null && !previewImage.Sprite.Texture.IsDisposed && Submarine.MainSub.Info.Type != SubmarineType.OutpostModule)
|
if (previewImage?.Sprite?.Texture != null && !previewImage.Sprite.Texture.IsDisposed && Submarine.MainSub.Info.Type != SubmarineType.OutpostModule)
|
||||||
{
|
{
|
||||||
bool savePreviewImage = true;
|
bool savePreviewImage = true;
|
||||||
@@ -1655,7 +1674,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Submarine.MainSub.SaveAs(savePath);
|
Submarine.MainSub.SaveAs(savePath);
|
||||||
}
|
}
|
||||||
Barotrauma.IO.Validation.DevException = false;
|
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||||
|
|
||||||
Submarine.MainSub.CheckForErrors();
|
Submarine.MainSub.CheckForErrors();
|
||||||
|
|
||||||
@@ -4695,6 +4714,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
graphics.Clear(backgroundColor);
|
graphics.Clear(backgroundColor);
|
||||||
|
|
||||||
ImageManager.Draw(spriteBatch, cam);
|
ImageManager.Draw(spriteBatch, cam);
|
||||||
|
|
||||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: cam.Transform);
|
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: cam.Transform);
|
||||||
|
|||||||
@@ -63,8 +63,18 @@ namespace Barotrauma.Sounds
|
|||||||
ALFormat = reader.Channels == 1 ? Al.FormatMono16 : Al.FormatStereo16;
|
ALFormat = reader.Channels == 1 ? Al.FormatMono16 : Al.FormatStereo16;
|
||||||
SampleRate = reader.SampleRate;
|
SampleRate = reader.SampleRate;
|
||||||
|
|
||||||
|
if (Buffers != null && SoundBuffers.BuffersGenerated < SoundBuffers.MaxBuffers)
|
||||||
|
{
|
||||||
|
Buffers.RequestAlBuffers(); FillBuffers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void FillBuffers()
|
||||||
|
{
|
||||||
if (!Stream)
|
if (!Stream)
|
||||||
{
|
{
|
||||||
|
reader.DecodedPosition = 0;
|
||||||
|
|
||||||
int bufferSize = (int)reader.TotalSamples * reader.Channels;
|
int bufferSize = (int)reader.TotalSamples * reader.Channels;
|
||||||
|
|
||||||
float[] floatBuffer = new float[bufferSize];
|
float[] floatBuffer = new float[bufferSize];
|
||||||
@@ -86,7 +96,7 @@ namespace Barotrauma.Sounds
|
|||||||
|
|
||||||
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
||||||
|
|
||||||
Al.BufferData(ALBuffer, ALFormat, shortBuffer,
|
Al.BufferData(Buffers.AlBuffer, ALFormat, shortBuffer,
|
||||||
readSamples * sizeof(short), SampleRate);
|
readSamples * sizeof(short), SampleRate);
|
||||||
|
|
||||||
int alError = Al.GetError();
|
int alError = Al.GetError();
|
||||||
@@ -99,7 +109,7 @@ namespace Barotrauma.Sounds
|
|||||||
|
|
||||||
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
||||||
|
|
||||||
Al.BufferData(ALMuffledBuffer, ALFormat, shortBuffer,
|
Al.BufferData(Buffers.AlMuffledBuffer, ALFormat, shortBuffer,
|
||||||
readSamples * sizeof(short), SampleRate);
|
readSamples * sizeof(short), SampleRate);
|
||||||
|
|
||||||
alError = Al.GetError();
|
alError = Al.GetError();
|
||||||
|
|||||||
@@ -52,16 +52,10 @@ namespace Barotrauma.Sounds
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint alBuffer;
|
private SoundBuffers buffers;
|
||||||
public uint ALBuffer
|
public SoundBuffers Buffers
|
||||||
{
|
{
|
||||||
get { return !Stream ? alBuffer : 0; }
|
get { return !Stream ? buffers : null; }
|
||||||
}
|
|
||||||
|
|
||||||
private uint alMuffledBuffer;
|
|
||||||
public uint ALMuffledBuffer
|
|
||||||
{
|
|
||||||
get { return !Stream ? alMuffledBuffer : 0; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int ALFormat
|
public int ALFormat
|
||||||
@@ -169,69 +163,20 @@ namespace Barotrauma.Sounds
|
|||||||
{
|
{
|
||||||
if (!Stream)
|
if (!Stream)
|
||||||
{
|
{
|
||||||
Al.GenBuffer(out alBuffer);
|
buffers = new SoundBuffers(this);
|
||||||
int alError = Al.GetError();
|
|
||||||
if (alError != Al.NoError)
|
|
||||||
{
|
|
||||||
throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Al.IsBuffer(alBuffer))
|
|
||||||
{
|
|
||||||
throw new Exception("Generated OpenAL buffer is invalid!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Al.GenBuffer(out alMuffledBuffer);
|
|
||||||
alError = Al.GetError();
|
|
||||||
if (alError != Al.NoError)
|
|
||||||
{
|
|
||||||
throw new Exception("Failed to create OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Al.IsBuffer(alMuffledBuffer))
|
|
||||||
{
|
|
||||||
throw new Exception("Generated OpenAL buffer is invalid!");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
alBuffer = 0;
|
buffers = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void FillBuffers() { }
|
||||||
|
|
||||||
public virtual void DeleteALBuffers()
|
public virtual void DeleteALBuffers()
|
||||||
{
|
{
|
||||||
Owner.KillChannels(this);
|
Owner.KillChannels(this);
|
||||||
if (alBuffer != 0)
|
buffers?.Dispose();
|
||||||
{
|
|
||||||
if (!Al.IsBuffer(alBuffer))
|
|
||||||
{
|
|
||||||
throw new Exception("Buffer to delete is invalid!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Al.DeleteBuffer(alBuffer); alBuffer = 0;
|
|
||||||
|
|
||||||
int alError = Al.GetError();
|
|
||||||
if (alError != Al.NoError)
|
|
||||||
{
|
|
||||||
throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (alMuffledBuffer != 0)
|
|
||||||
{
|
|
||||||
if (!Al.IsBuffer(alMuffledBuffer))
|
|
||||||
{
|
|
||||||
throw new Exception("Buffer to delete is invalid!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Al.DeleteBuffer(alMuffledBuffer); alMuffledBuffer = 0;
|
|
||||||
|
|
||||||
int alError = Al.GetError();
|
|
||||||
if (alError != Al.NoError)
|
|
||||||
{
|
|
||||||
throw new Exception("Failed to delete OpenAL buffer for non-streamed sound: " + Al.GetErrorString(alError));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Dispose()
|
public virtual void Dispose()
|
||||||
|
|||||||
@@ -334,7 +334,11 @@ namespace Barotrauma.Sounds
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Al.Sourcei(alSource, Al.Buffer, muffled ? (int)Sound.ALMuffledBuffer : (int)Sound.ALBuffer);
|
if (Sound.Buffers.RequestAlBuffers())
|
||||||
|
{
|
||||||
|
Sound.FillBuffers();
|
||||||
|
}
|
||||||
|
Al.Sourcei(alSource, Al.Buffer, muffled ? (int)Sound.Buffers.AlMuffledBuffer : (int)Sound.Buffers.AlBuffer);
|
||||||
|
|
||||||
alError = Al.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != Al.NoError)
|
if (alError != Al.NoError)
|
||||||
@@ -506,17 +510,26 @@ namespace Barotrauma.Sounds
|
|||||||
throw new Exception("Failed to reset source buffer: " + debugName + ", " + Al.GetErrorString(alError));
|
throw new Exception("Failed to reset source buffer: " + debugName + ", " + Al.GetErrorString(alError));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Al.IsBuffer(sound.ALBuffer))
|
if (Sound.Buffers.RequestAlBuffers())
|
||||||
|
{
|
||||||
|
Sound.FillBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Al.IsBuffer(sound.Buffers.AlBuffer))
|
||||||
{
|
{
|
||||||
throw new Exception(sound.Filename + " has an invalid buffer!");
|
throw new Exception(sound.Filename + " has an invalid buffer!");
|
||||||
}
|
}
|
||||||
|
if (!Al.IsBuffer(sound.Buffers.AlMuffledBuffer))
|
||||||
|
{
|
||||||
|
throw new Exception(sound.Filename + " has an invalid muffled buffer!");
|
||||||
|
}
|
||||||
|
|
||||||
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
|
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffled ? Sound.Buffers.AlMuffledBuffer : Sound.Buffers.AlBuffer;
|
||||||
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
|
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
|
||||||
alError = Al.GetError();
|
alError = Al.GetError();
|
||||||
if (alError != Al.NoError)
|
if (alError != Al.NoError)
|
||||||
{
|
{
|
||||||
throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + sound.ALBuffer.ToString() + "): " + debugName + ", " + Al.GetErrorString(alError));
|
throw new Exception("Failed to bind buffer to source (" + ALSourceIndex.ToString() + ":" + sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex) + "," + alBuffer.ToString() + "): " + debugName + ", " + Al.GetErrorString(alError));
|
||||||
}
|
}
|
||||||
|
|
||||||
Al.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
|
Al.SourcePlay(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex));
|
||||||
@@ -528,7 +541,7 @@ namespace Barotrauma.Sounds
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint alBuffer = sound.Owner.GetCategoryMuffle(category) || muffle ? sound.ALMuffledBuffer : sound.ALBuffer;
|
uint alBuffer = 0;
|
||||||
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
|
Al.Sourcei(sound.Owner.GetSourceFromIndex(Sound.SourcePoolIndex, ALSourceIndex), Al.Buffer, (int)alBuffer);
|
||||||
int alError = Al.GetError();
|
int alError = Al.GetError();
|
||||||
if (alError != Al.NoError)
|
if (alError != Al.NoError)
|
||||||
|
|||||||
@@ -30,6 +30,8 @@ namespace Barotrauma.Sounds
|
|||||||
private readonly SoundSourcePool[] sourcePools;
|
private readonly SoundSourcePool[] sourcePools;
|
||||||
|
|
||||||
private readonly List<Sound> loadedSounds;
|
private readonly List<Sound> loadedSounds;
|
||||||
|
public IReadOnlyList<Sound> LoadedSounds => loadedSounds;
|
||||||
|
|
||||||
private readonly SoundChannel[][] playingChannels = new SoundChannel[2][];
|
private readonly SoundChannel[][] playingChannels = new SoundChannel[2][];
|
||||||
private readonly object threadDeathMutex = new object();
|
private readonly object threadDeathMutex = new object();
|
||||||
|
|
||||||
|
|||||||
@@ -172,22 +172,22 @@ namespace Barotrauma
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, Vector2 pos, float rotate = 0.0f, float scale = 1.0f, SpriteEffects spriteEffect = SpriteEffects.None)
|
public void Draw(ISpriteBatch spriteBatch, Vector2 pos, float rotate = 0.0f, float scale = 1.0f, SpriteEffects spriteEffect = SpriteEffects.None)
|
||||||
{
|
{
|
||||||
this.Draw(spriteBatch, pos, Color.White, rotate, scale, spriteEffect);
|
this.Draw(spriteBatch, pos, Color.White, rotate, scale, spriteEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, Vector2 pos, Color color, float rotate = 0.0f, float scale = 1.0f, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = null)
|
public void Draw(ISpriteBatch spriteBatch, Vector2 pos, Color color, float rotate = 0.0f, float scale = 1.0f, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = null)
|
||||||
{
|
{
|
||||||
this.Draw(spriteBatch, pos, color, this.origin, rotate, new Vector2(scale, scale), spriteEffect, depth);
|
this.Draw(spriteBatch, pos, color, this.origin, rotate, new Vector2(scale, scale), spriteEffect, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate = 0.0f, float scale = 1.0f, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = null)
|
public void Draw(ISpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate = 0.0f, float scale = 1.0f, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = null)
|
||||||
{
|
{
|
||||||
this.Draw(spriteBatch, pos, color, origin, rotate, new Vector2(scale, scale), spriteEffect, depth);
|
this.Draw(spriteBatch, pos, color, origin, rotate, new Vector2(scale, scale), spriteEffect, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Draw(SpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = null)
|
public virtual void Draw(ISpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = null)
|
||||||
{
|
{
|
||||||
if (Texture == null) { return; }
|
if (Texture == null) { return; }
|
||||||
//DrawSilhouette(spriteBatch, pos, origin, rotate, scale, spriteEffect, depth);
|
//DrawSilhouette(spriteBatch, pos, origin, rotate, scale, spriteEffect, depth);
|
||||||
@@ -209,7 +209,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DrawTiled(SpriteBatch spriteBatch, Vector2 position, Vector2 targetSize,
|
public void DrawTiled(ISpriteBatch spriteBatch, Vector2 position, Vector2 targetSize,
|
||||||
Color? color = null, Vector2? startOffset = null, Vector2? textureScale = null, float? depth = null)
|
Color? color = null, Vector2? startOffset = null, Vector2? textureScale = null, float? depth = null)
|
||||||
{
|
{
|
||||||
if (Texture == null) { return; }
|
if (Texture == null) { return; }
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
partial class SpriteSheet : Sprite
|
partial class SpriteSheet : Sprite
|
||||||
{
|
{
|
||||||
public override void Draw(SpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = default(float?))
|
public override void Draw(ISpriteBatch spriteBatch, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = default(float?))
|
||||||
{
|
{
|
||||||
if (texture == null) return;
|
if (texture == null) return;
|
||||||
|
|
||||||
spriteBatch.Draw(texture, pos + offset, sourceRects[0], color, rotation + rotate, origin, scale, spriteEffect, depth == null ? this.depth : (float)depth);
|
spriteBatch.Draw(texture, pos + offset, sourceRects[0], color, rotation + rotate, origin, scale, spriteEffect, depth == null ? this.depth : (float)depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Draw(SpriteBatch spriteBatch, int spriteIndex, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = default(float?))
|
public void Draw(ISpriteBatch spriteBatch, int spriteIndex, Vector2 pos, Color color, Vector2 origin, float rotate, Vector2 scale, SpriteEffects spriteEffect = SpriteEffects.None, float? depth = default(float?))
|
||||||
{
|
{
|
||||||
if (texture == null) return;
|
if (texture == null) return;
|
||||||
|
|
||||||
|
|||||||
@@ -100,38 +100,6 @@ namespace Barotrauma
|
|||||||
return q1;
|
return q1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Convert a HSV value into a RGB value.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="hue">Value between 0 and 360</param>
|
|
||||||
/// <param name="saturation">Value between 0 and 1</param>
|
|
||||||
/// <param name="value">Value between 0 and 1</param>
|
|
||||||
/// <see href="https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB">Reference</see>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Color HSVToRGB(float hue, float saturation, float value)
|
|
||||||
{
|
|
||||||
float c = value * saturation;
|
|
||||||
|
|
||||||
float h = Math.Clamp(hue, 0, 360) / 60f;
|
|
||||||
|
|
||||||
float x = c * (1 - Math.Abs(h % 2 - 1));
|
|
||||||
|
|
||||||
float r = 0,
|
|
||||||
g = 0,
|
|
||||||
b = 0;
|
|
||||||
|
|
||||||
if (0 <= h && h <= 1) { r = c; g = x; b = 0; }
|
|
||||||
else if (1 < h && h <= 2) { r = x; g = c; b = 0; }
|
|
||||||
else if (2 < h && h <= 3) { r = 0; g = c; b = x; }
|
|
||||||
else if (3 < h && h <= 4) { r = 0; g = x; b = c; }
|
|
||||||
else if (4 < h && h <= 5) { r = x; g = 0; b = c; }
|
|
||||||
else if (5 < h && h <= 6) { r = c; g = 0; b = x; }
|
|
||||||
|
|
||||||
float m = value - c;
|
|
||||||
|
|
||||||
return new Color(r + m, g + m, b + m);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Convert a RGB value into a HSV value.
|
/// Convert a RGB value into a HSV value.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.1300.0.0</Version>
|
<Version>0.1300.0.1</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.1300.0.0</Version>
|
<Version>0.1300.0.1</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma</Product>
|
<Product>Barotrauma</Product>
|
||||||
<Version>0.1300.0.0</Version>
|
<Version>0.1300.0.1</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>Barotrauma</AssemblyName>
|
<AssemblyName>Barotrauma</AssemblyName>
|
||||||
|
|||||||
@@ -1,62 +1,62 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||||
<security>
|
<security>
|
||||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||||
</requestedPrivileges>
|
</requestedPrivileges>
|
||||||
</security>
|
</security>
|
||||||
</trustInfo>
|
</trustInfo>
|
||||||
|
|
||||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
<application>
|
<application>
|
||||||
<!-- A list of the Windows versions that this application has been tested on
|
<!-- A list of the Windows versions that this application has been tested on
|
||||||
and is designed to work with. Uncomment the appropriate elements
|
and is designed to work with. Uncomment the appropriate elements
|
||||||
and Windows will automatically select the most compatible environment. -->
|
and Windows will automatically select the most compatible environment. -->
|
||||||
|
|
||||||
<!-- Windows Vista -->
|
<!-- Windows Vista -->
|
||||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||||
|
|
||||||
<!-- Windows 7 -->
|
<!-- Windows 7 -->
|
||||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||||
|
|
||||||
<!-- Windows 8 -->
|
<!-- Windows 8 -->
|
||||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||||
|
|
||||||
<!-- Windows 8.1 -->
|
<!-- Windows 8.1 -->
|
||||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||||
|
|
||||||
<!-- Windows 10 -->
|
<!-- Windows 10 -->
|
||||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
</compatibility>
|
</compatibility>
|
||||||
|
|
||||||
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
|
<!-- Indicates that the application is DPI-aware and will not be automatically scaled by Windows at higher
|
||||||
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
|
DPIs. Windows Presentation Foundation (WPF) applications are automatically DPI-aware and do not need
|
||||||
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
|
to opt in. Windows Forms applications targeting .NET Framework 4.6 that opt into this setting, should
|
||||||
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
|
also set the 'EnableWindowsFormsHighDpiAutoResizing' setting to 'true' in their app.config. -->
|
||||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
<windowsSettings>
|
<windowsSettings>
|
||||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||||
</windowsSettings>
|
</windowsSettings>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||||
<!--
|
<!--
|
||||||
<dependency>
|
<dependency>
|
||||||
<dependentAssembly>
|
<dependentAssembly>
|
||||||
<assemblyIdentity
|
<assemblyIdentity
|
||||||
type="win32"
|
type="win32"
|
||||||
name="Microsoft.Windows.Common-Controls"
|
name="Microsoft.Windows.Common-Controls"
|
||||||
version="6.0.0.0"
|
version="6.0.0.0"
|
||||||
processorArchitecture="*"
|
processorArchitecture="*"
|
||||||
publicKeyToken="6595b64144ccf1df"
|
publicKeyToken="6595b64144ccf1df"
|
||||||
language="*"
|
language="*"
|
||||||
/>
|
/>
|
||||||
</dependentAssembly>
|
</dependentAssembly>
|
||||||
</dependency>
|
</dependency>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
</assembly>
|
</assembly>
|
||||||
|
|||||||
Regular → Executable
Regular → Executable
Regular → Executable
@@ -1,139 +1,139 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.1300.0.0</Version>
|
<Version>0.1300.0.1</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||||
<Configurations>Debug;Release;Unstable</Configurations>
|
<Configurations>Debug;Release;Unstable</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<DefineConstants>DEBUG;TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
<DefineConstants>DEBUG;TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<DefineConstants>TRACE;DEBUG;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;DEBUG;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||||
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||||
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||||
<Content Include="DedicatedServer.exe" CopyToOutputDirectory="PreserveNewest" />
|
<Content Include="DedicatedServer.exe" CopyToOutputDirectory="PreserveNewest" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||||
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- write the hash to the temp file.-->
|
<!-- write the hash to the temp file.-->
|
||||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||||
</Exec>
|
</Exec>
|
||||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD --symbolic-full-name --abbrev-ref=strict > $(BranchFile)" ContinueOnError="true" />
|
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD --symbolic-full-name --abbrev-ref=strict > $(BranchFile)" ContinueOnError="true" />
|
||||||
|
|
||||||
<Exec Command="echo GIT_UNAVAILABLE > $(VerFile)" Condition="'%(exitcodes.identity)'>0" />
|
<Exec Command="echo GIT_UNAVAILABLE > $(VerFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||||
<Exec Command="echo GIT_UNAVAILABLE > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
<Exec Command="echo GIT_UNAVAILABLE > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||||
|
|
||||||
<!-- read the version into the GitVersion itemGroup-->
|
<!-- read the version into the GitVersion itemGroup-->
|
||||||
<ReadLinesFromFile File="$(VerFile)">
|
<ReadLinesFromFile File="$(VerFile)">
|
||||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||||
</ReadLinesFromFile>
|
</ReadLinesFromFile>
|
||||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<BuildHash>@(GitVersion)</BuildHash>
|
<BuildHash>@(GitVersion)</BuildHash>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- read the branch into the GitBranch itemGroup-->
|
<!-- read the branch into the GitBranch itemGroup-->
|
||||||
<ReadLinesFromFile File="$(BranchFile)">
|
<ReadLinesFromFile File="$(BranchFile)">
|
||||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||||
</ReadLinesFromFile>
|
</ReadLinesFromFile>
|
||||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>GitRevision</_Parameter1>
|
<_Parameter1>GitRevision</_Parameter1>
|
||||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>GitBranch</_Parameter1>
|
<_Parameter1>GitBranch</_Parameter1>
|
||||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>ProjectDir</_Parameter1>
|
<_Parameter1>ProjectDir</_Parameter1>
|
||||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,152 +1,152 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.1300.0.0</Version>
|
<Version>0.1300.0.1</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||||
<ReleaseVersion>0.9.0.0</ReleaseVersion>
|
<ReleaseVersion>0.9.0.0</ReleaseVersion>
|
||||||
<Configurations>Debug;Release;Unstable</Configurations>
|
<Configurations>Debug;Release;Unstable</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;DEBUG;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
|
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;DEBUG;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\DebugMac</OutputPath>
|
<OutputPath>..\bin\DebugMac</OutputPath>
|
||||||
<ConsolePause>true</ConsolePause>
|
<ConsolePause>true</ConsolePause>
|
||||||
<CheckForOverflowUnderflow></CheckForOverflowUnderflow>
|
<CheckForOverflowUnderflow></CheckForOverflowUnderflow>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<DefineConstants>TRACE;DEBUG;SERVER;OSX;X64;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;DEBUG;SERVER;OSX;X64;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
|
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<DebugType></DebugType>
|
<DebugType></DebugType>
|
||||||
<OutputPath>..\bin\ReleaseMac</OutputPath>
|
<OutputPath>..\bin\ReleaseMac</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0;UNSTABLE</DefineConstants>
|
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0;UNSTABLE</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<DebugType />
|
<DebugType />
|
||||||
<OutputPath>..\bin\ReleaseMac</OutputPath>
|
<OutputPath>..\bin\ReleaseMac</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||||
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM;UNSTABLE</DefineConstants>
|
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM;UNSTABLE</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||||
<Content Remove="..\BarotraumaShared\libsteam_api64.dylib" />
|
<Content Remove="..\BarotraumaShared\libsteam_api64.dylib" />
|
||||||
<Content Remove="..\BarotraumaShared\libsteam_api64.so" />
|
<Content Remove="..\BarotraumaShared\libsteam_api64.so" />
|
||||||
<Content Remove="DedicatedServer.exe" />
|
<Content Remove="DedicatedServer.exe" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||||
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Posix.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="..\BarotraumaShared\libsteam_api64.dylib">
|
<None Include="..\BarotraumaShared\libsteam_api64.dylib">
|
||||||
<Link>libsteam_api64.dylib</Link>
|
<Link>libsteam_api64.dylib</Link>
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- write the hash to the temp file.-->
|
<!-- write the hash to the temp file.-->
|
||||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||||
</Exec>
|
</Exec>
|
||||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD --symbolic-full-name --abbrev-ref=strict > $(BranchFile)" ContinueOnError="true" />
|
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD --symbolic-full-name --abbrev-ref=strict > $(BranchFile)" ContinueOnError="true" />
|
||||||
|
|
||||||
<Exec Command="echo GIT_UNAVAILABLE > $(VerFile)" Condition="'%(exitcodes.identity)'>0" />
|
<Exec Command="echo GIT_UNAVAILABLE > $(VerFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||||
<Exec Command="echo GIT_UNAVAILABLE > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
<Exec Command="echo GIT_UNAVAILABLE > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||||
|
|
||||||
<!-- read the version into the GitVersion itemGroup-->
|
<!-- read the version into the GitVersion itemGroup-->
|
||||||
<ReadLinesFromFile File="$(VerFile)">
|
<ReadLinesFromFile File="$(VerFile)">
|
||||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||||
</ReadLinesFromFile>
|
</ReadLinesFromFile>
|
||||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<BuildHash>@(GitVersion)</BuildHash>
|
<BuildHash>@(GitVersion)</BuildHash>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- read the branch into the GitBranch itemGroup-->
|
<!-- read the branch into the GitBranch itemGroup-->
|
||||||
<ReadLinesFromFile File="$(BranchFile)">
|
<ReadLinesFromFile File="$(BranchFile)">
|
||||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||||
</ReadLinesFromFile>
|
</ReadLinesFromFile>
|
||||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>GitRevision</_Parameter1>
|
<_Parameter1>GitRevision</_Parameter1>
|
||||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>GitBranch</_Parameter1>
|
<_Parameter1>GitBranch</_Parameter1>
|
||||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>ProjectDir</_Parameter1>
|
<_Parameter1>ProjectDir</_Parameter1>
|
||||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
msg.Write(ID);
|
msg.Write(ID);
|
||||||
msg.Write(Name);
|
msg.Write(Name);
|
||||||
|
msg.Write(OriginalName);
|
||||||
msg.Write((byte)Gender);
|
msg.Write((byte)Gender);
|
||||||
msg.Write((byte)Race);
|
msg.Write((byte)Race);
|
||||||
msg.Write((byte)HeadSpriteId);
|
msg.Write((byte)HeadSpriteId);
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ namespace Barotrauma
|
|||||||
foreach (Character character in characters)
|
foreach (Character character in characters)
|
||||||
{
|
{
|
||||||
character.WriteSpawnData(msg, character.ID, restrictMessageSize: false);
|
character.WriteSpawnData(msg, character.ID, restrictMessageSize: false);
|
||||||
|
msg.Write(requireKill.Contains(character));
|
||||||
|
msg.Write(requireRescue.Contains(character));
|
||||||
msg.Write((ushort)characterItems[character].Count());
|
msg.Write((ushort)characterItems[character].Count());
|
||||||
foreach (Item item in characterItems[character])
|
foreach (Item item in characterItems[character])
|
||||||
{
|
{
|
||||||
|
|||||||
+90
-16
@@ -32,11 +32,11 @@ namespace Barotrauma
|
|||||||
get { return ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"); }
|
get { return ForceMapUI || CoroutineManager.IsCoroutineRunning("LevelTransition"); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void StartNewCampaign(string savePath, string subPath, string seed)
|
public static void StartNewCampaign(string savePath, string subPath, string seed, CampaignSettings settings)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(savePath)) { return; }
|
if (string.IsNullOrWhiteSpace(savePath)) { return; }
|
||||||
|
|
||||||
GameMain.GameSession = new GameSession(new SubmarineInfo(subPath), savePath, GameModePreset.MultiPlayerCampaign, seed);
|
GameMain.GameSession = new GameSession(new SubmarineInfo(subPath), savePath, GameModePreset.MultiPlayerCampaign, settings, seed);
|
||||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ namespace Barotrauma
|
|||||||
DebugConsole.ShowQuestionPrompt("Enter a save name for the campaign:", (string saveName) =>
|
DebugConsole.ShowQuestionPrompt("Enter a save name for the campaign:", (string saveName) =>
|
||||||
{
|
{
|
||||||
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveName);
|
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveName);
|
||||||
StartNewCampaign(savePath, GameMain.NetLobbyScreen.SelectedSub.FilePath, GameMain.NetLobbyScreen.LevelSeed);
|
StartNewCampaign(savePath, GameMain.NetLobbyScreen.SelectedSub.FilePath, GameMain.NetLobbyScreen.LevelSeed, CampaignSettings.Empty);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -667,13 +667,24 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool validateHires = msg.ReadBoolean();
|
bool validateHires = msg.ReadBoolean();
|
||||||
bool fireCharacter = msg.ReadBoolean();
|
|
||||||
|
|
||||||
|
bool renameCharacter = msg.ReadBoolean();
|
||||||
|
int renamedIdentifier = -1;
|
||||||
|
string newName = null;
|
||||||
|
bool existingCrewMember = false;
|
||||||
|
if (renameCharacter)
|
||||||
|
{
|
||||||
|
renamedIdentifier = msg.ReadInt32();
|
||||||
|
newName = msg.ReadString();
|
||||||
|
existingCrewMember = msg.ReadBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fireCharacter = msg.ReadBoolean();
|
||||||
int firedIdentifier = -1;
|
int firedIdentifier = -1;
|
||||||
if (fireCharacter) { firedIdentifier = msg.ReadInt32(); }
|
if (fireCharacter) { firedIdentifier = msg.ReadInt32(); }
|
||||||
|
|
||||||
Location location = map?.CurrentLocation;
|
Location location = map?.CurrentLocation;
|
||||||
|
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
|
||||||
CharacterInfo firedCharacter = null;
|
CharacterInfo firedCharacter = null;
|
||||||
|
|
||||||
if (location != null && AllowedToManageCampaign(sender))
|
if (location != null && AllowedToManageCampaign(sender))
|
||||||
@@ -691,13 +702,45 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (renameCharacter)
|
||||||
|
{
|
||||||
|
CharacterInfo characterInfo = null;
|
||||||
|
if (existingCrewMember && CrewManager != null)
|
||||||
|
{
|
||||||
|
characterInfo = CrewManager.CharacterInfos.FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == renamedIdentifier);
|
||||||
|
}
|
||||||
|
else if(!existingCrewMember && location.HireManager != null)
|
||||||
|
{
|
||||||
|
characterInfo = location.HireManager.AvailableCharacters.FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == renamedIdentifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (characterInfo != null && (characterInfo.Character?.IsBot ?? true))
|
||||||
|
{
|
||||||
|
if (existingCrewMember)
|
||||||
|
{
|
||||||
|
CrewManager.RenameCharacter(characterInfo, newName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
location.HireManager.RenameCharacter(characterInfo, newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DebugConsole.ThrowError($"Tried to rename an invalid character ({renamedIdentifier})");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (location.HireManager != null)
|
if (location.HireManager != null)
|
||||||
{
|
{
|
||||||
if (validateHires)
|
if (validateHires)
|
||||||
{
|
{
|
||||||
foreach (CharacterInfo hireInfo in location.HireManager.PendingHires)
|
foreach (CharacterInfo hireInfo in location.HireManager.PendingHires)
|
||||||
{
|
{
|
||||||
TryHireCharacter(location, hireInfo);
|
if (TryHireCharacter(location, hireInfo))
|
||||||
|
{
|
||||||
|
hiredCharacters.Add(hireInfo);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -706,10 +749,10 @@ namespace Barotrauma
|
|||||||
List<CharacterInfo> pendingHireInfos = new List<CharacterInfo>();
|
List<CharacterInfo> pendingHireInfos = new List<CharacterInfo>();
|
||||||
foreach (int identifier in pendingHires)
|
foreach (int identifier in pendingHires)
|
||||||
{
|
{
|
||||||
CharacterInfo match = location.GetHireableCharacters().FirstOrDefault(info => info.GetIdentifier() == identifier);
|
CharacterInfo match = location.GetHireableCharacters().FirstOrDefault(info => info.GetIdentifierUsingOriginalName() == identifier);
|
||||||
if (match == null)
|
if (match == null)
|
||||||
{
|
{
|
||||||
DebugConsole.ThrowError($"Tried to hire a character that doesn't exist ({identifier})");
|
DebugConsole.ThrowError($"Tried to add a character that doesn't exist ({identifier}) to pending hires");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -721,25 +764,39 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
location.HireManager.PendingHires = pendingHireInfos;
|
location.HireManager.PendingHires = pendingHireInfos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
location.HireManager.AvailableCharacters.ForEachMod(info =>
|
||||||
|
{
|
||||||
|
if(!location.HireManager.PendingHires.Contains(info))
|
||||||
|
{
|
||||||
|
location.HireManager.RenameCharacter(info, info.OriginalName);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// bounce back
|
// bounce back
|
||||||
SendCrewState(validateHires, firedCharacter);
|
if (renameCharacter && existingCrewMember)
|
||||||
|
{
|
||||||
|
SendCrewState(hiredCharacters, (renamedIdentifier, newName), firedCharacter);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendCrewState(hiredCharacters, default, firedCharacter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Notifies the clients of the current bot situation like syncing pending and available hires
|
/// Notifies the clients of the current bot situation like syncing pending and available hires
|
||||||
/// available hires are also synced
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="validateHires">When set to true notifies the clients that the hires have been validated.</param>
|
/// <param name="hiredCharacters">Inform the clients that these characters have been hired.</param>
|
||||||
/// <param name="firedCharacter">When not null will inform the clients that his character has been fired.</param>
|
/// <param name="firedCharacter">Inform the clients that this character has been fired.</param>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// It might be obsolete to sync available hires. I found that the available hires are always the same between
|
/// It might be obsolete to sync available hires. I found that the available hires are always the same between
|
||||||
/// the client and the server when there's only one person on the server but when a second person joins both of
|
/// the client and the server when there's only one person on the server but when a second person joins both of
|
||||||
/// their available hires are different from the server.
|
/// their available hires are different from the server.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public void SendCrewState(bool validateHires, CharacterInfo firedCharacter)
|
public void SendCrewState(List<CharacterInfo> hiredCharacters, (int id, string newName) renamedCrewMember, CharacterInfo firedCharacter)
|
||||||
{
|
{
|
||||||
List<CharacterInfo> availableHires = new List<CharacterInfo>();
|
List<CharacterInfo> availableHires = new List<CharacterInfo>();
|
||||||
List<CharacterInfo> pendingHires = new List<CharacterInfo>();
|
List<CharacterInfo> pendingHires = new List<CharacterInfo>();
|
||||||
@@ -765,10 +822,26 @@ namespace Barotrauma
|
|||||||
msg.Write((ushort)pendingHires.Count);
|
msg.Write((ushort)pendingHires.Count);
|
||||||
foreach (CharacterInfo pendingHire in pendingHires)
|
foreach (CharacterInfo pendingHire in pendingHires)
|
||||||
{
|
{
|
||||||
msg.Write(pendingHire.GetIdentifier());
|
msg.Write(pendingHire.GetIdentifierUsingOriginalName());
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.Write((ushort)(hiredCharacters?.Count ?? 0));
|
||||||
|
if(hiredCharacters != null)
|
||||||
|
{
|
||||||
|
foreach (CharacterInfo info in hiredCharacters)
|
||||||
|
{
|
||||||
|
info.ServerWrite(msg);
|
||||||
|
msg.Write(info.Salary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validRenaming = renamedCrewMember.id > -1 && !string.IsNullOrEmpty(renamedCrewMember.newName);
|
||||||
|
msg.Write(validRenaming);
|
||||||
|
if (validRenaming)
|
||||||
|
{
|
||||||
|
msg.Write(renamedCrewMember.id);
|
||||||
|
msg.Write(renamedCrewMember.newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.Write(validateHires);
|
|
||||||
|
|
||||||
msg.Write(firedCharacter != null);
|
msg.Write(firedCharacter != null);
|
||||||
if (firedCharacter != null) { msg.Write(firedCharacter.GetIdentifier()); }
|
if (firedCharacter != null) { msg.Write(firedCharacter.GetIdentifier()); }
|
||||||
@@ -786,6 +859,7 @@ namespace Barotrauma
|
|||||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
||||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||||
new XAttribute("cheatsenabled", CheatsEnabled));
|
new XAttribute("cheatsenabled", CheatsEnabled));
|
||||||
|
modeElement.Add(Settings.Save());
|
||||||
CampaignMetadata?.Save(modeElement);
|
CampaignMetadata?.Save(modeElement);
|
||||||
Map.Save(modeElement);
|
Map.Save(modeElement);
|
||||||
CargoManager?.SavePurchasedItems(modeElement);
|
CargoManager?.SavePurchasedItems(modeElement);
|
||||||
|
|||||||
@@ -121,13 +121,14 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsBanned(IPAddress IP, ulong steamID, out string reason)
|
public bool IsBanned(IPAddress IP, ulong steamID, ulong ownerSteamID, out string reason)
|
||||||
{
|
{
|
||||||
reason = string.Empty;
|
reason = string.Empty;
|
||||||
if (IPAddress.IsLoopback(IP)) { return false; }
|
if (IPAddress.IsLoopback(IP)) { return false; }
|
||||||
var bannedPlayer = bannedPlayers.Find(bp =>
|
var bannedPlayer = bannedPlayers.Find(bp =>
|
||||||
bp.CompareTo(IP) ||
|
bp.CompareTo(IP) ||
|
||||||
(steamID > 0 && (bp.SteamID == steamID || SteamManager.SteamIDStringToUInt64(bp.EndPoint) == steamID)));
|
(steamID > 0 && (bp.SteamID == steamID || SteamManager.SteamIDStringToUInt64(bp.EndPoint) == steamID)) ||
|
||||||
|
(ownerSteamID > 0 && (bp.SteamID == ownerSteamID || SteamManager.SteamIDStringToUInt64(bp.EndPoint) == ownerSteamID)));
|
||||||
reason = bannedPlayer?.Reason;
|
reason = bannedPlayer?.Reason;
|
||||||
return bannedPlayer != null;
|
return bannedPlayer != null;
|
||||||
}
|
}
|
||||||
@@ -166,6 +167,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
public void BanPlayer(string name, ulong steamID, string reason, TimeSpan? duration)
|
public void BanPlayer(string name, ulong steamID, string reason, TimeSpan? duration)
|
||||||
{
|
{
|
||||||
|
if (steamID == 0) { return; }
|
||||||
BanPlayer(name, "", steamID, reason, duration);
|
BanPlayer(name, "", steamID, reason, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -284,6 +284,7 @@ namespace Barotrauma.Networking
|
|||||||
newClient.Connection = connection;
|
newClient.Connection = connection;
|
||||||
newClient.Connection.Status = NetworkConnectionStatus.Connected;
|
newClient.Connection.Status = NetworkConnectionStatus.Connected;
|
||||||
newClient.SteamID = connection.SteamID;
|
newClient.SteamID = connection.SteamID;
|
||||||
|
newClient.OwnerSteamID = connection.OwnerSteamID;
|
||||||
newClient.Language = connection.Language;
|
newClient.Language = connection.Language;
|
||||||
ConnectedClients.Add(newClient);
|
ConnectedClients.Add(newClient);
|
||||||
|
|
||||||
@@ -308,12 +309,13 @@ namespace Barotrauma.Networking
|
|||||||
SendConsoleMessage("Granted all permissions to " + newClient.Name + ".", newClient);
|
SendConsoleMessage("Granted all permissions to " + newClient.Name + ".", newClient);
|
||||||
}
|
}
|
||||||
|
|
||||||
SendChatMessage($"ServerMessage.JoinedServer~[client]={clName}", ChatMessageType.Server, null, changeType: PlayerConnectionChangeType.Joined);
|
SendChatMessage($"ServerMessage.JoinedServer~[client]={ClientLogName(newClient)}", ChatMessageType.Server, null, changeType: PlayerConnectionChangeType.Joined);
|
||||||
serverSettings.ServerDetailsChanged = true;
|
serverSettings.ServerDetailsChanged = true;
|
||||||
|
|
||||||
if (previousPlayer != null && previousPlayer.Name != newClient.Name)
|
if (previousPlayer != null && previousPlayer.Name != newClient.Name)
|
||||||
{
|
{
|
||||||
SendChatMessage($"ServerMessage.PreviousClientName~[client]={clName}~[previousname]={previousPlayer.Name}", ChatMessageType.Server, null);
|
string prevNameSanitized = previousPlayer.Name.Replace("‖", "");
|
||||||
|
SendChatMessage($"ServerMessage.PreviousClientName~[client]={ClientLogName(newClient)}~[previousname]={prevNameSanitized}", ChatMessageType.Server, null);
|
||||||
previousPlayer.Name = newClient.Name;
|
previousPlayer.Name = newClient.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -475,12 +477,14 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else if (isCrewDead && respawnManager == null)
|
else if (isCrewDead && respawnManager == null)
|
||||||
{
|
{
|
||||||
|
#if !DEBUG
|
||||||
if (endRoundTimer <= 0.0f)
|
if (endRoundTimer <= 0.0f)
|
||||||
{
|
{
|
||||||
SendChatMessage(TextManager.GetWithVariable("CrewDeadNoRespawns", "[time]", "60"), ChatMessageType.Server);
|
SendChatMessage(TextManager.GetWithVariable("CrewDeadNoRespawns", "[time]", "60"), ChatMessageType.Server);
|
||||||
}
|
}
|
||||||
endRoundDelay = 60.0f;
|
endRoundDelay = 60.0f;
|
||||||
endRoundTimer += deltaTime;
|
endRoundTimer += deltaTime;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -752,6 +756,7 @@ namespace Barotrauma.Networking
|
|||||||
string seed = inc.ReadString();
|
string seed = inc.ReadString();
|
||||||
string subName = inc.ReadString();
|
string subName = inc.ReadString();
|
||||||
string subHash = inc.ReadString();
|
string subHash = inc.ReadString();
|
||||||
|
CampaignSettings settings = new CampaignSettings(inc);
|
||||||
|
|
||||||
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
|
var matchingSub = SubmarineInfo.SavedSubmarines.FirstOrDefault(s => s.Name == subName && s.MD5Hash.Hash == subHash);
|
||||||
|
|
||||||
@@ -772,10 +777,10 @@ namespace Barotrauma.Networking
|
|||||||
string localSavePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveName);
|
string localSavePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveName);
|
||||||
if (connectedClient.HasPermission(ClientPermissions.SelectMode) || connectedClient.HasPermission(ClientPermissions.ManageCampaign))
|
if (connectedClient.HasPermission(ClientPermissions.SelectMode) || connectedClient.HasPermission(ClientPermissions.ManageCampaign))
|
||||||
{
|
{
|
||||||
MultiPlayerCampaign.StartNewCampaign(localSavePath, matchingSub.FilePath, seed);
|
MultiPlayerCampaign.StartNewCampaign(localSavePath, matchingSub.FilePath, seed, settings);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string saveName = inc.ReadString();
|
string saveName = inc.ReadString();
|
||||||
@@ -1853,6 +1858,8 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
outmsg.Write(autoRestartTimerRunning ? serverSettings.AutoRestartTimer : 0.0f);
|
outmsg.Write(autoRestartTimerRunning ? serverSettings.AutoRestartTimer : 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
outmsg.Write(serverSettings.RadiationEnabled);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -2034,12 +2041,12 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
startGameCoroutine = GameMain.Instance.ShowLoading(StartGame(selectedSub, selectedShuttle, selectedMode), false);
|
startGameCoroutine = GameMain.Instance.ShowLoading(StartGame(selectedSub, selectedShuttle, selectedMode, CampaignSettings.Unsure), false);
|
||||||
|
|
||||||
yield return CoroutineStatus.Success;
|
yield return CoroutineStatus.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<object> StartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode)
|
private IEnumerable<object> StartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode, CampaignSettings settings)
|
||||||
{
|
{
|
||||||
entityEventManager.Clear();
|
entityEventManager.Clear();
|
||||||
|
|
||||||
@@ -2067,7 +2074,7 @@ namespace Barotrauma.Networking
|
|||||||
//don't instantiate a new gamesession if we're playing a campaign
|
//don't instantiate a new gamesession if we're playing a campaign
|
||||||
if (campaign == null || GameMain.GameSession == null)
|
if (campaign == null || GameMain.GameSession == null)
|
||||||
{
|
{
|
||||||
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, GameMain.NetLobbyScreen.LevelSeed, missionType: GameMain.NetLobbyScreen.MissionType);
|
GameMain.GameSession = new GameSession(selectedSub, "", selectedMode, settings, GameMain.NetLobbyScreen.LevelSeed, missionType: GameMain.NetLobbyScreen.MissionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Client> playingClients = new List<Client>(connectedClients);
|
List<Client> playingClients = new List<Client>(connectedClients);
|
||||||
@@ -2716,6 +2723,10 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
serverSettings.BanList.BanPlayer(client.Name, client.SteamID, reason, duration);
|
serverSettings.BanList.BanPlayer(client.Name, client.SteamID, reason, duration);
|
||||||
}
|
}
|
||||||
|
if (client.OwnerSteamID > 0)
|
||||||
|
{
|
||||||
|
serverSettings.BanList.BanPlayer(client.Name, client.OwnerSteamID, reason, duration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BanPreviousPlayer(PreviousPlayer previousPlayer, string reason, bool range = false, TimeSpan? duration = null)
|
public void BanPreviousPlayer(PreviousPlayer previousPlayer, string reason, bool range = false, TimeSpan? duration = null)
|
||||||
@@ -2735,6 +2746,10 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
serverSettings.BanList.BanPlayer(previousPlayer.Name, previousPlayer.SteamID, reason, duration);
|
serverSettings.BanList.BanPlayer(previousPlayer.Name, previousPlayer.SteamID, reason, duration);
|
||||||
}
|
}
|
||||||
|
if (previousPlayer.OwnerSteamID > 0)
|
||||||
|
{
|
||||||
|
serverSettings.BanList.BanPlayer(previousPlayer.Name, previousPlayer.OwnerSteamID, reason, duration);
|
||||||
|
}
|
||||||
|
|
||||||
string msg = $"ServerMessage.BannedFromServer~[client]={previousPlayer.Name}";
|
string msg = $"ServerMessage.BannedFromServer~[client]={previousPlayer.Name}";
|
||||||
if (!string.IsNullOrWhiteSpace(reason))
|
if (!string.IsNullOrWhiteSpace(reason))
|
||||||
@@ -2784,7 +2799,7 @@ namespace Barotrauma.Networking
|
|||||||
client.HasSpawned = false;
|
client.HasSpawned = false;
|
||||||
client.InGame = false;
|
client.InGame = false;
|
||||||
|
|
||||||
if (string.IsNullOrWhiteSpace(msg)) { msg = $"ServerMessage.ClientLeftServer~[client]={client.Name}"; }
|
if (string.IsNullOrWhiteSpace(msg)) { msg = $"ServerMessage.ClientLeftServer~[client]={ClientLogName(client)}"; }
|
||||||
if (string.IsNullOrWhiteSpace(targetmsg)) { targetmsg = "ServerMessage.YouLeftServer"; }
|
if (string.IsNullOrWhiteSpace(targetmsg)) { targetmsg = "ServerMessage.YouLeftServer"; }
|
||||||
if (!string.IsNullOrWhiteSpace(reason))
|
if (!string.IsNullOrWhiteSpace(reason))
|
||||||
{
|
{
|
||||||
@@ -3747,7 +3762,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
retVal += "color:#ff9900;";
|
retVal += "color:#ff9900;";
|
||||||
}
|
}
|
||||||
retVal += "metadata:" + (client.SteamID != 0 ? client.SteamID.ToString() : client.ID.ToString()) + "‖" + (name ?? client.Name) + "‖end‖";
|
retVal += "metadata:" + (client.SteamID != 0 ? client.SteamID.ToString() : client.ID.ToString()) + "‖" + (name ?? client.Name).Replace("‖","") + "‖end‖";
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3826,6 +3841,7 @@ namespace Barotrauma.Networking
|
|||||||
public string Name;
|
public string Name;
|
||||||
public string EndPoint;
|
public string EndPoint;
|
||||||
public UInt64 SteamID;
|
public UInt64 SteamID;
|
||||||
|
public UInt64 OwnerSteamID;
|
||||||
public float Karma;
|
public float Karma;
|
||||||
public int KarmaKickCount;
|
public int KarmaKickCount;
|
||||||
public readonly List<Client> KickVoters = new List<Client>();
|
public readonly List<Client> KickVoters = new List<Client>();
|
||||||
@@ -3835,6 +3851,7 @@ namespace Barotrauma.Networking
|
|||||||
Name = c.Name;
|
Name = c.Name;
|
||||||
EndPoint = c.Connection?.EndPointString ?? "";
|
EndPoint = c.Connection?.EndPointString ?? "";
|
||||||
SteamID = c.SteamID;
|
SteamID = c.SteamID;
|
||||||
|
OwnerSteamID = c.OwnerSteamID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool MatchesClient(Client c)
|
public bool MatchesClient(Client c)
|
||||||
|
|||||||
+6
-4
@@ -184,7 +184,7 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serverSettings.BanList.IsBanned(inc.SenderConnection.RemoteEndPoint.Address, 0, out string banReason))
|
if (serverSettings.BanList.IsBanned(inc.SenderConnection.RemoteEndPoint.Address, 0, 0, out string banReason))
|
||||||
{
|
{
|
||||||
//IP banned: deny immediately
|
//IP banned: deny immediately
|
||||||
inc.SenderConnection.Deny(DisconnectReason.Banned.ToString() + "/ " + banReason);
|
inc.SenderConnection.Deny(DisconnectReason.Banned.ToString() + "/ " + banReason);
|
||||||
@@ -233,7 +233,7 @@ namespace Barotrauma.Networking
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pendingClient != null) { pendingClients.Remove(pendingClient); }
|
if (pendingClient != null) { pendingClients.Remove(pendingClient); }
|
||||||
if (serverSettings.BanList.IsBanned(conn.IPEndPoint.Address, conn.SteamID, out string banReason))
|
if (serverSettings.BanList.IsBanned(conn.IPEndPoint.Address, conn.SteamID, conn.OwnerSteamID, out string banReason))
|
||||||
{
|
{
|
||||||
Disconnect(conn, DisconnectReason.Banned.ToString() + "/ " + banReason);
|
Disconnect(conn, DisconnectReason.Banned.ToString() + "/ " + banReason);
|
||||||
return;
|
return;
|
||||||
@@ -308,7 +308,8 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
|
|
||||||
LidgrenConnection pendingConnection = pendingClient.Connection as LidgrenConnection;
|
LidgrenConnection pendingConnection = pendingClient.Connection as LidgrenConnection;
|
||||||
if (serverSettings.BanList.IsBanned(pendingConnection.NetConnection.RemoteEndPoint.Address, steamID, out string banReason))
|
string banReason;
|
||||||
|
if (serverSettings.BanList.IsBanned(pendingConnection.NetConnection.RemoteEndPoint.Address, steamID, ownerID, out banReason))
|
||||||
{
|
{
|
||||||
RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason);
|
RemovePendingClient(pendingClient, DisconnectReason.Banned, banReason);
|
||||||
return;
|
return;
|
||||||
@@ -316,6 +317,7 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (status == Steamworks.AuthResponse.OK)
|
if (status == Steamworks.AuthResponse.OK)
|
||||||
{
|
{
|
||||||
|
pendingClient.OwnerSteamID = ownerID;
|
||||||
pendingClient.InitializationStep = serverSettings.HasPassword ? ConnectionInitialization.Password : ConnectionInitialization.ContentPackageOrder;
|
pendingClient.InitializationStep = serverSettings.HasPassword ? ConnectionInitialization.Password : ConnectionInitialization.ContentPackageOrder;
|
||||||
pendingClient.UpdateTime = Timing.TotalTime;
|
pendingClient.UpdateTime = Timing.TotalTime;
|
||||||
}
|
}
|
||||||
@@ -452,7 +454,7 @@ namespace Barotrauma.Networking
|
|||||||
pendingClient.AuthSessionStarted = true;
|
pendingClient.AuthSessionStarted = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //TODO: could remove since this seems impossible
|
else
|
||||||
{
|
{
|
||||||
if (pendingClient.SteamID != steamId)
|
if (pendingClient.SteamID != steamId)
|
||||||
{
|
{
|
||||||
|
|||||||
+18
-4
@@ -49,6 +49,16 @@ namespace Barotrauma.Networking
|
|||||||
Connection.SetSteamIDIfUnknown(value ?? 0);
|
Connection.SetSteamIDIfUnknown(value ?? 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private UInt64? ownerSteamId;
|
||||||
|
public UInt64? OwnerSteamID
|
||||||
|
{
|
||||||
|
get { return ownerSteamId; }
|
||||||
|
set
|
||||||
|
{
|
||||||
|
ownerSteamId = value;
|
||||||
|
Connection.SetOwnerSteamIDIfUnknown(value ?? 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
public Int32? PasswordSalt;
|
public Int32? PasswordSalt;
|
||||||
public bool AuthSessionStarted;
|
public bool AuthSessionStarted;
|
||||||
|
|
||||||
@@ -59,6 +69,7 @@ namespace Barotrauma.Networking
|
|||||||
InitializationStep = ConnectionInitialization.SteamTicketAndVersion;
|
InitializationStep = ConnectionInitialization.SteamTicketAndVersion;
|
||||||
Retries = 0;
|
Retries = 0;
|
||||||
SteamID = null;
|
SteamID = null;
|
||||||
|
OwnerSteamID = null;
|
||||||
PasswordSalt = null;
|
PasswordSalt = null;
|
||||||
UpdateTime = Timing.TotalTime + Timing.Step * 3.0;
|
UpdateTime = Timing.TotalTime + Timing.Step * 3.0;
|
||||||
TimeOut = NetworkConnection.TimeoutThreshold;
|
TimeOut = NetworkConnection.TimeoutThreshold;
|
||||||
@@ -107,8 +118,8 @@ namespace Barotrauma.Networking
|
|||||||
RemovePendingClient(pendingClient, DisconnectReason.InvalidVersion,
|
RemovePendingClient(pendingClient, DisconnectReason.InvalidVersion,
|
||||||
$"DisconnectMessage.InvalidVersion~[version]={GameMain.Version}~[clientversion]={version}");
|
$"DisconnectMessage.InvalidVersion~[version]={GameMain.Version}~[clientversion]={version}");
|
||||||
|
|
||||||
GameServer.Log(name + " (" + pendingClient.SteamID.ToString() + ") couldn't join the server (incompatible game version)", ServerLog.MessageType.Error);
|
GameServer.Log($"{name} ({steamId}) couldn't join the server (incompatible game version)", ServerLog.MessageType.Error);
|
||||||
DebugConsole.NewMessage(name + " (" + pendingClient.SteamID.ToString() + ") couldn't join the server (incompatible game version)", Microsoft.Xna.Framework.Color.Red);
|
DebugConsole.NewMessage($"{name} ({steamId}) couldn't join the server (incompatible game version)", Microsoft.Xna.Framework.Color.Red);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +130,7 @@ namespace Barotrauma.Networking
|
|||||||
if (nameTaken != null)
|
if (nameTaken != null)
|
||||||
{
|
{
|
||||||
RemovePendingClient(pendingClient, DisconnectReason.NameTaken, "");
|
RemovePendingClient(pendingClient, DisconnectReason.NameTaken, "");
|
||||||
GameServer.Log(name + " (" + pendingClient.SteamID.ToString() + ") couldn't join the server (name too similar to the name of the client \"" + nameTaken.Name + "\").", ServerLog.MessageType.Error);
|
GameServer.Log($"{name} ({steamId}) couldn't join the server (name too similar to the name of the client \"" + nameTaken.Name + "\").", ServerLog.MessageType.Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,6 +183,7 @@ namespace Barotrauma.Networking
|
|||||||
else if (pendingClient.Connection is SteamP2PConnection s)
|
else if (pendingClient.Connection is SteamP2PConnection s)
|
||||||
{
|
{
|
||||||
serverSettings.BanList.BanPlayer(pendingClient.Name, s.SteamID, banReason, duration);
|
serverSettings.BanList.BanPlayer(pendingClient.Name, s.SteamID, banReason, duration);
|
||||||
|
serverSettings.BanList.BanPlayer(pendingClient.Name, s.OwnerSteamID, banReason, duration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +195,8 @@ namespace Barotrauma.Networking
|
|||||||
}
|
}
|
||||||
else if (pendingClient.Connection is SteamP2PConnection s)
|
else if (pendingClient.Connection is SteamP2PConnection s)
|
||||||
{
|
{
|
||||||
return serverSettings.BanList.IsBanned(s.SteamID, out banReason);
|
return serverSettings.BanList.IsBanned(s.SteamID, out banReason) ||
|
||||||
|
serverSettings.BanList.IsBanned(s.OwnerSteamID, out banReason);
|
||||||
}
|
}
|
||||||
banReason = null;
|
banReason = null;
|
||||||
return false;
|
return false;
|
||||||
@@ -273,6 +286,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
Steam.SteamManager.StopAuthSession(pendingClient.SteamID.Value);
|
Steam.SteamManager.StopAuthSession(pendingClient.SteamID.Value);
|
||||||
pendingClient.SteamID = null;
|
pendingClient.SteamID = null;
|
||||||
|
pendingClient.OwnerSteamID = null;
|
||||||
pendingClient.AuthSessionStarted = false;
|
pendingClient.AuthSessionStarted = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-1
@@ -123,6 +123,7 @@ namespace Barotrauma.Networking
|
|||||||
if (!started) { return; }
|
if (!started) { return; }
|
||||||
|
|
||||||
UInt64 senderSteamId = inc.ReadUInt64();
|
UInt64 senderSteamId = inc.ReadUInt64();
|
||||||
|
UInt64 ownerSteamId = inc.ReadUInt64();
|
||||||
|
|
||||||
byte incByte = inc.ReadByte();
|
byte incByte = inc.ReadByte();
|
||||||
bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
|
bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
|
||||||
@@ -145,7 +146,9 @@ namespace Barotrauma.Networking
|
|||||||
pendingClient?.Heartbeat();
|
pendingClient?.Heartbeat();
|
||||||
connectedClient?.Heartbeat();
|
connectedClient?.Heartbeat();
|
||||||
|
|
||||||
if (serverSettings.BanList.IsBanned(senderSteamId, out string banReason))
|
string banReason;
|
||||||
|
if (serverSettings.BanList.IsBanned(senderSteamId, out banReason) ||
|
||||||
|
serverSettings.BanList.IsBanned(ownerSteamId, out banReason))
|
||||||
{
|
{
|
||||||
if (pendingClient != null)
|
if (pendingClient != null)
|
||||||
{
|
{
|
||||||
@@ -181,6 +184,10 @@ namespace Barotrauma.Networking
|
|||||||
|
|
||||||
if (pendingClient != null)
|
if (pendingClient != null)
|
||||||
{
|
{
|
||||||
|
if (ownerSteamId != 0)
|
||||||
|
{
|
||||||
|
pendingClient.Connection.SetOwnerSteamIDIfUnknown(ownerSteamId);
|
||||||
|
}
|
||||||
ReadConnectionInitializationStep(pendingClient, new ReadOnlyMessage(inc.Buffer, false, inc.BytePosition, inc.LengthBytes - inc.BytePosition, null));
|
ReadConnectionInitializationStep(pendingClient, new ReadOnlyMessage(inc.Buffer, false, inc.BytePosition, inc.LengthBytes - inc.BytePosition, null));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -223,6 +230,7 @@ namespace Barotrauma.Networking
|
|||||||
{
|
{
|
||||||
Language = GameMain.Config.Language
|
Language = GameMain.Config.Language
|
||||||
};
|
};
|
||||||
|
OwnerConnection.SetOwnerSteamIDIfUnknown(OwnerSteamID);
|
||||||
|
|
||||||
OnInitializationComplete?.Invoke(OwnerConnection);
|
OnInitializationComplete?.Invoke(OwnerConnection);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,6 +159,8 @@ namespace Barotrauma.Networking
|
|||||||
AutoRestart = autoRestart;
|
AutoRestart = autoRestart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RadiationEnabled = incMsg.ReadBoolean();
|
||||||
|
|
||||||
changed |= true;
|
changed |= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ namespace Barotrauma
|
|||||||
private SubmarineInfo selectedSub;
|
private SubmarineInfo selectedSub;
|
||||||
private SubmarineInfo selectedShuttle;
|
private SubmarineInfo selectedShuttle;
|
||||||
|
|
||||||
|
public bool RadiationEnabled = true;
|
||||||
|
|
||||||
public SubmarineInfo SelectedSub
|
public SubmarineInfo SelectedSub
|
||||||
{
|
{
|
||||||
get { return selectedSub; }
|
get { return selectedSub; }
|
||||||
|
|||||||
@@ -1,147 +1,147 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<RootNamespace>Barotrauma</RootNamespace>
|
<RootNamespace>Barotrauma</RootNamespace>
|
||||||
<Authors>FakeFish, Undertow Games</Authors>
|
<Authors>FakeFish, Undertow Games</Authors>
|
||||||
<Product>Barotrauma Dedicated Server</Product>
|
<Product>Barotrauma Dedicated Server</Product>
|
||||||
<Version>0.1300.0.0</Version>
|
<Version>0.1300.0.1</Version>
|
||||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||||
<Platforms>AnyCPU;x64</Platforms>
|
<Platforms>AnyCPU;x64</Platforms>
|
||||||
<AssemblyName>DedicatedServer</AssemblyName>
|
<AssemblyName>DedicatedServer</AssemblyName>
|
||||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||||
<Configurations>Debug;Release;Unstable</Configurations>
|
<Configurations>Debug;Release;Unstable</Configurations>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
<DefineConstants>DEBUG;TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
<DefineConstants>DEBUG;TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<DefineConstants>TRACE;DEBUG;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;DEBUG;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||||
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<DefineConstants>TRACE;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||||
<DefineConstants>TRACE;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
<DefineConstants>TRACE;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||||
<PlatformTarget>x64</PlatformTarget>
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||||
<DebugType>full</DebugType>
|
<DebugType>full</DebugType>
|
||||||
<DebugSymbols>true</DebugSymbols>
|
<DebugSymbols>true</DebugSymbols>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||||
<Compile Remove="..\BarotraumaShared\SharedSource\Networking\Primitives\Message\WrapperMsg.cs" />
|
<Compile Remove="..\BarotraumaShared\SharedSource\Networking\Primitives\Message\WrapperMsg.cs" />
|
||||||
<Content Remove="DedicatedServer.exe" />
|
<Content Remove="DedicatedServer.exe" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||||
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Win64.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Win64.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
<ItemGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Win64.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Facepunch.Steamworks\Facepunch.Steamworks.Win64.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Farseer Physics Engine 3.5\Farseer.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\GameAnalytics\GA_SDK_NETSTANDARD\GA_SDK_NETSTANDARD.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Hyper.ComponentModel\Hyper.ComponentModel.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
<ProjectReference Include="..\..\Libraries\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- write the hash to the temp file.-->
|
<!-- write the hash to the temp file.-->
|
||||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||||
</Exec>
|
</Exec>
|
||||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD --symbolic-full-name --abbrev-ref=strict > $(BranchFile)" ContinueOnError="true" />
|
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD --symbolic-full-name --abbrev-ref=strict > $(BranchFile)" ContinueOnError="true" />
|
||||||
|
|
||||||
<Exec Command="echo GIT_UNAVAILABLE > $(VerFile)" Condition="'%(exitcodes.identity)'>0" />
|
<Exec Command="echo GIT_UNAVAILABLE > $(VerFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||||
<Exec Command="echo GIT_UNAVAILABLE > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
<Exec Command="echo GIT_UNAVAILABLE > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||||
|
|
||||||
<!-- read the version into the GitVersion itemGroup-->
|
<!-- read the version into the GitVersion itemGroup-->
|
||||||
<ReadLinesFromFile File="$(VerFile)">
|
<ReadLinesFromFile File="$(VerFile)">
|
||||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||||
</ReadLinesFromFile>
|
</ReadLinesFromFile>
|
||||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<BuildHash>@(GitVersion)</BuildHash>
|
<BuildHash>@(GitVersion)</BuildHash>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- read the branch into the GitBranch itemGroup-->
|
<!-- read the branch into the GitBranch itemGroup-->
|
||||||
<ReadLinesFromFile File="$(BranchFile)">
|
<ReadLinesFromFile File="$(BranchFile)">
|
||||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||||
</ReadLinesFromFile>
|
</ReadLinesFromFile>
|
||||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>GitRevision</_Parameter1>
|
<_Parameter1>GitRevision</_Parameter1>
|
||||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>GitBranch</_Parameter1>
|
<_Parameter1>GitBranch</_Parameter1>
|
||||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
<AssemblyAttributes Include="AssemblyMetadata">
|
<AssemblyAttributes Include="AssemblyMetadata">
|
||||||
<_Parameter1>ProjectDir</_Parameter1>
|
<_Parameter1>ProjectDir</_Parameter1>
|
||||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||||
</AssemblyAttributes>
|
</AssemblyAttributes>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -62,6 +62,7 @@
|
|||||||
<Character file="Content/Characters/Balloon/Balloon.xml" />
|
<Character file="Content/Characters/Balloon/Balloon.xml" />
|
||||||
<Character file="Content/Characters/Carrier/Carrier.xml" />
|
<Character file="Content/Characters/Carrier/Carrier.xml" />
|
||||||
<Character file="Content/Characters/Charybdis/Charybdis.xml" />
|
<Character file="Content/Characters/Charybdis/Charybdis.xml" />
|
||||||
|
<Character file="Content/Characters/Charybdisold/Charybdisold.xml" />
|
||||||
<Character file="Content/Characters/Coelanth/Coelanth.xml" />
|
<Character file="Content/Characters/Coelanth/Coelanth.xml" />
|
||||||
<Character file="Content/Characters/Crawler/Crawler.xml" />
|
<Character file="Content/Characters/Crawler/Crawler.xml" />
|
||||||
<Character file="Content/Characters/Crawlerhusk/Crawlerhusk.xml" />
|
<Character file="Content/Characters/Crawlerhusk/Crawlerhusk.xml" />
|
||||||
@@ -248,4 +249,6 @@
|
|||||||
<OutpostModule file="Content/Map/Outposts/Hall4wayModule_01_Abandoned.sub" />
|
<OutpostModule file="Content/Map/Outposts/Hall4wayModule_01_Abandoned.sub" />
|
||||||
<BeaconStation file="Content/Map/BeaconStations/BeaconStation1.sub" />
|
<BeaconStation file="Content/Map/BeaconStations/BeaconStation1.sub" />
|
||||||
<OutpostModule file="Content/Map/Outposts/MineModule_04.sub" />
|
<OutpostModule file="Content/Map/Outposts/MineModule_04.sub" />
|
||||||
|
<OutpostModule file="Content/Map/Outposts/HallModuleHorizontal_Abandoned.sub" />
|
||||||
|
<OutpostModule file="Content/Map/Outposts/HallModuleVertical_Abandoned.sub" />
|
||||||
</contentpackage>
|
</contentpackage>
|
||||||
@@ -232,8 +232,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public bool IsWithinSector(Vector2 worldPosition)
|
public bool IsWithinSector(Vector2 worldPosition)
|
||||||
{
|
{
|
||||||
if (sectorRad >= MathHelper.TwoPi) return true;
|
if (sectorRad >= MathHelper.TwoPi) { return true; }
|
||||||
|
|
||||||
Vector2 diff = worldPosition - WorldPosition;
|
Vector2 diff = worldPosition - WorldPosition;
|
||||||
return MathUtils.GetShortestAngle(MathUtils.VectorToAngle(diff), MathUtils.VectorToAngle(sectorDir)) <= sectorRad * 0.5f;
|
return MathUtils.GetShortestAngle(MathUtils.VectorToAngle(diff), MathUtils.VectorToAngle(sectorDir)) <= sectorRad * 0.5f;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ namespace Barotrauma
|
|||||||
private CharacterParams.TargetParams GetTargetParams(AITarget aiTarget) => GetTargetParams(GetTargetingTag(aiTarget));
|
private CharacterParams.TargetParams GetTargetParams(AITarget aiTarget) => GetTargetParams(GetTargetingTag(aiTarget));
|
||||||
private string GetTargetingTag(AITarget aiTarget)
|
private string GetTargetingTag(AITarget aiTarget)
|
||||||
{
|
{
|
||||||
if (aiTarget.Entity == null) { return null; }
|
if (aiTarget?.Entity == null) { return null; }
|
||||||
string targetingTag = null;
|
string targetingTag = null;
|
||||||
if (aiTarget.Entity is Character targetCharacter)
|
if (aiTarget.Entity is Character targetCharacter)
|
||||||
{
|
{
|
||||||
@@ -377,6 +377,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (DisableEnemyAI) { return; }
|
if (DisableEnemyAI) { return; }
|
||||||
base.Update(deltaTime);
|
base.Update(deltaTime);
|
||||||
|
UpdateTriggers(deltaTime);
|
||||||
|
|
||||||
bool ignorePlatforms = Character.AnimController.TargetMovement.Y < -0.5f && (-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
|
bool ignorePlatforms = Character.AnimController.TargetMovement.Y < -0.5f && (-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
|
||||||
if (steeringManager == insideSteering)
|
if (steeringManager == insideSteering)
|
||||||
@@ -462,7 +463,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
updateTargetsTimer -= deltaTime;
|
updateTargetsTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
else if (avoidTimer <= 0)
|
else if (avoidTimer <= 0 || activeTriggers.Any() && returnTimer <= 0)
|
||||||
{
|
{
|
||||||
CharacterParams.TargetParams targetingParams = null;
|
CharacterParams.TargetParams targetingParams = null;
|
||||||
UpdateTargets(Character, out targetingParams);
|
UpdateTargets(Character, out targetingParams);
|
||||||
@@ -1448,8 +1449,12 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
case AttackPattern.Circle:
|
case AttackPattern.Circle:
|
||||||
if (IsCoolDownRunning) { break; }
|
if (IsCoolDownRunning) { break; }
|
||||||
if (IsAttackRunning) { break; }
|
if (IsAttackRunning && CirclePhase != CirclePhase.Strike) { break; }
|
||||||
if (selectedTargetingParams == null) { break; }
|
if (selectedTargetingParams == null) { break; }
|
||||||
|
var targetSub = SelectedAiTarget.Entity?.Submarine;
|
||||||
|
if (targetSub == null) { break; }
|
||||||
|
float subSize = Math.Max(targetSub.Borders.Width, targetSub.Borders.Height) / 2;
|
||||||
|
float sqrDistToSub = Vector2.DistanceSquared(WorldPosition, targetSub.WorldPosition);
|
||||||
switch (CirclePhase)
|
switch (CirclePhase)
|
||||||
{
|
{
|
||||||
case CirclePhase.Start:
|
case CirclePhase.Start:
|
||||||
@@ -1471,22 +1476,31 @@ namespace Barotrauma
|
|||||||
circleOffset = Rand.Vector(MathHelper.Lerp(selectedTargetingParams.CircleMaxRandomOffset, 0, currentAttackIntensity * Rand.Range(0.9f, 1.1f)));
|
circleOffset = Rand.Vector(MathHelper.Lerp(selectedTargetingParams.CircleMaxRandomOffset, 0, currentAttackIntensity * Rand.Range(0.9f, 1.1f)));
|
||||||
canAttack = false;
|
canAttack = false;
|
||||||
aggressionIntensity = Math.Clamp(aggressionIntensity, AIParams.StartAggression, AIParams.MaxAggression);
|
aggressionIntensity = Math.Clamp(aggressionIntensity, AIParams.StartAggression, AIParams.MaxAggression);
|
||||||
CirclePhase = Vector2.DistanceSquared(WorldPosition, attackWorldPos) > MathUtils.Pow2(circleFallbackDistance) ? CirclePhase.CloseIn : CirclePhase.FallBack;
|
if (targetSub.Borders.Width < 1000)
|
||||||
|
{
|
||||||
|
breakCircling = true;
|
||||||
|
CirclePhase = CirclePhase.CloseIn;
|
||||||
|
}
|
||||||
|
else if (sqrDistToSub > MathUtils.Pow2(subSize + selectedTargetingParams.CircleStartDistance))
|
||||||
|
{
|
||||||
|
CirclePhase = CirclePhase.CloseIn;
|
||||||
|
}
|
||||||
|
else if (sqrDistToSub < MathUtils.Pow2(subSize + circleFallbackDistance))
|
||||||
|
{
|
||||||
|
CirclePhase = CirclePhase.FallBack;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CirclePhase = CirclePhase.Advance;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CirclePhase.CloseIn:
|
case CirclePhase.CloseIn:
|
||||||
var sub = SelectedAiTarget.Entity?.Submarine;
|
if (AttackingLimb != null && distance > 0 && distance < AttackingLimb.attack.Range * GetStrikeDistanceMultiplier(targetSub.Velocity))
|
||||||
if (sub == null)
|
|
||||||
{
|
|
||||||
CirclePhase = CirclePhase.Start;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (AttackingLimb != null && distance > 0 && distance < AttackingLimb.attack.Range * GetStrikeDistanceMultiplier(sub.Velocity))
|
|
||||||
{
|
{
|
||||||
strikeTimer = AttackingLimb.attack.CoolDown;
|
strikeTimer = AttackingLimb.attack.CoolDown;
|
||||||
CirclePhase = CirclePhase.Strike;
|
CirclePhase = CirclePhase.Strike;
|
||||||
}
|
}
|
||||||
else if (!breakCircling && Vector2.DistanceSquared(WorldPosition, attackWorldPos) <= MathUtils.Pow2(circleFallbackDistance - 1000) &&
|
else if (!breakCircling && sqrDistToSub <= MathUtils.Pow2(subSize + selectedTargetingParams.CircleStartDistance / 2) && targetSub.Velocity.LengthSquared() <= MathUtils.Pow2(GetTargetMaxSpeed()))
|
||||||
sub.Velocity.LengthSquared() <= MathUtils.Pow2(GetTargetMaxSpeed()))
|
|
||||||
{
|
{
|
||||||
CirclePhase = CirclePhase.Advance;
|
CirclePhase = CirclePhase.Advance;
|
||||||
}
|
}
|
||||||
@@ -1494,23 +1508,17 @@ namespace Barotrauma
|
|||||||
break;
|
break;
|
||||||
case CirclePhase.FallBack:
|
case CirclePhase.FallBack:
|
||||||
bool isBlocked = !UpdateFallBack(attackWorldPos, deltaTime, followThrough: false, checkBlocking: true);
|
bool isBlocked = !UpdateFallBack(attackWorldPos, deltaTime, followThrough: false, checkBlocking: true);
|
||||||
if (isBlocked || Vector2.DistanceSquared(WorldPosition, attackWorldPos) > MathUtils.Pow2(circleFallbackDistance))
|
if (isBlocked || sqrDistToSub > MathUtils.Pow2(subSize + circleFallbackDistance))
|
||||||
{
|
{
|
||||||
CirclePhase = CirclePhase.Advance;
|
CirclePhase = CirclePhase.Advance;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case CirclePhase.Advance:
|
case CirclePhase.Advance:
|
||||||
var targetSub = SelectedAiTarget.Entity?.Submarine;
|
|
||||||
if (targetSub == null)
|
|
||||||
{
|
|
||||||
CirclePhase = CirclePhase.Start;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Vector2 subSpeed = targetSub.Velocity;
|
Vector2 subSpeed = targetSub.Velocity;
|
||||||
float requiredDistMultiplier = 1;
|
float requiredDistMultiplier = 1;
|
||||||
// If the target sub is moving fast, just steer towards the target until close enough to strike
|
// If the target sub is moving fast, just steer towards the target until close enough to strike
|
||||||
if (breakCircling || subSpeed.LengthSquared() > MathUtils.Pow2(GetTargetMaxSpeed()) || distance > selectedTargetingParams.CircleStartDistance + 1000)
|
if (breakCircling || subSpeed.LengthSquared() > MathUtils.Pow2(GetTargetMaxSpeed()) || sqrDistToSub > MathUtils.Pow2(subSize + selectedTargetingParams.CircleStartDistance * 1.2f))
|
||||||
{
|
{
|
||||||
CirclePhase = CirclePhase.CloseIn;
|
CirclePhase = CirclePhase.CloseIn;
|
||||||
}
|
}
|
||||||
@@ -1532,7 +1540,7 @@ namespace Barotrauma
|
|||||||
// When the offset position is outside of the sub it happens that the creature sometimes reaches the target point,
|
// When the offset position is outside of the sub it happens that the creature sometimes reaches the target point,
|
||||||
// which makes it continue circling around the point (as supposed)
|
// which makes it continue circling around the point (as supposed)
|
||||||
// But when there is some offset and the offset is too near, this is not what we want.
|
// But when there is some offset and the offset is too near, this is not what we want.
|
||||||
if (targetSub.Borders.ContainsWorld(attackWorldPos + ConvertUnits.ToDisplayUnits(circleOffset)))
|
if (AttackingLimb != null && sqrDistToSub < MathUtils.Pow2(subSize + circleFallbackDistance))
|
||||||
{
|
{
|
||||||
CirclePhase = CirclePhase.Strike;
|
CirclePhase = CirclePhase.Strike;
|
||||||
strikeTimer = AttackingLimb.attack.CoolDown;
|
strikeTimer = AttackingLimb.attack.CoolDown;
|
||||||
@@ -1646,15 +1654,15 @@ namespace Barotrauma
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance, attackTargetLimb))
|
if (!UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance, attackTargetLimb))
|
||||||
{
|
|
||||||
CirclePhase = CirclePhase.Start;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
IgnoreTarget(SelectedAiTarget);
|
IgnoreTarget(SelectedAiTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (IsAttackRunning)
|
||||||
|
{
|
||||||
|
AttackingLimb.attack.ResetAttackTimer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly List<Limb> attackLimbs = new List<Limb>();
|
private readonly List<Limb> attackLimbs = new List<Limb>();
|
||||||
@@ -2060,6 +2068,7 @@ namespace Barotrauma
|
|||||||
targetValue = 0;
|
targetValue = 0;
|
||||||
selectedTargetMemory = null;
|
selectedTargetMemory = null;
|
||||||
targetingParams = null;
|
targetingParams = null;
|
||||||
|
bool isAnyTargetClose = false;
|
||||||
|
|
||||||
foreach (AITarget aiTarget in AITarget.List)
|
foreach (AITarget aiTarget in AITarget.List)
|
||||||
{
|
{
|
||||||
@@ -2163,6 +2172,14 @@ namespace Barotrauma
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (door == null)
|
||||||
|
{
|
||||||
|
// Ignore items inside ruins, unless we are in the same hull. We can't target the ruin walls.
|
||||||
|
if (item.Submarine == null && item.CurrentHull != Character.CurrentHull)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
foreach (var prio in AIParams.Targets)
|
foreach (var prio in AIParams.Targets)
|
||||||
{
|
{
|
||||||
if (item.HasTag(prio.Tag))
|
if (item.HasTag(prio.Tag))
|
||||||
@@ -2379,18 +2396,16 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!aiTarget.IsWithinSector(WorldPosition)) { continue; }
|
||||||
Vector2 toTarget = aiTarget.WorldPosition - character.WorldPosition;
|
Vector2 toTarget = aiTarget.WorldPosition - character.WorldPosition;
|
||||||
float dist = toTarget.Length();
|
float dist = toTarget.Length();
|
||||||
|
float nonModifiedDist = dist;
|
||||||
//if the target has been within range earlier, the character will notice it more easily
|
//if the target has been within range earlier, the character will notice it more easily
|
||||||
if (targetMemories.ContainsKey(aiTarget))
|
if (targetMemories.ContainsKey(aiTarget))
|
||||||
{
|
{
|
||||||
dist *= 0.9f;
|
dist *= 0.9f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!CanPerceive(aiTarget, dist)) { continue; }
|
if (!CanPerceive(aiTarget, dist)) { continue; }
|
||||||
if (!aiTarget.IsWithinSector(WorldPosition)) { continue; }
|
|
||||||
|
|
||||||
//if the target is very close, the distance doesn't make much difference
|
//if the target is very close, the distance doesn't make much difference
|
||||||
// -> just ignore the distance and attack whatever has the highest priority
|
// -> just ignore the distance and attack whatever has the highest priority
|
||||||
@@ -2405,14 +2420,26 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (targetParams.AttackPattern == AttackPattern.Circle)
|
if (targetParams.AttackPattern == AttackPattern.Circle)
|
||||||
{
|
{
|
||||||
if (Character.Submarine == null && aiTarget.Entity?.Submarine != null)
|
if (Character.Submarine == null && aiTarget.Entity?.Submarine != null && !isAnyTargetClose)
|
||||||
{
|
{
|
||||||
if (Submarine.MainSubs.Contains(aiTarget.Entity.Submarine))
|
if (Submarine.MainSubs.Contains(aiTarget.Entity.Submarine))
|
||||||
{
|
{
|
||||||
// Prioritize targets that are near the horizontal center of the sub
|
// Prioritize targets that are near the horizontal center of the sub, but only when none of the targets is reachable.
|
||||||
float horizontalDistanceToSubCenter = Math.Abs(aiTarget.WorldPosition.X - aiTarget.Entity.Submarine.WorldPosition.X);
|
float horizontalDistanceToSubCenter = Math.Abs(aiTarget.WorldPosition.X - aiTarget.Entity.Submarine.WorldPosition.X);
|
||||||
dist *= MathHelper.Lerp(1f, 5f, MathUtils.InverseLerp(0, 10000, horizontalDistanceToSubCenter));
|
dist *= MathHelper.Lerp(1f, 5f, MathUtils.InverseLerp(0, 10000, horizontalDistanceToSubCenter));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dist *= 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Don't target characters that are outside of the allowed zone, unless attacking or escaping
|
||||||
|
if (targetParams.State != AIState.Attack && targetParams.State != AIState.Escape && targetParams.State != AIState.Avoid)
|
||||||
|
{
|
||||||
|
if (!IsPositionInsideAllowedZone(aiTarget.WorldPosition, out _))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2486,11 +2513,26 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (targetCharacter.Submarine == null && Character.Submarine == null)
|
||||||
|
{
|
||||||
|
// Ignore the target when it's far enough and blocked by the level geometry, because the steering avoidance probably can't get us to the target.
|
||||||
|
if (dist > Math.Clamp(ConvertUnits.ToDisplayUnits(colliderLength) * 10, 1000, 5000))
|
||||||
|
{
|
||||||
|
if (Submarine.PickBodies(SimPosition, targetCharacter.SimPosition, collisionCategory: Physics.CollisionLevel).Any())
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
newTarget = aiTarget;
|
newTarget = aiTarget;
|
||||||
selectedTargetMemory = targetMemory;
|
selectedTargetMemory = targetMemory;
|
||||||
targetValue = valueModifier;
|
targetValue = valueModifier;
|
||||||
targetingParams = targetParams;
|
targetingParams = targetParams;
|
||||||
|
if (!isAnyTargetClose)
|
||||||
|
{
|
||||||
|
isAnyTargetClose = ConvertUnits.ToDisplayUnits(colliderLength) > nonModifiedDist;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2619,7 +2661,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!Character.AnimController.CanEnterSubmarine && wallTarget == null)
|
if (!Character.AnimController.CanEnterSubmarine && wallTarget == null && selectedTargetingParams?.AttackPattern == AttackPattern.Straight)
|
||||||
{
|
{
|
||||||
if (closestBody.UserData is Structure w && w.Submarine != null && w.Submarine == SelectedAiTarget.Entity?.Submarine ||
|
if (closestBody.UserData is Structure w && w.Submarine != null && w.Submarine == SelectedAiTarget.Entity?.Submarine ||
|
||||||
closestBody.UserData is Item i && i.Submarine != null && i.Submarine == SelectedAiTarget.Entity?.Submarine)
|
closestBody.UserData is Item i && i.Submarine != null && i.Submarine == SelectedAiTarget.Entity?.Submarine)
|
||||||
@@ -2753,6 +2795,44 @@ namespace Barotrauma
|
|||||||
private readonly float stateResetCooldown = 10;
|
private readonly float stateResetCooldown = 10;
|
||||||
private float stateResetTimer;
|
private float stateResetTimer;
|
||||||
private bool isStateChanged;
|
private bool isStateChanged;
|
||||||
|
private readonly Dictionary<AITrigger, CharacterParams.TargetParams> activeTriggers = new Dictionary<AITrigger, CharacterParams.TargetParams>();
|
||||||
|
private readonly HashSet<AITrigger> inactiveTriggers = new HashSet<AITrigger>();
|
||||||
|
|
||||||
|
public void LaunchTrigger(AITrigger trigger)
|
||||||
|
{
|
||||||
|
if (trigger.IsTriggered) { return; }
|
||||||
|
if (activeTriggers.ContainsKey(trigger)) { return; }
|
||||||
|
if (activeTriggers.ContainsValue(selectedTargetingParams))
|
||||||
|
{
|
||||||
|
if (!trigger.AllowToOverride) { return; }
|
||||||
|
var existingTrigger = activeTriggers.FirstOrDefault(kvp => kvp.Value == selectedTargetingParams && kvp.Key.AllowToBeOverridden);
|
||||||
|
if (existingTrigger.Key == null) { return; }
|
||||||
|
activeTriggers.Remove(existingTrigger.Key);
|
||||||
|
}
|
||||||
|
trigger.Launch();
|
||||||
|
activeTriggers.Add(trigger, selectedTargetingParams);
|
||||||
|
ChangeParams(selectedTargetingParams, trigger.State);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTriggers(float deltaTime)
|
||||||
|
{
|
||||||
|
foreach (var triggerObject in activeTriggers)
|
||||||
|
{
|
||||||
|
AITrigger trigger = triggerObject.Key;
|
||||||
|
trigger.UpdateTimer(deltaTime);
|
||||||
|
if (!trigger.IsActive)
|
||||||
|
{
|
||||||
|
trigger.Reset();
|
||||||
|
ResetParams(triggerObject.Value);
|
||||||
|
inactiveTriggers.Add(trigger);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (AITrigger trigger in inactiveTriggers)
|
||||||
|
{
|
||||||
|
activeTriggers.Remove(trigger);
|
||||||
|
}
|
||||||
|
inactiveTriggers.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Resets the target's state to the original value defined in the xml.
|
/// Resets the target's state to the original value defined in the xml.
|
||||||
@@ -2768,11 +2848,7 @@ namespace Barotrauma
|
|||||||
tempParams.Values.ForEach(t => AIParams.RemoveTarget(t));
|
tempParams.Values.ForEach(t => AIParams.RemoveTarget(t));
|
||||||
tempParams.Remove(tag);
|
tempParams.Remove(tag);
|
||||||
}
|
}
|
||||||
targetParams.Reset();
|
ResetParams(targetParams);
|
||||||
ResetAITarget();
|
|
||||||
// Enforce the idle state so that we don't keep following the target if there's one
|
|
||||||
State = AIState.Idle;
|
|
||||||
PreviousState = AIState.Idle;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2784,6 +2860,27 @@ namespace Barotrauma
|
|||||||
private readonly Dictionary<string, CharacterParams.TargetParams> modifiedParams = new Dictionary<string, CharacterParams.TargetParams>();
|
private readonly Dictionary<string, CharacterParams.TargetParams> modifiedParams = new Dictionary<string, CharacterParams.TargetParams>();
|
||||||
private readonly Dictionary<string, CharacterParams.TargetParams> tempParams = new Dictionary<string, CharacterParams.TargetParams>();
|
private readonly Dictionary<string, CharacterParams.TargetParams> tempParams = new Dictionary<string, CharacterParams.TargetParams>();
|
||||||
|
|
||||||
|
private void ChangeParams(CharacterParams.TargetParams targetParams, AIState state, float? priority = null)
|
||||||
|
{
|
||||||
|
if (targetParams == null) { return; }
|
||||||
|
if (priority.HasValue)
|
||||||
|
{
|
||||||
|
targetParams.Priority = priority.Value;
|
||||||
|
}
|
||||||
|
targetParams.State = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ResetParams(CharacterParams.TargetParams targetParams)
|
||||||
|
{
|
||||||
|
targetParams?.Reset();
|
||||||
|
if (selectedTargetingParams == targetParams || State == AIState.Idle)
|
||||||
|
{
|
||||||
|
ResetAITarget();
|
||||||
|
State = AIState.Idle;
|
||||||
|
PreviousState = AIState.Idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ChangeParams(string tag, AIState state, float? priority = null, bool onlyExisting = false)
|
private void ChangeParams(string tag, AIState state, float? priority = null, bool onlyExisting = false)
|
||||||
{
|
{
|
||||||
if (!AIParams.TryGetTarget(tag, out CharacterParams.TargetParams targetParams))
|
if (!AIParams.TryGetTarget(tag, out CharacterParams.TargetParams targetParams))
|
||||||
@@ -2938,45 +3035,56 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsPositionInsideAllowedZone(Vector2 pos, out Vector2 targetDir)
|
||||||
|
{
|
||||||
|
targetDir = Vector2.Zero;
|
||||||
|
if (AIParams.AvoidAbyss)
|
||||||
|
{
|
||||||
|
if (pos.Y < Level.Loaded.AbyssStart)
|
||||||
|
{
|
||||||
|
// Too far down
|
||||||
|
targetDir = Vector2.UnitY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (AIParams.StayInAbyss)
|
||||||
|
{
|
||||||
|
if (pos.Y > Level.Loaded.AbyssStart)
|
||||||
|
{
|
||||||
|
// Too far up
|
||||||
|
targetDir = -Vector2.UnitY;
|
||||||
|
}
|
||||||
|
else if (pos.Y < Level.Loaded.AbyssEnd)
|
||||||
|
{
|
||||||
|
// Too far down
|
||||||
|
targetDir = Vector2.UnitY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
float margin = 30000;
|
||||||
|
if (pos.X < -margin)
|
||||||
|
{
|
||||||
|
// Too far left
|
||||||
|
targetDir = Vector2.UnitX;
|
||||||
|
}
|
||||||
|
else if (pos.X > Level.Loaded.Size.X + margin)
|
||||||
|
{
|
||||||
|
// Too far right
|
||||||
|
targetDir = -Vector2.UnitX;
|
||||||
|
}
|
||||||
|
return targetDir == Vector2.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
private Vector2 returnDir;
|
private Vector2 returnDir;
|
||||||
private float returnTimer;
|
private float returnTimer;
|
||||||
private void SteerInsideLevel(float deltaTime)
|
private void SteerInsideLevel(float deltaTime)
|
||||||
{
|
{
|
||||||
if (State == AIState.Attack) { return; }
|
|
||||||
if (SteeringManager is IndoorsSteeringManager) { return; }
|
if (SteeringManager is IndoorsSteeringManager) { return; }
|
||||||
if (Level.Loaded == null) { return; }
|
if (Level.Loaded == null) { return; }
|
||||||
Point levelSize = Level.Loaded.Size;
|
if (State == AIState.Attack && returnTimer <= 0) { return; }
|
||||||
float returnTime = 10;
|
float returnTime = 5;
|
||||||
if (AIParams.AvoidAbyss)
|
if (!IsPositionInsideAllowedZone(WorldPosition, out Vector2 targetDir))
|
||||||
{
|
{
|
||||||
if (WorldPosition.Y < Level.Loaded.AbyssStart)
|
returnDir = targetDir;
|
||||||
{
|
|
||||||
// Too far down
|
|
||||||
returnTimer = returnTime * Rand.Range(0.75f, 1.25f);
|
|
||||||
returnDir = Vector2.UnitY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (AIParams.StayInAbyss)
|
|
||||||
{
|
|
||||||
if (WorldPosition.Y > Level.Loaded.AbyssStart)
|
|
||||||
{
|
|
||||||
// Too far up
|
|
||||||
returnTimer = returnTime * Rand.Range(0.75f, 1.25f);
|
|
||||||
returnDir = -Vector2.UnitY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
float margin = AIParams.AvoidAbyss ? 0 : 30000;
|
|
||||||
if (WorldPosition.X < margin)
|
|
||||||
{
|
|
||||||
// Too far left
|
|
||||||
returnTimer = returnTime * Rand.Range(0.75f, 1.25f);
|
returnTimer = returnTime * Rand.Range(0.75f, 1.25f);
|
||||||
returnDir = Vector2.UnitX;
|
|
||||||
}
|
|
||||||
if (WorldPosition.X > levelSize.X + margin)
|
|
||||||
{
|
|
||||||
// Too far right
|
|
||||||
returnTimer = returnTime * Rand.Range(0.75f, 1.25f);
|
|
||||||
returnDir = -Vector2.UnitX;
|
|
||||||
}
|
}
|
||||||
if (returnTimer > 0)
|
if (returnTimer > 0)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private readonly AIObjectiveManager objectiveManager;
|
private readonly AIObjectiveManager objectiveManager;
|
||||||
|
|
||||||
private float sortTimer;
|
public float SortTimer { get; set; }
|
||||||
private float crouchRaycastTimer;
|
private float crouchRaycastTimer;
|
||||||
private float reactTimer;
|
private float reactTimer;
|
||||||
private float unreachableClearTimer;
|
private float unreachableClearTimer;
|
||||||
@@ -131,7 +131,7 @@ namespace Barotrauma
|
|||||||
outsideSteering = new SteeringManager(this);
|
outsideSteering = new SteeringManager(this);
|
||||||
objectiveManager = new AIObjectiveManager(c);
|
objectiveManager = new AIObjectiveManager(c);
|
||||||
reactTimer = GetReactionTime();
|
reactTimer = GetReactionTime();
|
||||||
sortTimer = Rand.Range(0f, sortObjectiveInterval);
|
SortTimer = Rand.Range(0f, sortObjectiveInterval);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Update(float deltaTime)
|
public override void Update(float deltaTime)
|
||||||
@@ -218,6 +218,7 @@ namespace Barotrauma
|
|||||||
foreach (Character c in Character.CharacterList)
|
foreach (Character c in Character.CharacterList)
|
||||||
{
|
{
|
||||||
if (c.Submarine != Character.Submarine) { continue; }
|
if (c.Submarine != Character.Submarine) { continue; }
|
||||||
|
if (c.Removed || c.IsDead || c.IsIncapacitated) { continue; }
|
||||||
if (IsFriendly(c)) { continue; }
|
if (IsFriendly(c)) { continue; }
|
||||||
Vector2 toTarget = c.WorldPosition - WorldPosition;
|
Vector2 toTarget = c.WorldPosition - WorldPosition;
|
||||||
float dist = toTarget.LengthSquared();
|
float dist = toTarget.LengthSquared();
|
||||||
@@ -264,14 +265,14 @@ namespace Barotrauma
|
|||||||
CheckCrouching(deltaTime);
|
CheckCrouching(deltaTime);
|
||||||
Character.ClearInputs();
|
Character.ClearInputs();
|
||||||
|
|
||||||
if (sortTimer > 0.0f)
|
if (SortTimer > 0.0f)
|
||||||
{
|
{
|
||||||
sortTimer -= deltaTime;
|
SortTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
objectiveManager.SortObjectives();
|
objectiveManager.SortObjectives();
|
||||||
sortTimer = sortObjectiveInterval;
|
SortTimer = sortObjectiveInterval;
|
||||||
}
|
}
|
||||||
objectiveManager.UpdateObjectives(deltaTime);
|
objectiveManager.UpdateObjectives(deltaTime);
|
||||||
|
|
||||||
@@ -288,14 +289,14 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (Character.CurrentHull != null)
|
if (Character.CurrentHull != null)
|
||||||
{
|
{
|
||||||
if (Character.TeamID == CharacterTeamType.FriendlyNPC)
|
if (Character.IsOnPlayerTeam)
|
||||||
{
|
{
|
||||||
// Outpost npcs don't inform each other about threats, like crew members do.
|
VisibleHulls.ForEach(h => PropagateHullSafety(Character, h));
|
||||||
VisibleHulls.ForEach(h => RefreshHullSafety(h));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VisibleHulls.ForEach(h => PropagateHullSafety(Character, h));
|
// Outpost npcs don't inform each other about threats, like crew members do.
|
||||||
|
VisibleHulls.ForEach(h => RefreshHullSafety(h));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Character.SpeechImpediment < 100.0f)
|
if (Character.SpeechImpediment < 100.0f)
|
||||||
@@ -1065,7 +1066,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (!IsFriendly(attacker))
|
if (!IsFriendly(attacker))
|
||||||
{
|
{
|
||||||
return c.IsSecurity ? AIObjectiveCombat.CombatMode.Offensive : AIObjectiveCombat.CombatMode.Defensive;
|
return c.AIController is HumanAIController humanAI &&
|
||||||
|
(humanAI.ObjectiveManager.IsCurrentOrder<AIObjectiveFightIntruders>() || humanAI.ObjectiveManager.Objectives.Any(o => o is AIObjectiveFightIntruders))
|
||||||
|
? AIObjectiveCombat.CombatMode.Offensive : AIObjectiveCombat.CombatMode.Defensive;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1192,7 +1195,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
base.Reset();
|
base.Reset();
|
||||||
objectiveManager.SortObjectives();
|
objectiveManager.SortObjectives();
|
||||||
sortTimer = sortObjectiveInterval;
|
SortTimer = sortObjectiveInterval;
|
||||||
float waitDuration = characterWaitOnSwitch;
|
float waitDuration = characterWaitOnSwitch;
|
||||||
if (ObjectiveManager.IsCurrentObjective<AIObjectiveIdle>())
|
if (ObjectiveManager.IsCurrentObjective<AIObjectiveIdle>())
|
||||||
{
|
{
|
||||||
@@ -1418,6 +1421,9 @@ namespace Barotrauma
|
|||||||
item.StolenDuringRound = true;
|
item.StolenDuringRound = true;
|
||||||
otherCharacter.Speak(TextManager.Get("dialogstealwarning"), null, Rand.Range(0.5f, 1.0f), "thief", 10.0f);
|
otherCharacter.Speak(TextManager.Get("dialogstealwarning"), null, Rand.Range(0.5f, 1.0f), "thief", 10.0f);
|
||||||
someoneSpoke = true;
|
someoneSpoke = true;
|
||||||
|
#if CLIENT
|
||||||
|
HintManager.OnStoleItem(thief, item);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// React if we are security
|
// React if we are security
|
||||||
if (!TriggerSecurity(otherHumanAI))
|
if (!TriggerSecurity(otherHumanAI))
|
||||||
@@ -1554,7 +1560,7 @@ namespace Barotrauma
|
|||||||
targetAdded = true;
|
targetAdded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, (caller.AIController as HumanAIController)?.ReportRange ?? float.PositiveInfinity);
|
}, range: (caller.AIController as HumanAIController)?.ReportRange ?? float.PositiveInfinity);
|
||||||
return targetAdded;
|
return targetAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1726,11 +1732,9 @@ namespace Barotrauma
|
|||||||
switch (myTeam)
|
switch (myTeam)
|
||||||
{
|
{
|
||||||
case CharacterTeamType.None:
|
case CharacterTeamType.None:
|
||||||
// Only enemies are in the Team "None"
|
|
||||||
return false;
|
|
||||||
case CharacterTeamType.Team1:
|
case CharacterTeamType.Team1:
|
||||||
case CharacterTeamType.Team2:
|
case CharacterTeamType.Team2:
|
||||||
// Team1 is only friendly to Team1 and friendly NPCs
|
// Only friendly to the same team and friendly NPCs
|
||||||
return otherTeam == CharacterTeamType.FriendlyNPC;
|
return otherTeam == CharacterTeamType.FriendlyNPC;
|
||||||
case CharacterTeamType.FriendlyNPC:
|
case CharacterTeamType.FriendlyNPC:
|
||||||
// Friendly NPCs are friendly to both teams
|
// Friendly NPCs are friendly to both teams
|
||||||
|
|||||||
@@ -221,6 +221,19 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
currentFlags.Add("CampaignNPC." + speaker.CampaignInteractionType);
|
currentFlags.Add("CampaignNPC." + speaker.CampaignInteractionType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GameMain.GameSession?.GameMode is CampaignMode campaignMode &&
|
||||||
|
(campaignMode.Map?.CurrentLocation?.Type?.Identifier.Equals("abandoned", StringComparison.OrdinalIgnoreCase) ?? false))
|
||||||
|
{
|
||||||
|
if (speaker.TeamID == CharacterTeamType.None)
|
||||||
|
{
|
||||||
|
currentFlags.Add("Bandit");
|
||||||
|
}
|
||||||
|
else if (speaker.TeamID == CharacterTeamType.FriendlyNPC)
|
||||||
|
{
|
||||||
|
currentFlags.Add("Hostage");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return currentFlags;
|
return currentFlags;
|
||||||
|
|||||||
+28
-16
@@ -79,6 +79,7 @@ namespace Barotrauma
|
|||||||
private float coolDownTimer;
|
private float coolDownTimer;
|
||||||
private IEnumerable<Body> myBodies;
|
private IEnumerable<Body> myBodies;
|
||||||
private float aimTimer;
|
private float aimTimer;
|
||||||
|
private float reloadTimer;
|
||||||
private float spreadTimer;
|
private float spreadTimer;
|
||||||
|
|
||||||
private bool canSeeTarget;
|
private bool canSeeTarget;
|
||||||
@@ -147,6 +148,7 @@ namespace Barotrauma
|
|||||||
Mode = CombatMode.Retreat;
|
Mode = CombatMode.Retreat;
|
||||||
}
|
}
|
||||||
spreadTimer = Rand.Range(-10, 10);
|
spreadTimer = Rand.Range(-10, 10);
|
||||||
|
HumanAIController.SortTimer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float GetPriority()
|
public override float GetPriority()
|
||||||
@@ -170,6 +172,10 @@ namespace Barotrauma
|
|||||||
base.Update(deltaTime);
|
base.Update(deltaTime);
|
||||||
ignoreWeaponTimer -= deltaTime;
|
ignoreWeaponTimer -= deltaTime;
|
||||||
checkWeaponsTimer -= deltaTime;
|
checkWeaponsTimer -= deltaTime;
|
||||||
|
if (reloadTimer > 0)
|
||||||
|
{
|
||||||
|
reloadTimer -= deltaTime;
|
||||||
|
}
|
||||||
if (ignoreWeaponTimer < 0)
|
if (ignoreWeaponTimer < 0)
|
||||||
{
|
{
|
||||||
ignoredWeapons.Clear();
|
ignoredWeapons.Clear();
|
||||||
@@ -219,7 +225,11 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
OperateWeapon(deltaTime);
|
OperateWeapon(deltaTime);
|
||||||
}
|
}
|
||||||
if (!HoldPosition && seekAmmunitionObjective == null && seekWeaponObjective == null)
|
if (HoldPosition)
|
||||||
|
{
|
||||||
|
SteeringManager.Reset();
|
||||||
|
}
|
||||||
|
else if (seekAmmunitionObjective == null && seekWeaponObjective == null)
|
||||||
{
|
{
|
||||||
Move(deltaTime);
|
Move(deltaTime);
|
||||||
}
|
}
|
||||||
@@ -641,7 +651,7 @@ namespace Barotrauma
|
|||||||
var slots = Weapon.AllowedSlots.Where(s => s == InvSlotType.LeftHand || s == InvSlotType.RightHand || s == (InvSlotType.LeftHand | InvSlotType.RightHand));
|
var slots = Weapon.AllowedSlots.Where(s => s == InvSlotType.LeftHand || s == InvSlotType.RightHand || s == (InvSlotType.LeftHand | InvSlotType.RightHand));
|
||||||
if (character.Inventory.TryPutItem(Weapon, character, slots))
|
if (character.Inventory.TryPutItem(Weapon, character, slots))
|
||||||
{
|
{
|
||||||
aimTimer = Rand.Range(1f, 1.5f) / AimSpeed;
|
aimTimer = Rand.Range(0.2f, 0.4f) / AimSpeed;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -912,7 +922,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
if (!canSeeTarget)
|
if (!canSeeTarget)
|
||||||
{
|
{
|
||||||
aimTimer = Rand.Range(0.2f, 1f) / AimSpeed;
|
aimTimer = Rand.Range(0.2f, 0.4f) / AimSpeed;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (Weapon.RequireAimToUse)
|
if (Weapon.RequireAimToUse)
|
||||||
@@ -930,6 +940,7 @@ namespace Barotrauma
|
|||||||
aimTimer -= deltaTime;
|
aimTimer -= deltaTime;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (reloadTimer > 0) { return; }
|
||||||
if (Mode == CombatMode.Arrest && isLethalWeapon && Enemy.Stun > 1) { return; }
|
if (Mode == CombatMode.Arrest && isLethalWeapon && Enemy.Stun > 1) { return; }
|
||||||
if (holdFireCondition != null && holdFireCondition()) { return; }
|
if (holdFireCondition != null && holdFireCondition()) { return; }
|
||||||
float sqrDist = Vector2.DistanceSquared(character.Position, Enemy.Position);
|
float sqrDist = Vector2.DistanceSquared(character.Position, Enemy.Position);
|
||||||
@@ -1010,18 +1021,25 @@ namespace Barotrauma
|
|||||||
|
|
||||||
private void UseWeapon(float deltaTime)
|
private void UseWeapon(float deltaTime)
|
||||||
{
|
{
|
||||||
character.SetInput(InputType.Shoot, false, true);
|
|
||||||
Weapon.Use(deltaTime, character);
|
|
||||||
float reloadTime = 0;
|
float reloadTime = 0;
|
||||||
if (WeaponComponent is RangedWeapon rangedWeapon)
|
if (WeaponComponent is RangedWeapon rangedWeapon)
|
||||||
{
|
{
|
||||||
reloadTime = rangedWeapon.Reload;
|
// If the weapon is just equipped, we can't shoot just yet.
|
||||||
|
if (rangedWeapon.ReloadTimer <= 0)
|
||||||
|
{
|
||||||
|
reloadTime = rangedWeapon.Reload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (WeaponComponent is MeleeWeapon mw)
|
if (WeaponComponent is MeleeWeapon mw)
|
||||||
{
|
{
|
||||||
reloadTime = mw.Reload;
|
if (!((HumanoidAnimController)character.AnimController).Crouching)
|
||||||
|
{
|
||||||
|
reloadTime = mw.Reload;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
aimTimer = Math.Max(reloadTime, reloadTime * Rand.Range(1f, 1.5f) / AimSpeed);
|
character.SetInput(InputType.Shoot, false, true);
|
||||||
|
Weapon.Use(deltaTime, character);
|
||||||
|
reloadTimer = Math.Max(reloadTime, reloadTime * Rand.Range(1f, 1.25f) / AimSpeed);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnCompleted()
|
protected override void OnCompleted()
|
||||||
@@ -1031,10 +1049,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Unequip();
|
Unequip();
|
||||||
}
|
}
|
||||||
if (!HoldPosition)
|
SteeringManager.Reset();
|
||||||
{
|
|
||||||
SteeringManager.Reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnAbandon()
|
protected override void OnAbandon()
|
||||||
@@ -1044,10 +1059,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
Unequip();
|
Unequip();
|
||||||
}
|
}
|
||||||
if (!HoldPosition)
|
SteeringManager.Reset();
|
||||||
{
|
|
||||||
SteeringManager.Reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
|
|||||||
+4
-1
@@ -10,6 +10,8 @@ namespace Barotrauma
|
|||||||
protected override float IgnoreListClearInterval => 30;
|
protected override float IgnoreListClearInterval => 30;
|
||||||
public override bool IgnoreUnsafeHulls => true;
|
public override bool IgnoreUnsafeHulls => true;
|
||||||
|
|
||||||
|
protected override float TargetUpdateTimeMultiplier => 0.2f;
|
||||||
|
|
||||||
public AIObjectiveFightIntruders(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1)
|
public AIObjectiveFightIntruders(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1)
|
||||||
: base(character, objectiveManager, priorityModifier) { }
|
: base(character, objectiveManager, priorityModifier) { }
|
||||||
|
|
||||||
@@ -48,7 +50,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public static bool IsValidTarget(Character target, Character character)
|
public static bool IsValidTarget(Character target, Character character)
|
||||||
{
|
{
|
||||||
if (target == null || target.IsDead || target.Removed) { return false; }
|
if (target == null || target.Removed) { return false; }
|
||||||
|
if (target.IsDead || target.IsUnconscious) { return false; }
|
||||||
if (target == character) { return false; }
|
if (target == character) { return false; }
|
||||||
if (target.Submarine == null) { return false; }
|
if (target.Submarine == null) { return false; }
|
||||||
if (character.Submarine == null) { return false; }
|
if (character.Submarine == null) { return false; }
|
||||||
|
|||||||
@@ -555,6 +555,13 @@ namespace Barotrauma
|
|||||||
//otherwise characters can let go of the ladders too soon once they're close enough to the target
|
//otherwise characters can let go of the ladders too soon once they're close enough to the target
|
||||||
if (PathSteering.CurrentPath.NextNode != null) { return false; }
|
if (PathSteering.CurrentPath.NextNode != null) { return false; }
|
||||||
}
|
}
|
||||||
|
if (!character.AnimController.InWater)
|
||||||
|
{
|
||||||
|
float yDiff = Math.Abs(Target.WorldPosition.Y - character.WorldPosition.Y);
|
||||||
|
if (yDiff > CloseEnough) { return false; }
|
||||||
|
float xDiff = Math.Abs(Target.WorldPosition.X - character.WorldPosition.X);
|
||||||
|
return xDiff <= CloseEnough;
|
||||||
|
}
|
||||||
return Vector2.DistanceSquared(Target.WorldPosition, character.WorldPosition) < CloseEnough * CloseEnough;
|
return Vector2.DistanceSquared(Target.WorldPosition, character.WorldPosition) < CloseEnough * CloseEnough;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-5
@@ -11,6 +11,7 @@ namespace Barotrauma
|
|||||||
protected HashSet<T> ignoreList = new HashSet<T>();
|
protected HashSet<T> ignoreList = new HashSet<T>();
|
||||||
private float ignoreListTimer;
|
private float ignoreListTimer;
|
||||||
protected float targetUpdateTimer;
|
protected float targetUpdateTimer;
|
||||||
|
protected virtual float TargetUpdateTimeMultiplier { get; } = 1;
|
||||||
|
|
||||||
private float syncTimer;
|
private float syncTimer;
|
||||||
private readonly float syncTime = 1;
|
private readonly float syncTime = 1;
|
||||||
@@ -61,7 +62,7 @@ namespace Barotrauma
|
|||||||
ignoreListTimer += deltaTime;
|
ignoreListTimer += deltaTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (targetUpdateTimer < 0)
|
if (targetUpdateTimer <= 0)
|
||||||
{
|
{
|
||||||
UpdateTargets();
|
UpdateTargets();
|
||||||
}
|
}
|
||||||
@@ -69,9 +70,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
targetUpdateTimer -= deltaTime;
|
targetUpdateTimer -= deltaTime;
|
||||||
}
|
}
|
||||||
if (syncTimer < 0)
|
if (syncTimer <= 0)
|
||||||
{
|
{
|
||||||
syncTimer = syncTime * Rand.Range(0.9f, 1.1f);
|
syncTimer = Math.Min(syncTime * Rand.Range(0.9f, 1.1f), targetUpdateTimer);
|
||||||
// Sync objectives, subobjectives and targets
|
// Sync objectives, subobjectives and targets
|
||||||
foreach (var objective in Objectives)
|
foreach (var objective in Objectives)
|
||||||
{
|
{
|
||||||
@@ -95,7 +96,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
|
|
||||||
// the timer is set between 1 and 10 seconds, depending on the priority modifier and a random +-25%
|
// the timer is set between 1 and 10 seconds, depending on the priority modifier and a random +-25%
|
||||||
private float SetTargetUpdateTimer() => targetUpdateTimer = 1 / MathHelper.Clamp(PriorityModifier * Rand.Range(0.75f, 1.25f), 0.1f, 1);
|
private float CalculateTargetUpdateTimer() => targetUpdateTimer = 1 / MathHelper.Clamp(PriorityModifier * Rand.Range(0.75f, 1.25f), 0.1f, 1) * TargetUpdateTimeMultiplier;
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
@@ -156,7 +157,7 @@ namespace Barotrauma
|
|||||||
|
|
||||||
protected void UpdateTargets()
|
protected void UpdateTargets()
|
||||||
{
|
{
|
||||||
SetTargetUpdateTimer();
|
CalculateTargetUpdateTimer();
|
||||||
Targets.Clear();
|
Targets.Clear();
|
||||||
FindTargets();
|
FindTargets();
|
||||||
CreateObjectives();
|
CreateObjectives();
|
||||||
|
|||||||
+3
-1
@@ -386,7 +386,9 @@ namespace Barotrauma
|
|||||||
Abandon = true;
|
Abandon = true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool isCompleted = AIObjectiveRescueAll.GetVitalityFactor(targetCharacter) >= AIObjectiveRescueAll.GetVitalityThreshold(objectiveManager, character, targetCharacter);
|
bool isCompleted =
|
||||||
|
AIObjectiveRescueAll.GetVitalityFactor(targetCharacter) >= AIObjectiveRescueAll.GetVitalityThreshold(objectiveManager, character, targetCharacter) ||
|
||||||
|
targetCharacter.CharacterHealth.GetAllAfflictions().All(a => a.Strength < a.Prefab.TreatmentThreshold);
|
||||||
if (isCompleted && targetCharacter != character && character.IsOnPlayerTeam)
|
if (isCompleted && targetCharacter != character && character.IsOnPlayerTeam)
|
||||||
{
|
{
|
||||||
character.Speak(TextManager.GetWithVariable("DialogTargetHealed", "[targetname]", targetCharacter.Name),
|
character.Speak(TextManager.GetWithVariable("DialogTargetHealed", "[targetname]", targetCharacter.Name),
|
||||||
|
|||||||
+3
-3
@@ -25,8 +25,8 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
// When targeting player characters, always treat them when ordered, else use the threshold so that minor/non-severe damage is ignored.
|
// When targeting player characters, always treat them when ordered, else use the threshold so that minor/non-severe damage is ignored.
|
||||||
// If we ignore any damage when the player orders a bot to do healings, it's observed to cause confusion among the players.
|
// If we ignore any damage when the player orders a bot to do healings, it's observed to cause confusion among the players.
|
||||||
// On the other hand, if the bots too eagerly heal characters when it's not nevessary, it's inefficient and can feel frustrating, because it can't be controlled.
|
// On the other hand, if the bots too eagerly heal characters when it's not necessary, it's inefficient and can feel frustrating, because it can't be controlled.
|
||||||
return character == target || manager.CurrentOrder is AIObjectiveRescueAll ? (target.IsPlayer ? 100 : vitalityThresholdForOrders) : vitalityThreshold;
|
return character == target || manager.HasOrder<AIObjectiveRescueAll>() ? (target.IsPlayer ? 100 : vitalityThresholdForOrders) : vitalityThreshold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ namespace Barotrauma
|
|||||||
if (character.AIController is HumanAIController humanAI)
|
if (character.AIController is HumanAIController humanAI)
|
||||||
{
|
{
|
||||||
if (GetVitalityFactor(target) >= GetVitalityThreshold(humanAI.ObjectiveManager, character, target)) { return false; }
|
if (GetVitalityFactor(target) >= GetVitalityThreshold(humanAI.ObjectiveManager, character, target)) { return false; }
|
||||||
if (!humanAI.ObjectiveManager.IsCurrentOrder<AIObjectiveRescueAll>())
|
if (!humanAI.ObjectiveManager.HasOrder<AIObjectiveRescueAll>())
|
||||||
{
|
{
|
||||||
if (!character.IsMedic && target != character)
|
if (!character.IsMedic && target != character)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -281,7 +281,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public const float MAX_SPEED = 30;
|
public const float MAX_SPEED = 20;
|
||||||
|
|
||||||
public Vector2 TargetMovement
|
public Vector2 TargetMovement
|
||||||
{
|
{
|
||||||
@@ -636,9 +636,12 @@ namespace Barotrauma
|
|||||||
//always collides with bodies other than structures
|
//always collides with bodies other than structures
|
||||||
if (!(f2.Body.UserData is Structure structure))
|
if (!(f2.Body.UserData is Structure structure))
|
||||||
{
|
{
|
||||||
lock (impactQueue)
|
if (!f2.IsSensor)
|
||||||
{
|
{
|
||||||
impactQueue.Enqueue(new Impact(f1, f2, contact, velocity));
|
lock (impactQueue)
|
||||||
|
{
|
||||||
|
impactQueue.Enqueue(new Impact(f1, f2, contact, velocity));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public Entity LastDamageSource;
|
public Entity LastDamageSource;
|
||||||
|
|
||||||
|
public AttackResult LastDamage;
|
||||||
|
|
||||||
public float InvisibleTimer;
|
public float InvisibleTimer;
|
||||||
|
|
||||||
private CharacterPrefab prefab;
|
private CharacterPrefab prefab;
|
||||||
@@ -199,7 +201,12 @@ namespace Barotrauma
|
|||||||
set => Params.Visibility = value;
|
set => Params.Visibility = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsTraitor;
|
public bool IsTraitor
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
set;
|
||||||
|
}
|
||||||
|
|
||||||
public string TraitorCurrentObjective = "";
|
public string TraitorCurrentObjective = "";
|
||||||
public bool IsHuman => SpeciesName.Equals(CharacterPrefab.HumanSpeciesName, StringComparison.OrdinalIgnoreCase);
|
public bool IsHuman => SpeciesName.Equals(CharacterPrefab.HumanSpeciesName, StringComparison.OrdinalIgnoreCase);
|
||||||
public bool IsMale => Info != null && Info.HasGenders && Info.Gender == Gender.Male;
|
public bool IsMale => Info != null && Info.HasGenders && Info.Gender == Gender.Male;
|
||||||
@@ -333,6 +340,7 @@ namespace Barotrauma
|
|||||||
//text displayed when the character is highlighted if custom interact is set
|
//text displayed when the character is highlighted if custom interact is set
|
||||||
public string customInteractHUDText;
|
public string customInteractHUDText;
|
||||||
private Action<Character, Character> onCustomInteract;
|
private Action<Character, Character> onCustomInteract;
|
||||||
|
public ConversationAction ActiveConversation;
|
||||||
|
|
||||||
public bool AllowCustomInteract
|
public bool AllowCustomInteract
|
||||||
{
|
{
|
||||||
@@ -349,6 +357,9 @@ namespace Barotrauma
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
lockHandsTimer = MathHelper.Clamp(lockHandsTimer + (value ? 1.0f : -0.5f), 0.0f, 10.0f);
|
lockHandsTimer = MathHelper.Clamp(lockHandsTimer + (value ? 1.0f : -0.5f), 0.0f, 10.0f);
|
||||||
|
#if CLIENT
|
||||||
|
HintManager.OnHandcuffed(this);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -605,6 +616,9 @@ namespace Barotrauma
|
|||||||
get => _selectedConstruction;
|
get => _selectedConstruction;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
|
#if CLIENT
|
||||||
|
HintManager.OnSetSelectedConstruction(this, _selectedConstruction, value);
|
||||||
|
#endif
|
||||||
_selectedConstruction = value;
|
_selectedConstruction = value;
|
||||||
#if CLIENT
|
#if CLIENT
|
||||||
if (Controlled == this)
|
if (Controlled == this)
|
||||||
@@ -1661,6 +1675,12 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
item.Use(deltaTime, this);
|
item.Use(deltaTime, this);
|
||||||
}
|
}
|
||||||
|
#if CLIENT
|
||||||
|
else if (item.RequireAimToUse && !IsKeyDown(InputType.Aim))
|
||||||
|
{
|
||||||
|
HintManager.OnShootWithoutAiming(this, item);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1853,6 +1873,19 @@ namespace Barotrauma
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Item GetEquippedItem(string tagOrIdentifier)
|
||||||
|
{
|
||||||
|
if (Inventory == null) { return null; }
|
||||||
|
for (int i = 0; i < Inventory.Capacity; i++)
|
||||||
|
{
|
||||||
|
if (Inventory.SlotTypes[i] == InvSlotType.Any) { continue; }
|
||||||
|
var item = Inventory.GetItemAt(i);
|
||||||
|
if (item == null) { continue; }
|
||||||
|
if (item.Prefab.Identifier == tagOrIdentifier || item.HasTag(tagOrIdentifier)) { return item; }
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public bool CanAccessInventory(Inventory inventory)
|
public bool CanAccessInventory(Inventory inventory)
|
||||||
{
|
{
|
||||||
if (!CanInteract || inventory.Locked) { return false; }
|
if (!CanInteract || inventory.Locked) { return false; }
|
||||||
@@ -2857,6 +2890,7 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
if (character == this) { continue; }
|
if (character == this) { continue; }
|
||||||
if (character.TeamID != TeamID) { continue; }
|
if (character.TeamID != TeamID) { continue; }
|
||||||
|
if (!HumanAIController.IsActive(character)) { continue; }
|
||||||
foreach (var currentOrder in character.CurrentOrders)
|
foreach (var currentOrder in character.CurrentOrders)
|
||||||
{
|
{
|
||||||
if (currentOrder.Order == null) { continue; }
|
if (currentOrder.Order == null) { continue; }
|
||||||
@@ -3268,12 +3302,13 @@ namespace Barotrauma
|
|||||||
//#endif
|
//#endif
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
SetStun(stun);
|
||||||
|
|
||||||
if (attacker != null && attacker != this && GameMain.NetworkMember != null && !GameMain.NetworkMember.ServerSettings.AllowFriendlyFire)
|
if (attacker != null && attacker != this && GameMain.NetworkMember != null && !GameMain.NetworkMember.ServerSettings.AllowFriendlyFire)
|
||||||
{
|
{
|
||||||
if (attacker.TeamID == TeamID) { return new AttackResult(); }
|
if (attacker.TeamID == TeamID) { return new AttackResult(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
SetStun(stun);
|
|
||||||
Vector2 dir = hitLimb.WorldPosition - worldPosition;
|
Vector2 dir = hitLimb.WorldPosition - worldPosition;
|
||||||
if (Math.Abs(attackImpulse) > 0.0f)
|
if (Math.Abs(attackImpulse) > 0.0f)
|
||||||
{
|
{
|
||||||
@@ -3308,6 +3343,7 @@ namespace Barotrauma
|
|||||||
};
|
};
|
||||||
if (attackResult.Damage > 0)
|
if (attackResult.Damage > 0)
|
||||||
{
|
{
|
||||||
|
LastDamage = attackResult;
|
||||||
ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
||||||
hitLimb.ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
hitLimb.ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
||||||
if (attacker != null)
|
if (attacker != null)
|
||||||
|
|||||||
@@ -153,6 +153,8 @@ namespace Barotrauma
|
|||||||
private static ushort idCounter;
|
private static ushort idCounter;
|
||||||
private const string disguiseName = "???";
|
private const string disguiseName = "???";
|
||||||
|
|
||||||
|
public bool HasNickname => Name != OriginalName;
|
||||||
|
public string OriginalName { get; private set; }
|
||||||
public string Name;
|
public string Name;
|
||||||
public string DisplayName
|
public string DisplayName
|
||||||
{
|
{
|
||||||
@@ -453,7 +455,7 @@ namespace Barotrauma
|
|||||||
public bool IsAttachmentsLoaded => HairIndex > -1 && BeardIndex > -1 && MoustacheIndex > -1 && FaceAttachmentIndex > -1;
|
public bool IsAttachmentsLoaded => HairIndex > -1 && BeardIndex > -1 && MoustacheIndex > -1 && FaceAttachmentIndex > -1;
|
||||||
|
|
||||||
// Used for creating the data
|
// Used for creating the data
|
||||||
public CharacterInfo(string speciesName, string name = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
public CharacterInfo(string speciesName, string name = "", string originalName = "", JobPrefab jobPrefab = null, string ragdollFileName = null, int variant = 0, Rand.RandSync randSync = Rand.RandSync.Unsynced)
|
||||||
{
|
{
|
||||||
if (speciesName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
|
if (speciesName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
@@ -503,6 +505,7 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
OriginalName = !string.IsNullOrEmpty(originalName) ? originalName : Name;
|
||||||
personalityTrait = NPCPersonalityTrait.GetRandom(name + HeadSpriteId);
|
personalityTrait = NPCPersonalityTrait.GetRandom(name + HeadSpriteId);
|
||||||
Salary = CalculateSalary();
|
Salary = CalculateSalary();
|
||||||
if (ragdollFileName != null)
|
if (ragdollFileName != null)
|
||||||
@@ -518,6 +521,7 @@ namespace Barotrauma
|
|||||||
ID = idCounter;
|
ID = idCounter;
|
||||||
idCounter++;
|
idCounter++;
|
||||||
Name = infoElement.GetAttributeString("name", "");
|
Name = infoElement.GetAttributeString("name", "");
|
||||||
|
OriginalName = infoElement.GetAttributeString("originalname", null);
|
||||||
string genderStr = infoElement.GetAttributeString("gender", "male").ToLowerInvariant();
|
string genderStr = infoElement.GetAttributeString("gender", "male").ToLowerInvariant();
|
||||||
Salary = infoElement.GetAttributeInt("salary", 1000);
|
Salary = infoElement.GetAttributeInt("salary", 1000);
|
||||||
Enum.TryParse(infoElement.GetAttributeString("race", "White"), true, out Race race);
|
Enum.TryParse(infoElement.GetAttributeString("race", "White"), true, out Race race);
|
||||||
@@ -576,6 +580,11 @@ namespace Barotrauma
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(OriginalName))
|
||||||
|
{
|
||||||
|
OriginalName = Name;
|
||||||
|
}
|
||||||
|
|
||||||
StartItemsGiven = infoElement.GetAttributeBool("startitemsgiven", false);
|
StartItemsGiven = infoElement.GetAttributeBool("startitemsgiven", false);
|
||||||
string personalityName = infoElement.GetAttributeString("personality", "");
|
string personalityName = infoElement.GetAttributeString("personality", "");
|
||||||
ragdollFileName = infoElement.GetAttributeString("ragdoll", string.Empty);
|
ragdollFileName = infoElement.GetAttributeString("ragdoll", string.Empty);
|
||||||
@@ -622,7 +631,17 @@ namespace Barotrauma
|
|||||||
|
|
||||||
public int GetIdentifier()
|
public int GetIdentifier()
|
||||||
{
|
{
|
||||||
int id = ToolBox.StringToInt(Name);
|
return GetIdentifier(Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetIdentifierUsingOriginalName()
|
||||||
|
{
|
||||||
|
return GetIdentifier(OriginalName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetIdentifier(string name)
|
||||||
|
{
|
||||||
|
int id = ToolBox.StringToInt(name);
|
||||||
id ^= HeadSpriteId;
|
id ^= HeadSpriteId;
|
||||||
id ^= (int)Race << 6;
|
id ^= (int)Race << 6;
|
||||||
id ^= HairIndex << 12;
|
id ^= HairIndex << 12;
|
||||||
@@ -939,12 +958,24 @@ namespace Barotrauma
|
|||||||
|
|
||||||
partial void OnSkillChanged(string skillIdentifier, float prevLevel, float newLevel, Vector2 textPopupPos);
|
partial void OnSkillChanged(string skillIdentifier, float prevLevel, float newLevel, Vector2 textPopupPos);
|
||||||
|
|
||||||
|
public void Rename(string newName)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(newName)) { return; }
|
||||||
|
Name = newName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ResetName()
|
||||||
|
{
|
||||||
|
Name = OriginalName;
|
||||||
|
}
|
||||||
|
|
||||||
public XElement Save(XElement parentElement)
|
public XElement Save(XElement parentElement)
|
||||||
{
|
{
|
||||||
XElement charElement = new XElement("Character");
|
XElement charElement = new XElement("Character");
|
||||||
|
|
||||||
charElement.Add(
|
charElement.Add(
|
||||||
new XAttribute("name", Name),
|
new XAttribute("name", Name),
|
||||||
|
new XAttribute("originalname", OriginalName),
|
||||||
new XAttribute("speciesname", SpeciesName),
|
new XAttribute("speciesname", SpeciesName),
|
||||||
new XAttribute("gender", Head.gender == Gender.Male ? "male" : "female"),
|
new XAttribute("gender", Head.gender == Gender.Male ? "male" : "female"),
|
||||||
new XAttribute("race", Head.race.ToString()),
|
new XAttribute("race", Head.race.ToString()),
|
||||||
@@ -957,7 +988,7 @@ namespace Barotrauma
|
|||||||
new XAttribute("startitemsgiven", StartItemsGiven),
|
new XAttribute("startitemsgiven", StartItemsGiven),
|
||||||
new XAttribute("ragdoll", ragdollFileName),
|
new XAttribute("ragdoll", ragdollFileName),
|
||||||
new XAttribute("personality", personalityTrait == null ? "" : personalityTrait.Name));
|
new XAttribute("personality", personalityTrait == null ? "" : personalityTrait.Name));
|
||||||
|
|
||||||
// TODO: animations?
|
// TODO: animations?
|
||||||
|
|
||||||
if (Character != null)
|
if (Character != null)
|
||||||
|
|||||||
+5
-2
@@ -260,10 +260,13 @@ namespace Barotrauma
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use this method to skip clamping and additional logic of the setters.
|
/// Use this method to skip clamping and additional logic of the setters.
|
||||||
/// Intended only to be used when the value is already clamped! (networking code)
|
|
||||||
/// Ideally we would keep this private, but doing so would require too much refactoring.
|
/// Ideally we would keep this private, but doing so would require too much refactoring.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void SetStrength(float strength) => _strength = strength;
|
public void SetStrength(float strength)
|
||||||
|
{
|
||||||
|
_nonClampedStrength = strength;
|
||||||
|
_strength = _nonClampedStrength;
|
||||||
|
}
|
||||||
|
|
||||||
public bool ShouldShowIcon(Character afflictedCharacter)
|
public bool ShouldShowIcon(Character afflictedCharacter)
|
||||||
{
|
{
|
||||||
|
|||||||
+28
-3
@@ -290,6 +290,9 @@ namespace Barotrauma
|
|||||||
//how high the strength has to be for the affliction icon to be shown with a health scanner
|
//how high the strength has to be for the affliction icon to be shown with a health scanner
|
||||||
public readonly float ShowInHealthScannerThreshold = 0.05f;
|
public readonly float ShowInHealthScannerThreshold = 0.05f;
|
||||||
|
|
||||||
|
//how strong the affliction needs to be before bots attempt to treat it
|
||||||
|
public readonly float TreatmentThreshold = 5.0f;
|
||||||
|
|
||||||
//how much karma changes when a player applies this affliction to someone (per strength of the affliction)
|
//how much karma changes when a player applies this affliction to someone (per strength of the affliction)
|
||||||
public float KarmaChangeOnApplied;
|
public float KarmaChangeOnApplied;
|
||||||
|
|
||||||
@@ -376,6 +379,9 @@ namespace Barotrauma
|
|||||||
{
|
{
|
||||||
DebugConsole.ThrowError("Cannot override all afflictions, because many of them are required by the main game! Please try overriding them one by one.");
|
DebugConsole.ThrowError("Cannot override all afflictions, because many of them are required by the main game! Please try overriding them one by one.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<(AfflictionPrefab prefab, XElement element)> loadedAfflictions = new List<(AfflictionPrefab prefab, XElement element)>();
|
||||||
|
|
||||||
foreach (XElement element in mainElement.Elements())
|
foreach (XElement element in mainElement.Elements())
|
||||||
{
|
{
|
||||||
bool isOverride = element.IsOverride();
|
bool isOverride = element.IsOverride();
|
||||||
@@ -510,10 +516,18 @@ namespace Barotrauma
|
|||||||
|
|
||||||
if (prefab != null)
|
if (prefab != null)
|
||||||
{
|
{
|
||||||
|
loadedAfflictions.Add((prefab, element));
|
||||||
Prefabs.Add(prefab, isOverride);
|
Prefabs.Add(prefab, isOverride);
|
||||||
prefab.CalculatePrefabUIntIdentifier(Prefabs);
|
prefab.CalculatePrefabUIntIdentifier(Prefabs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//load the effects after all the afflictions in the file have been instantiated
|
||||||
|
//otherwise afflictions can't inflict other afflictions that are defined at a later point in the file
|
||||||
|
foreach ((AfflictionPrefab prefab, XElement element) in loadedAfflictions)
|
||||||
|
{
|
||||||
|
prefab.LoadEffects(element);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RemoveByFile(string filePath)
|
public static void RemoveByFile(string filePath)
|
||||||
@@ -565,6 +579,7 @@ namespace Barotrauma
|
|||||||
MaxStrength = element.GetAttributeFloat("maxstrength", 100.0f);
|
MaxStrength = element.GetAttributeFloat("maxstrength", 100.0f);
|
||||||
|
|
||||||
ShowInHealthScannerThreshold = element.GetAttributeFloat("showinhealthscannerthreshold", Math.Max(ActivationThreshold, 0.05f));
|
ShowInHealthScannerThreshold = element.GetAttributeFloat("showinhealthscannerthreshold", Math.Max(ActivationThreshold, 0.05f));
|
||||||
|
TreatmentThreshold = element.GetAttributeFloat("treatmentthreshold", Math.Max(ActivationThreshold, 5.0f));
|
||||||
|
|
||||||
DamageOverlayAlpha = element.GetAttributeFloat("damageoverlayalpha", 0.0f);
|
DamageOverlayAlpha = element.GetAttributeFloat("damageoverlayalpha", 0.0f);
|
||||||
BurnOverlayAlpha = element.GetAttributeFloat("burnoverlayalpha", 0.0f);
|
BurnOverlayAlpha = element.GetAttributeFloat("burnoverlayalpha", 0.0f);
|
||||||
@@ -584,9 +599,6 @@ namespace Barotrauma
|
|||||||
case "icon":
|
case "icon":
|
||||||
Icon = new Sprite(subElement);
|
Icon = new Sprite(subElement);
|
||||||
break;
|
break;
|
||||||
case "effect":
|
|
||||||
effects.Add(new Effect(subElement, Name));
|
|
||||||
break;
|
|
||||||
case "periodiceffect":
|
case "periodiceffect":
|
||||||
periodicEffects.Add(new PeriodicEffect(subElement, Name));
|
periodicEffects.Add(new PeriodicEffect(subElement, Name));
|
||||||
break;
|
break;
|
||||||
@@ -614,6 +626,19 @@ namespace Barotrauma
|
|||||||
constructor = type.GetConstructor(new[] { typeof(AfflictionPrefab), typeof(float) });
|
constructor = type.GetConstructor(new[] { typeof(AfflictionPrefab), typeof(float) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LoadEffects(XElement element)
|
||||||
|
{
|
||||||
|
foreach (XElement subElement in element.Elements())
|
||||||
|
{
|
||||||
|
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||||
|
{
|
||||||
|
case "effect":
|
||||||
|
effects.Add(new Effect(subElement, Name));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return "AfflictionPrefab (" + Name + ")";
|
return "AfflictionPrefab (" + Name + ")";
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user