Unstable v0.1300.0.1
This commit is contained in:
@@ -257,7 +257,7 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
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;
|
||||
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 diffViewCenter;
|
||||
|
||||
@@ -529,6 +529,7 @@ namespace Barotrauma
|
||||
{
|
||||
ushort infoID = inc.ReadUInt16();
|
||||
string newName = inc.ReadString();
|
||||
string originalName = inc.ReadString();
|
||||
int gender = inc.ReadByte();
|
||||
int race = inc.ReadByte();
|
||||
int headSpriteID = inc.ReadByte();
|
||||
@@ -556,7 +557,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
// TODO: animations
|
||||
CharacterInfo ch = new CharacterInfo(speciesName, newName, jobPrefab, ragdollFile, variant)
|
||||
CharacterInfo ch = new CharacterInfo(speciesName, newName, originalName, jobPrefab, ragdollFile, variant)
|
||||
{
|
||||
ID = infoID,
|
||||
};
|
||||
|
||||
@@ -240,6 +240,8 @@ namespace Barotrauma
|
||||
Character.Controlled.SelectedConstruction = null;
|
||||
}
|
||||
}
|
||||
|
||||
HintManager.OnShowHealthInterface();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -718,6 +720,7 @@ namespace Barotrauma
|
||||
int dmgPerSecond = Math.Sign(a2.DamagePerSecond - a1.DamagePerSecond);
|
||||
return dmgPerSecond != 0 ? dmgPerSecond : Math.Sign(a1.Strength - a1.Strength);
|
||||
});
|
||||
HintManager.OnAfflictionDisplayed(Character, currentDisplayedAfflictions.FirstOrDefault());
|
||||
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
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
Color = GetAfflictionIconColor(affliction.Prefab, affliction),
|
||||
Color = GetAfflictionIconColor(affliction),
|
||||
CanBeFocused = false
|
||||
};
|
||||
afflictionIcon.PressedColor = afflictionIcon.Color;
|
||||
@@ -1911,7 +1916,7 @@ namespace Barotrauma
|
||||
float alpha = MathHelper.Lerp(0.3f, 1.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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1534,7 +1534,9 @@ namespace Barotrauma
|
||||
List<string> lines = missingTags.Select(t => "\"" + t.Key + "\"\n missing from " + string.Join(", ", t.Value)).ToList();
|
||||
|
||||
string filePath = "missingloca.txt";
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
File.WriteAllLines(filePath, lines);
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||
TextManager.Language = "English";
|
||||
}));
|
||||
@@ -1543,7 +1545,9 @@ namespace Barotrauma
|
||||
{
|
||||
var debugLines = EventSet.GetDebugStatistics();
|
||||
string filePath = "eventstats.txt";
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
File.WriteAllLines(filePath, debugLines);
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||
}));
|
||||
|
||||
@@ -1824,7 +1828,9 @@ namespace Barotrauma
|
||||
lines.Add("<EntityName." + me.Identifier + ">" + me.Name + "</EntityName." + me.Identifier + ">");
|
||||
lines.Add("<EntityDescription." + me.Identifier + ">" + me.Description + "</EntityDescription." + me.Identifier + ">");
|
||||
}
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
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) =>
|
||||
@@ -1843,16 +1849,15 @@ namespace Barotrauma
|
||||
docs.Add(eventPrefab.ConfigElement.Document);
|
||||
getTextsFromElement(eventPrefab.ConfigElement, lines, eventPrefab.Identifier);
|
||||
}
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
File.WriteAllLines(filePath, lines);
|
||||
|
||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||
|
||||
System.Xml.XmlWriterSettings settings = new System.Xml.XmlWriterSettings
|
||||
{
|
||||
Indent = true,
|
||||
NewLineOnAttributes = false
|
||||
};
|
||||
|
||||
};
|
||||
foreach (XDocument doc in docs)
|
||||
{
|
||||
using (var writer = XmlWriter.Create(new System.Uri(doc.BaseUri).LocalPath, settings))
|
||||
@@ -1861,6 +1866,7 @@ namespace Barotrauma
|
||||
writer.Flush();
|
||||
}
|
||||
}
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
|
||||
void getTextsFromElement(XElement element, List<string> list, string parentName)
|
||||
{
|
||||
@@ -2007,7 +2013,9 @@ namespace Barotrauma
|
||||
lines.Add("[/table]");
|
||||
lines.Add("");
|
||||
}
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
File.WriteAllLines(filePath, lines);
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
ToolBox.OpenFileWithShell(Path.GetFullPath(filePath));
|
||||
}));
|
||||
#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) =>
|
||||
{
|
||||
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\propertylocalization.txt";
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
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) =>
|
||||
|
||||
@@ -560,6 +560,22 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
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,7 +10,16 @@ namespace Barotrauma
|
||||
|
||||
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();
|
||||
for (int j = 0; j < itemCount; j++)
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Barotrauma
|
||||
{
|
||||
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
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
{
|
||||
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,
|
||||
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; }
|
||||
|
||||
@@ -457,13 +457,13 @@ namespace Barotrauma
|
||||
|
||||
Color currentTextColor;
|
||||
|
||||
if (currentRichTextData != null && i > currentRichTextData.EndIndex + lineNum)
|
||||
while (currentRichTextData != null && i + rtdOffset > currentRichTextData.EndIndex + lineNum)
|
||||
{
|
||||
richTextDataIndex++;
|
||||
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;
|
||||
if (!string.IsNullOrEmpty(currentRichTextData.Metadata))
|
||||
|
||||
@@ -321,6 +321,10 @@ namespace Barotrauma
|
||||
float prevSize = chatBox.BarSize;
|
||||
|
||||
string displayedText = message.TranslatedText;
|
||||
if (message.Type == ChatMessageType.Server)
|
||||
{
|
||||
RichTextData.GetRichTextData(displayedText, out displayedText);
|
||||
}
|
||||
string senderName = "";
|
||||
Color senderColor = Color.White;
|
||||
if (!string.IsNullOrWhiteSpace(message.SenderName))
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using Barotrauma.Networking;
|
||||
|
||||
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);
|
||||
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
|
||||
};
|
||||
@@ -208,7 +208,7 @@ namespace Barotrauma
|
||||
{
|
||||
ClickSound = GUISoundType.HireRepairClick,
|
||||
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"))
|
||||
{
|
||||
@@ -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")
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -346,19 +346,22 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
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()))
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
GUILayoutGroup nameAndJobGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.4f - portraitWidth, 0.8f), mainGroup.RectTransform));
|
||||
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform),
|
||||
characterInfo.Name, textColor: jobColor, textAlignment: Alignment.BottomLeft)
|
||||
GUILayoutGroup nameAndJobGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.4f - portraitWidth, 0.8f), mainGroup.RectTransform)) { CanBeFocused = false };
|
||||
GUILayoutGroup nameGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.5f), nameAndJobGroup.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { CanBeFocused = false };
|
||||
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(Vector2.One, nameGroup.RectTransform),
|
||||
listBox == hireableList ? characterInfo.OriginalName : characterInfo.Name,
|
||||
textColor: jobColor, textAlignment: Alignment.BottomLeft)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
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),
|
||||
characterInfo.Job.Name, textColor: Color.White, font: GUI.SmallFont, textAlignment: Alignment.TopLeft)
|
||||
{
|
||||
@@ -384,11 +387,18 @@ namespace Barotrauma
|
||||
|
||||
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
|
||||
};
|
||||
}
|
||||
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)
|
||||
{
|
||||
@@ -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)
|
||||
@@ -479,7 +506,10 @@ namespace Barotrauma
|
||||
GUILayoutGroup infoValueGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.6f, 1.0f), infoGroup.RectTransform)) { Stretch = true };
|
||||
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), 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)
|
||||
{
|
||||
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); }
|
||||
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == characterInfo));
|
||||
pendingList.UpdateScrollBarSize();
|
||||
CreateCharacterFrame(characterInfo, hireableList);
|
||||
SortCharacters(hireableList, (SortingMethod)sortingDropDown.SelectedItemData);
|
||||
hireableList.UpdateScrollBarSize();
|
||||
|
||||
// Server will reset the names to originals in multiplayer
|
||||
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 (createNetworkMessage) { SendCrewState(true); }
|
||||
return true;
|
||||
@@ -573,36 +612,41 @@ namespace Barotrauma
|
||||
{
|
||||
if (pendingList == null || totalBlock == null || validateHiresButton == null) { return; }
|
||||
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);
|
||||
bool enoughMoney = campaign != null ? total <= campaign.Money : true;
|
||||
totalBlock.TextColor = enoughMoney ? Color.White : Color.Red;
|
||||
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>();
|
||||
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 == null || hires.None()) { return false; }
|
||||
|
||||
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;
|
||||
foreach (CharacterInfo ci in hires)
|
||||
foreach (CharacterInfo ci in nonDuplicateHires)
|
||||
{
|
||||
if (campaign.TryHireCharacter(campaign.Map.CurrentLocation, ci))
|
||||
{
|
||||
atLeastOneHired = true;
|
||||
PendingHires.Remove(ci);
|
||||
pendingList.Content.RemoveChild(pendingList.Content.FindChild(c => (c.UserData as Tuple<CharacterInfo, float>).Item1 == ci));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -629,6 +673,93 @@ namespace Barotrauma
|
||||
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)
|
||||
{
|
||||
if (!(selection is CharacterInfo characterInfo)) { return false; }
|
||||
@@ -649,9 +780,10 @@ namespace Barotrauma
|
||||
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;
|
||||
GUIListBox listBox = null;
|
||||
@@ -674,7 +806,7 @@ namespace Barotrauma
|
||||
|
||||
if (listBox != null)
|
||||
{
|
||||
SelectCharacter(listBox, GUI.MouseOn as GUIFrame, characterInfo);
|
||||
SelectCharacter(listBox, highlightedFrame as GUIFrame, highlightedInfo);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -688,6 +820,27 @@ namespace Barotrauma
|
||||
characterPreviewFrame.Parent?.RemoveChild(characterPreviewFrame);
|
||||
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)
|
||||
@@ -700,7 +853,7 @@ namespace Barotrauma
|
||||
PendingHires.Clear();
|
||||
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)
|
||||
{
|
||||
PendingHires.Add(match);
|
||||
@@ -717,9 +870,10 @@ namespace Barotrauma
|
||||
/// Notify the server of crew changes
|
||||
/// </summary>
|
||||
/// <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="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)
|
||||
{
|
||||
@@ -732,12 +886,23 @@ namespace Barotrauma
|
||||
msg.Write((ushort)PendingHires.Count);
|
||||
foreach (CharacterInfo pendingHire in PendingHires)
|
||||
{
|
||||
msg.Write(pendingHire.GetIdentifier());
|
||||
msg.Write(pendingHire.GetIdentifierUsingOriginalName());
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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)
|
||||
@@ -1407,7 +1407,7 @@ namespace Barotrauma
|
||||
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)
|
||||
{
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
@@ -1430,15 +1430,15 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Draw(t, new Rectangle(rect.X + thickness, rect.Y, rect.Width - thickness * 2, thickness), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
||||
sb.Draw(t, new Rectangle(rect.X + thickness, rect.Y + rect.Height - thickness, rect.Width - thickness * 2, thickness), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
||||
|
||||
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 Rectangle(rect.X + rect.Width - thickness, rect.Y, thickness, rect.Height), null, clr, 0.0f, Vector2.Zero, SpriteEffects.None, depth);
|
||||
Rectangle srcRect = new Rectangle(0, 0, 1, 1);
|
||||
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 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 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);
|
||||
|
||||
@@ -1455,7 +1455,7 @@ namespace Barotrauma
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -705,6 +705,29 @@ namespace Barotrauma
|
||||
if (!Visible) return;
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -4,6 +4,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Barotrauma.Networking;
|
||||
using Barotrauma.Extensions;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -22,11 +23,11 @@ namespace Barotrauma
|
||||
{
|
||||
Default,
|
||||
InGame,
|
||||
Vote
|
||||
Vote,
|
||||
Hint
|
||||
}
|
||||
|
||||
public List<GUIButton> Buttons { get; private set; } = new List<GUIButton>();
|
||||
//public GUIFrame BackgroundFrame { get; private set; }
|
||||
public GUILayoutGroup Content { get; private set; }
|
||||
public GUIFrame InnerFrame { get; private set; }
|
||||
public GUITextBlock Header { get; private set; }
|
||||
@@ -58,8 +59,6 @@ namespace Barotrauma
|
||||
|
||||
public bool AutoClose;
|
||||
|
||||
private readonly bool alwaysVisible;
|
||||
|
||||
private float openState;
|
||||
private float iconState;
|
||||
private bool iconSwitching;
|
||||
@@ -77,10 +76,17 @@ namespace Barotrauma
|
||||
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")
|
||||
{
|
||||
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)
|
||||
{
|
||||
width = (int)(GameMain.GraphicsWidth * relativeSize.Value.X);
|
||||
@@ -107,6 +113,7 @@ namespace Barotrauma
|
||||
Anchor anchor = type switch
|
||||
{
|
||||
Type.InGame => Anchor.TopCenter,
|
||||
Type.Hint => Anchor.TopRight,
|
||||
Type.Vote => Anchor.TopRight,
|
||||
_ => 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 };
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
Text.RectTransform.NonScaledSize = Text.RectTransform.MinSize = Text.RectTransform.MaxSize =
|
||||
new Point(Text.Rect.Width, Text.Rect.Height);
|
||||
@@ -180,7 +187,6 @@ namespace Barotrauma
|
||||
else if (type == Type.InGame)
|
||||
{
|
||||
InnerFrame.RectTransform.AbsoluteOffset = new Point(0, GameMain.GraphicsHeight);
|
||||
alwaysVisible = true;
|
||||
CanBeFocused = false;
|
||||
AutoClose = true;
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
Content.Recalculate();
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/// <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()
|
||||
{
|
||||
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();
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = MessageBoxes.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (MessageBoxes[i].UserData as string == "verificationprompt" ||
|
||||
MessageBoxes[i].UserData as string == "bugreporter")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!(MessageBoxes[i] is GUIMessageBox msgBox) || !msgBox.alwaysVisible)
|
||||
{
|
||||
MessageBoxes[i].AddToGUIUpdateList();
|
||||
if (MessageBoxes[i] == null) { continue; }
|
||||
if (!(MessageBoxes[i] is GUIMessageBox messageBox))
|
||||
{
|
||||
if (type == Type.Default)
|
||||
{
|
||||
// Message box not of type GUIMessageBox is likely the round summary
|
||||
MessageBoxes[i].AddToGUIUpdateList();
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (messageBox.type != type) { continue; }
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -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 defaultPos = new Vector2(0.0f, HUDLayoutSettings.InventoryAreaLower.Y - InnerFrame.Rect.Height - 20 * GUI.Scale);
|
||||
Vector2 endPos = new Vector2(GameMain.GraphicsWidth, defaultPos.Y);
|
||||
Vector2 initialPos, defaultPos, endPos;
|
||||
if (type == Type.InGame)
|
||||
{
|
||||
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)
|
||||
{
|
||||
@@ -428,7 +618,7 @@ namespace Barotrauma
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (type == Type.InGame)
|
||||
if (type == Type.InGame || type == Type.Hint)
|
||||
{
|
||||
closing = true;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ namespace Barotrauma
|
||||
public readonly Sprite[] CursorSprite = new Sprite[7];
|
||||
|
||||
public UISprite RadiationSprite { get; private set; }
|
||||
public SpriteSheet RadiationAnimSpriteSheet { get; private set; }
|
||||
|
||||
public UISprite UIGlow { get; private set; }
|
||||
public UISprite UIGlowCircular { get; private set; }
|
||||
@@ -214,6 +215,9 @@ namespace Barotrauma
|
||||
case "radiation":
|
||||
RadiationSprite = new UISprite(subElement);
|
||||
break;
|
||||
case "radiationanimspritesheet":
|
||||
RadiationAnimSpriteSheet = new SpriteSheet(subElement);
|
||||
break;
|
||||
case "uiglowcircular":
|
||||
UIGlowCircular = new UISprite(subElement);
|
||||
break;
|
||||
|
||||
@@ -279,7 +279,8 @@ namespace Barotrauma
|
||||
/// If the rectT height is set 0, the height is calculated from the text.
|
||||
/// </summary>
|
||||
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)
|
||||
{
|
||||
if (color.HasValue)
|
||||
@@ -289,7 +290,13 @@ namespace Barotrauma
|
||||
if (textColor.HasValue)
|
||||
{
|
||||
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,
|
||||
//use the default CJK font as a fallback
|
||||
|
||||
@@ -70,6 +70,14 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
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 float? loadState;
|
||||
@@ -115,7 +123,7 @@ namespace Barotrauma
|
||||
overlay = TextureLoader.FromFile("Content/UI/LoadingScreenOverlay.png");
|
||||
noiseSprite = new Sprite("Content/UI/noise.png", Vector2.Zero);
|
||||
DrawLoadingText = true;
|
||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
||||
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch, GraphicsDevice graphics, float deltaTime)
|
||||
@@ -215,14 +223,34 @@ namespace Barotrauma
|
||||
|
||||
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[] lines = wrappedTip.Split('\n');
|
||||
float lineHeight = GUI.Font.MeasureString(selectedTip).Y;
|
||||
|
||||
for (int i = 0; i < lines.Length; i++)
|
||||
if (selectedTipRichTextData != null)
|
||||
{
|
||||
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);
|
||||
int rtdOffset = 0;
|
||||
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;
|
||||
//reload tip in the selected language
|
||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
||||
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
||||
GameMain.Config.SetDefaultBindings(legacy: false);
|
||||
GameMain.Config.CheckBindings(useDefaults: true);
|
||||
WaitForLanguageSelection = false;
|
||||
@@ -364,7 +392,7 @@ namespace Barotrauma
|
||||
{
|
||||
drawn = false;
|
||||
LoadState = null;
|
||||
selectedTip = TextManager.Get("LoadingScreenTip", true);
|
||||
SetSelectedTip(TextManager.Get("LoadingScreenTip", true));
|
||||
currentBackgroundTexture = LocationType.List.GetRandom()?.GetPortrait(Rand.Int(int.MaxValue))?.Texture;
|
||||
|
||||
while (!drawn)
|
||||
|
||||
@@ -1284,7 +1284,8 @@ namespace Barotrauma
|
||||
// Add items on the sub(s)
|
||||
Submarine.MainSub?.GetItems(true)
|
||||
.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));
|
||||
|
||||
// Add items in character inventories
|
||||
@@ -1302,6 +1303,16 @@ namespace Barotrauma
|
||||
|
||||
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)
|
||||
{
|
||||
if (OwnedItems.ContainsKey(itemPrefab))
|
||||
|
||||
@@ -882,10 +882,15 @@ namespace Barotrauma
|
||||
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);
|
||||
|
||||
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 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 missionDescriptionSize = GUI.Font.MeasureString(missionDescriptionString);
|
||||
@@ -901,12 +906,12 @@ namespace Barotrauma
|
||||
int iconHeight = Math.Max(missionTextGroup.RectTransform.NonScaledSize.Y, (int)(iconWidth * iconAspectRatio));
|
||||
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), 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), missionNameRichTextData, missionNameString, font: GUI.LargeFont);
|
||||
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), missionDescriptionRichTextData, missionDescriptionString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -465,7 +465,28 @@ namespace Barotrauma
|
||||
|
||||
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())
|
||||
{
|
||||
@@ -535,6 +556,7 @@ namespace Barotrauma
|
||||
Order.Init();
|
||||
EventManagerSettings.Init();
|
||||
BallastFloraPrefab.LoadAll(GetFilesOfType(ContentType.MapCreature));
|
||||
HintManager.Init();
|
||||
TitleScreen.LoadState = 50.0f;
|
||||
yield return CoroutineStatus.Running;
|
||||
|
||||
@@ -920,6 +942,8 @@ namespace Barotrauma
|
||||
Client.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
SubmarinePreview.AddToGUIUpdateList();
|
||||
|
||||
FileSelection.AddToGUIUpdateList();
|
||||
|
||||
DebugConsole.AddToGUIUpdateList();
|
||||
|
||||
@@ -330,7 +330,10 @@ namespace Barotrauma
|
||||
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; }
|
||||
|
||||
@@ -416,7 +419,8 @@ namespace Barotrauma
|
||||
font: font,
|
||||
textColor: character.Info?.Job?.Prefab?.UIColor)
|
||||
{
|
||||
CanBeFocused = false
|
||||
CanBeFocused = false,
|
||||
UserData = "name"
|
||||
};
|
||||
nameBlock.Text = ToolBox.LimitString(character.Name, font, (int)nameBlock.Rect.Width);
|
||||
|
||||
@@ -429,22 +433,7 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = character
|
||||
};
|
||||
|
||||
// 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
|
||||
}};
|
||||
}
|
||||
}
|
||||
SetCharacterButtonTooltip(characterButton);
|
||||
|
||||
if (IsSinglePlayer)
|
||||
{
|
||||
@@ -482,6 +471,14 @@ namespace Barotrauma
|
||||
UserData = character
|
||||
};
|
||||
currentOrderList.RectTransform.IsFixedSize = true;
|
||||
currentOrderList.OnAddedToGUIUpdateList += (component) =>
|
||||
{
|
||||
if (component is GUIListBox list)
|
||||
{
|
||||
list.CanBeFocused = CanIssueOrders;
|
||||
list.CanDragElements = CanIssueOrders && list.Content.CountChildren > 1;
|
||||
}
|
||||
};
|
||||
|
||||
// Previous orders
|
||||
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>
|
||||
/// Sets which character is selected in the crew UI (highlight effect etc)
|
||||
/// </summary>
|
||||
public bool CharacterClicked(GUIComponent component, object selection)
|
||||
{
|
||||
if (!AllowCharacterSwitch) { return false; }
|
||||
Character character = selection as Character;
|
||||
if (character == null || character.IsDead || character.IsUnconscious) { return false; }
|
||||
if (!(selection is Character character) || character.IsDead || character.IsUnconscious) { return false; }
|
||||
if (!character.IsOnPlayerTeam) { return false; }
|
||||
|
||||
SelectCharacter(character);
|
||||
if (GUI.KeyboardDispatcher.Subscriber == crewList) { GUI.KeyboardDispatcher.Subscriber = null; }
|
||||
return true;
|
||||
@@ -588,6 +597,15 @@ namespace Barotrauma
|
||||
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
|
||||
|
||||
#region Dialog
|
||||
@@ -835,7 +853,6 @@ namespace Barotrauma
|
||||
|
||||
if (order == null || order.Identifier == dismissedOrderPrefab.Identifier || updatedExistingIcon)
|
||||
{
|
||||
currentOrderIconList.CanDragElements = currentOrderIconList.Content.CountChildren > 1;
|
||||
RearrangeIcons();
|
||||
return;
|
||||
}
|
||||
@@ -874,7 +891,6 @@ namespace Barotrauma
|
||||
nodeIcon.RectTransform.RepositionChildInHierarchy(hierarchyIndex);
|
||||
}
|
||||
|
||||
currentOrderIconList.CanDragElements = currentOrderIconList.Content.CountChildren > 1;
|
||||
RearrangeIcons();
|
||||
|
||||
void RearrangeIcons()
|
||||
@@ -1276,6 +1292,7 @@ namespace Barotrauma
|
||||
}
|
||||
DisableCommandUI();
|
||||
Character.Controlled = character;
|
||||
HintManager.OnChangeCharacter();
|
||||
}
|
||||
|
||||
private int TryAdjustIndex(int amount)
|
||||
@@ -1537,6 +1554,11 @@ namespace Barotrauma
|
||||
if (characterComponent.UserData is Character character)
|
||||
{
|
||||
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 (character == Character.Controlled && characterComponent.State != GUIComponent.ComponentState.Selected)
|
||||
@@ -1817,6 +1839,8 @@ namespace Barotrauma
|
||||
{
|
||||
Character.Controlled.dontFollowCursor = true;
|
||||
}
|
||||
|
||||
HintManager.OnShowCommandInterface();
|
||||
}
|
||||
|
||||
private void ToggleCommandUI()
|
||||
@@ -3218,14 +3242,14 @@ namespace Barotrauma
|
||||
#endif
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
.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
|
||||
@@ -3242,6 +3266,12 @@ namespace Barotrauma
|
||||
.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
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace Barotrauma
|
||||
{
|
||||
new GUIMessageBox(
|
||||
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,
|
||||
UserData = "missionstartmessage"
|
||||
|
||||
@@ -437,8 +437,10 @@ namespace Barotrauma
|
||||
{
|
||||
ShowCampaignUI = false;
|
||||
}
|
||||
HintManager.OnAvailableTransition(transitionType);
|
||||
}
|
||||
}
|
||||
|
||||
public override void End(TransitionType transitionType = TransitionType.None)
|
||||
{
|
||||
base.End(transitionType);
|
||||
@@ -649,7 +651,7 @@ namespace Barotrauma
|
||||
{
|
||||
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.CampaignID = campaignID;
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
@@ -777,16 +779,29 @@ namespace Barotrauma
|
||||
{
|
||||
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();
|
||||
|
||||
int firedIdentifier = -1;
|
||||
if (fireCharacter) { firedIdentifier = msg.ReadInt32(); }
|
||||
|
||||
if (fireCharacter)
|
||||
{
|
||||
int firedIdentifier = msg.ReadInt32();
|
||||
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
|
||||
if (firedCharacter != null) { CrewManager.FireCharacter(firedCharacter); }
|
||||
@@ -794,10 +809,10 @@ namespace Barotrauma
|
||||
|
||||
if (map?.CurrentLocation?.HireManager != null && CampaignUI?.CrewManagement != null)
|
||||
{
|
||||
CampaignUI?.CrewManagement?.SetHireables(map.CurrentLocation, availableHires);
|
||||
if (validateHires) { CampaignUI?.CrewManagement.ValidatePendingHires(); }
|
||||
CampaignUI?.CrewManagement?.SetPendingHires(pendingHires, map?.CurrentLocation);
|
||||
if (fireCharacter) { CampaignUI?.CrewManagement.UpdateCrew(); }
|
||||
CampaignUI.CrewManagement.SetHireables(map.CurrentLocation, availableHires);
|
||||
if (hiredCharacters.Any()) { CampaignUI.CrewManagement.ValidateHires(hiredCharacters); }
|
||||
CampaignUI.CrewManagement.SetPendingHires(pendingHires, map.CurrentLocation);
|
||||
if (renameCrewMember || fireCharacter) { CampaignUI.CrewManagement.UpdateCrew(); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,11 +57,12 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Instantiates a new single player campaign
|
||||
/// </summary>
|
||||
private SinglePlayerCampaign(string mapSeed) : base(GameModePreset.SinglePlayerCampaign)
|
||||
private SinglePlayerCampaign(string mapSeed, CampaignSettings settings) : base(GameModePreset.SinglePlayerCampaign)
|
||||
{
|
||||
CampaignMetadata = new CampaignMetadata(this);
|
||||
UpgradeManager = new UpgradeManager(this);
|
||||
map = new Map(this, mapSeed);
|
||||
map = new Map(this, mapSeed, settings);
|
||||
Settings = settings;
|
||||
foreach (JobPrefab jobPrefab in JobPrefab.Prefabs)
|
||||
{
|
||||
for (int i = 0; i < jobPrefab.InitialCount; i++)
|
||||
@@ -85,11 +86,14 @@ namespace Barotrauma
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "campaignsettings":
|
||||
Settings = new CampaignSettings(subElement);
|
||||
break;
|
||||
case "crew":
|
||||
GameMain.GameSession.CrewManager = new CrewManager(subElement, true);
|
||||
break;
|
||||
case "map":
|
||||
map = Map.Load(this, subElement);
|
||||
map = Map.Load(this, subElement, Settings);
|
||||
break;
|
||||
case "metadata":
|
||||
CampaignMetadata = new CampaignMetadata(this, subElement);
|
||||
@@ -141,9 +145,9 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// Start a completely new single player campaign
|
||||
/// </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;
|
||||
}
|
||||
|
||||
@@ -608,6 +612,7 @@ namespace Barotrauma
|
||||
{
|
||||
ShowCampaignUI = false;
|
||||
}
|
||||
HintManager.OnAvailableTransition(transitionType);
|
||||
}
|
||||
|
||||
if (!crewDead)
|
||||
@@ -629,9 +634,9 @@ namespace Barotrauma
|
||||
if (nextLevel == null)
|
||||
{
|
||||
//no level selected -> force the player to select one
|
||||
ForceMapUI = true;
|
||||
CampaignUI.SelectTab(InteractionType.Map);
|
||||
map.SelectLocation(-1);
|
||||
ForceMapUI = true;
|
||||
return false;
|
||||
}
|
||||
else if (transitionType == TransitionType.ProgressToNextEmptyLocation)
|
||||
@@ -704,6 +709,7 @@ namespace Barotrauma
|
||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||
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
|
||||
foreach (Character c in Character.CharacterList)
|
||||
|
||||
@@ -99,7 +99,7 @@ namespace Barotrauma.Tutorials
|
||||
captain_medicSpawnPos = Item.ItemList.Find(i => i.HasTag("captain_medicspawnpos")).WorldPosition;
|
||||
tutorial_submarineDoor = Item.ItemList.Find(i => i.HasTag("tutorial_submarinedoor")).GetComponent<Door>();
|
||||
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.TeamID = CharacterTeamType.Team1;
|
||||
captain_medic.GiveJobItems(null);
|
||||
@@ -122,17 +122,17 @@ namespace Barotrauma.Tutorials
|
||||
SetDoorAccess(tutorial_lockedDoor_1, 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.TeamID = CharacterTeamType.Team1;
|
||||
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.TeamID = CharacterTeamType.Team1;
|
||||
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.TeamID = CharacterTeamType.Team1;
|
||||
captain_engineer.GiveJobItems();
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace Barotrauma.Tutorials
|
||||
var patientHull2 = WayPoint.WayPointList.Find(wp => wp.IdCardDesc == "airlock").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.TeamID = CharacterTeamType.Team1;
|
||||
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.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.TeamID = CharacterTeamType.Team1;
|
||||
patient2.GiveJobItems(null);
|
||||
patient2.CanSpeak = 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");
|
||||
subPatient1.TeamID = CharacterTeamType.Team1;
|
||||
subPatient1.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 40.0f) }, stun: 0, playSound: false);
|
||||
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");
|
||||
subPatient2.TeamID = CharacterTeamType.Team1;
|
||||
subPatient2.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.InternalDamage, 40.0f) }, stun: 0, playSound: false);
|
||||
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");
|
||||
subPatient3.TeamID = CharacterTeamType.Team1;
|
||||
subPatient3.AddDamage(patient1.WorldPosition, new List<Affliction>() { new Affliction(AfflictionPrefab.Burn, 20.0f) }, stun: 0, playSound: false);
|
||||
|
||||
@@ -110,7 +110,7 @@ namespace Barotrauma.Tutorials
|
||||
}
|
||||
|
||||
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"));
|
||||
|
||||
WayPoint wayPoint = GetSpawnPoint(charInfo);
|
||||
|
||||
@@ -535,15 +535,15 @@ namespace Barotrauma.Tutorials
|
||||
titleBlock.RectTransform.IsFixedSize = true;
|
||||
}
|
||||
|
||||
List<RichTextData> richTextData = RichTextData.GetRichTextData(text, out text);
|
||||
List<RichTextData> richTextData = RichTextData.GetRichTextData(" " + text, out text);
|
||||
GUITextBlock textBlock;
|
||||
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
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -88,6 +88,8 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HintManager.Update();
|
||||
}
|
||||
|
||||
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));
|
||||
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())
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Barotrauma
|
||||
Audio,
|
||||
VoiceChat,
|
||||
Controls,
|
||||
Gameplay,
|
||||
#if DEBUG
|
||||
Debug
|
||||
#endif
|
||||
@@ -532,29 +533,19 @@ namespace Barotrauma
|
||||
UserData = tab
|
||||
};
|
||||
|
||||
float tabWidth = 0.25f;
|
||||
float tabWidth = 1.0f / tabs.Length;
|
||||
#if DEBUG
|
||||
tabWidth = 0.2f;
|
||||
if (tab != Tab.Debug)
|
||||
{
|
||||
string buttonText = tab != Tab.Debug ? TextManager.Get("SettingsTab." + tab.ToString()) : "Debug";
|
||||
#else
|
||||
string buttonText = TextManager.Get("SettingsTab." + tab.ToString());
|
||||
#endif
|
||||
tabButtons[(int)tab] = new GUIButton(new RectTransform(new Vector2(tabWidth, 1.0f), tabButtonHolder.RectTransform),
|
||||
TextManager.Get("SettingsTab." + tab.ToString()), 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), style: "GUITabButton")
|
||||
{
|
||||
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; }
|
||||
};
|
||||
}
|
||||
#endif
|
||||
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));
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
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);
|
||||
GUIScrollBar particleScrollBar = new GUIScrollBar(new RectTransform(new Vector2(1.0f, 0.05f), rightColumn.RectTransform), style: "GUISlider",
|
||||
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 ----------------------------------------------------------------
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
/// 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),
|
||||
TextManager.Get("Cancel"))
|
||||
{
|
||||
@@ -1465,55 +1475,54 @@ namespace Barotrauma
|
||||
{ RelativeOffset = new Vector2(0.02f, 0.02f) })
|
||||
{ RelativeSpacing = 0.01f };
|
||||
|
||||
var automaticQuickStartTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "Automatic quickstart enabled", style: "GUITickBox");
|
||||
automaticQuickStartTickBox.Selected = AutomaticQuickStartEnabled;
|
||||
automaticQuickStartTickBox.ToolTip = "Will the game automatically move on to Quickstart when the game is launched";
|
||||
automaticQuickStartTickBox.OnSelected = (tickBox) =>
|
||||
void addDebugTickBox(bool initialValue, Action<bool> set, string label, string tooltip)
|
||||
{
|
||||
AutomaticQuickStartEnabled = tickBox.Selected;
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
};
|
||||
var tickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), label, style: "GUITickBox");
|
||||
tickBox.Selected = initialValue;
|
||||
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");
|
||||
automaticCampaignLoadTickBox.Selected = AutomaticCampaignLoadEnabled;
|
||||
automaticCampaignLoadTickBox.ToolTip = "Will the game automatically load the latest campaign save when the game is launched";
|
||||
automaticCampaignLoadTickBox.OnSelected = (tickBox) =>
|
||||
{
|
||||
AutomaticCampaignLoadEnabled = tickBox.Selected;
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
};
|
||||
addDebugTickBox(
|
||||
AutomaticQuickStartEnabled,
|
||||
(b) => AutomaticQuickStartEnabled = b,
|
||||
"Automatic quickstart enabled",
|
||||
"Will the game automatically move on to Quickstart when the game is launched");
|
||||
|
||||
var showSplashScreenTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "Splash screen enabled", style: "GUITickBox");
|
||||
showSplashScreenTickBox.Selected = EnableSplashScreen;
|
||||
showSplashScreenTickBox.ToolTip = "Are the splash screens shown when the game is launched";
|
||||
showSplashScreenTickBox.OnSelected = (tickBox) =>
|
||||
{
|
||||
EnableSplashScreen = tickBox.Selected;
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
};
|
||||
addDebugTickBox(
|
||||
AutomaticCampaignLoadEnabled,
|
||||
(b) => AutomaticCampaignLoadEnabled = b,
|
||||
"Automatic campaign load enabled",
|
||||
"Will the game automatically load the latest campaign save when the game is launched");
|
||||
|
||||
var verboseLoggingTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "Verbose logging enabled", style: "GUITickBox");
|
||||
verboseLoggingTickBox.Selected = VerboseLogging;
|
||||
verboseLoggingTickBox.ToolTip = "Should verbose logging be used";
|
||||
verboseLoggingTickBox.OnSelected = (tickBox) =>
|
||||
{
|
||||
VerboseLogging = tickBox.Selected;
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
};
|
||||
addDebugTickBox(
|
||||
EnableSplashScreen,
|
||||
(b) => EnableSplashScreen = b,
|
||||
"Splash screen enabled",
|
||||
"Are the splash screens shown when the game is launched");
|
||||
|
||||
var textManagerDebugModeTickBox = new GUITickBox(new RectTransform(tickBoxScale / 0.18f, debugTickBoxes.RectTransform, scaleBasis: ScaleBasis.BothHeight), "TextManager debug mode enabled", style: "GUITickBox");
|
||||
textManagerDebugModeTickBox.Selected = TextManagerDebugModeEnabled;
|
||||
textManagerDebugModeTickBox.ToolTip = "Does the TextManager return the text tags for debug purposes?";
|
||||
textManagerDebugModeTickBox.OnSelected = (tickBox) =>
|
||||
{
|
||||
TextManagerDebugModeEnabled = tickBox.Selected;
|
||||
UnsavedSettings = true;
|
||||
return true;
|
||||
};
|
||||
addDebugTickBox(
|
||||
VerboseLogging,
|
||||
(b) => VerboseLogging = b,
|
||||
"Verbose logging enabled",
|
||||
"Should verbose logging be used");
|
||||
|
||||
addDebugTickBox(
|
||||
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
|
||||
|
||||
UnsavedSettings = false; // Reset unsaved settings to false once the UI has been created
|
||||
|
||||
@@ -639,7 +639,13 @@ namespace Barotrauma
|
||||
foreach (Item doubleClickedItem in doubleClickedItems)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@@ -810,6 +816,8 @@ namespace Barotrauma
|
||||
highlightedSubInventorySlot.Inventory.HideTimer = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
HintManager.OnShowSubInventory(slotRef?.Item);
|
||||
}
|
||||
|
||||
public void AssignQuickUseNumKeys()
|
||||
|
||||
@@ -39,6 +39,8 @@ namespace Barotrauma.Items.Components
|
||||
|
||||
private Pair<Rectangle, string> tooltip;
|
||||
|
||||
private GUITextBlock requiredTimeBlock;
|
||||
|
||||
partial void InitProjSpecific()
|
||||
{
|
||||
CreateGUI();
|
||||
@@ -522,7 +524,7 @@ namespace Barotrauma.Items.Components
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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));
|
||||
if (!passive && !CheckBlipVisibility(blip, transducerPos)) { continue; }
|
||||
sonarBlips.Add(blip);
|
||||
HintManager.OnSonarSpottedCharacter(Item, c);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -1399,6 +1400,7 @@ namespace Barotrauma.Items.Components
|
||||
MathHelper.Clamp(limb.Mass * 0.1f, 0.1f, 2.0f));
|
||||
if (!passive && !CheckBlipVisibility(blip, transducerPos)) { continue; }
|
||||
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)))
|
||||
{
|
||||
// Undocking from an outpost
|
||||
campaign.CampaignUI.SelectTab(CampaignMode.InteractionType.Map);
|
||||
campaign.ShowCampaignUI = true;
|
||||
campaign.CampaignUI.SelectTab(CampaignMode.InteractionType.Map);
|
||||
return false;
|
||||
}
|
||||
else if (!Level.IsLoadedOutpost && DockingModeEnabled && ActiveDockingSource != null &&
|
||||
@@ -748,7 +748,7 @@ namespace Barotrauma.Items.Components
|
||||
}
|
||||
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;
|
||||
if (PlayerInput.KeyDown(InputType.Left)) { 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)
|
||||
{
|
||||
float chargeRatio = charge / capacity;
|
||||
chargeIndicator.Color = ToolBox.GradientLerp(chargeRatio, Color.Red, Color.Orange, Color.Green);
|
||||
if (chargeIndicator != null)
|
||||
{
|
||||
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)
|
||||
|
||||
@@ -87,7 +87,7 @@ namespace Barotrauma.Items.Components
|
||||
SpriteEffects.None,
|
||||
depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static Sprite defaultWireSprite;
|
||||
private Sprite overrideSprite;
|
||||
private Sprite wireSprite;
|
||||
|
||||
@@ -167,11 +167,11 @@ namespace Barotrauma.Items.Components
|
||||
{
|
||||
if (DockingTarget.joint != null)
|
||||
{
|
||||
DockingTarget.Lock(isNetworkMessage: true, forcePosition: true);
|
||||
DockingTarget.Lock(isNetworkMessage: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
Lock(isNetworkMessage: true, forcePosition: true);
|
||||
Lock(isNetworkMessage: true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -327,10 +327,11 @@ namespace Barotrauma
|
||||
Vector2 pos = rectCenter + (location.MapPosition + viewOffset) * zoom;
|
||||
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; }
|
||||
|
||||
Rectangle drawRect = location.Type.Sprite.SourceRect;
|
||||
Rectangle drawRect = locationSprite.SourceRect;
|
||||
drawRect.Width = (int)(drawRect.Width * iconScale * zoom * 1.4f);
|
||||
drawRect.Height = (int)(drawRect.Height * iconScale * zoom * 1.4f);
|
||||
drawRect.X = (int)pos.X - drawRect.Width / 2;
|
||||
@@ -375,13 +376,18 @@ namespace Barotrauma
|
||||
foreach (LocationConnection connection in Connections)
|
||||
{
|
||||
if (HighlightedLocation != CurrentDisplayLocation &&
|
||||
connection.Locations.Contains(HighlightedLocation) && connection.Locations.Contains(CurrentDisplayLocation))
|
||||
connection.Locations.Contains(HighlightedLocation) &&
|
||||
connection.Locations.Contains(CurrentDisplayLocation))
|
||||
{
|
||||
if (PlayerInput.PrimaryMouseButtonClicked() &&
|
||||
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
|
||||
if ((GameMain.GameSession?.GameMode as CampaignMode)?.AllowedToManageCampaign() ?? false)
|
||||
else if ((GameMain.GameSession?.GameMode as CampaignMode)?.AllowedToManageCampaign() ?? false)
|
||||
{
|
||||
connectionHighlightState = 0.0f;
|
||||
SelectedConnection = connection;
|
||||
@@ -517,8 +523,6 @@ namespace Barotrauma
|
||||
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));
|
||||
|
||||
Radiation.Draw(spriteBatch, rect, zoom);
|
||||
|
||||
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)),
|
||||
color : Color.White * cameraNoiseStrength * 0.1f,
|
||||
@@ -534,6 +538,8 @@ namespace Barotrauma
|
||||
color: Color.White * cameraNoiseStrength * 0.1f,
|
||||
textureScale: Vector2.One * noiseScale);
|
||||
|
||||
Radiation.Draw(spriteBatch, rect, zoom);
|
||||
|
||||
Pair<Rectangle, string> tooltip = null;
|
||||
if (generationParams.ShowLocations)
|
||||
{
|
||||
@@ -548,8 +554,10 @@ namespace Barotrauma
|
||||
Location location = Locations[i];
|
||||
if (IsInFogOfWar(location)) { continue; }
|
||||
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.Y = (int)pos.Y - drawRect.Width / 2;
|
||||
|
||||
@@ -562,20 +570,14 @@ namespace Barotrauma
|
||||
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;
|
||||
if (location == HighlightedLocation)
|
||||
{
|
||||
iconScale *= 1.2f;
|
||||
}
|
||||
|
||||
location.Type.Sprite.Draw(spriteBatch, pos, color,
|
||||
scale: generationParams.LocationIconSize / location.Type.Sprite.size.X * iconScale * zoom);
|
||||
locationSprite.Draw(spriteBatch, pos, color,
|
||||
scale: generationParams.LocationIconSize / locationSprite.size.X * iconScale * zoom);
|
||||
|
||||
if (location == CurrentDisplayLocation)
|
||||
{
|
||||
@@ -657,8 +659,11 @@ namespace Barotrauma
|
||||
|
||||
DrawDecorativeHUD(spriteBatch, rect);
|
||||
|
||||
bool drawRadiationTooltip = true;
|
||||
|
||||
if (HighlightedLocation != null)
|
||||
{
|
||||
drawRadiationTooltip = false;
|
||||
Vector2 pos = rectCenter + (HighlightedLocation.MapPosition + viewOffset) * zoom;
|
||||
pos.X += 50 * zoom;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if (tooltip != null)
|
||||
{
|
||||
GUIComponent.DrawToolTip(spriteBatch, tooltip.Second, tooltip.First);
|
||||
drawRadiationTooltip = false;
|
||||
}
|
||||
if (connectionTooltip != null)
|
||||
{
|
||||
GUIComponent.DrawToolTip(spriteBatch, connectionTooltip.Second, connectionTooltip.First);
|
||||
drawRadiationTooltip = false;
|
||||
}
|
||||
|
||||
if (drawRadiationTooltip)
|
||||
{
|
||||
Radiation.DrawFront(spriteBatch);
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
GameMain.Instance.GraphicsDevice.ScissorRectangle = prevScissorRect;
|
||||
spriteBatch.Begin(SpriteSortMode.Deferred, samplerState: GUI.SamplerState, rasterizerState: GameMain.ScissorTestEnable);
|
||||
@@ -827,6 +841,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (connection.LevelData.HasBeaconStation) { iconCount++; }
|
||||
if (connection.LevelData.HasHuntingGrounds) { iconCount++; }
|
||||
if (connection.Locked) { iconCount++; }
|
||||
string tooltip = null;
|
||||
var subCrushDepth = Submarine.MainSub?.RealWorldCrushDepth ?? Level.DefaultRealWorldCrushDepth;
|
||||
if (GameMain.GameSession?.Campaign?.UpgradeManager != null)
|
||||
@@ -867,6 +882,11 @@ namespace Barotrauma
|
||||
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)
|
||||
{
|
||||
DrawIcon("HuntingGrounds", (int)(28 * zoom), TextManager.Get("HuntingGroundsTooltip"));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
|
||||
@@ -6,6 +7,13 @@ namespace Barotrauma
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!Enabled) { return; }
|
||||
@@ -19,16 +27,38 @@ namespace Barotrauma
|
||||
Vector2 size = new Vector2((Amount - increasedAmount) * zoom + halfSizeX, viewBottom - topLeft.Y);
|
||||
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)
|
||||
{
|
||||
float spriteStep = Params.BorderAnimationSpeed * deltaTime;
|
||||
spriteIndex = (spriteIndex + spriteStep) % maxFrames;
|
||||
|
||||
if (increasedAmount > 0)
|
||||
{
|
||||
increasedAmount -= (lastIncrease / Params.AnimationSpeed) * deltaTime;
|
||||
|
||||
@@ -805,7 +805,7 @@ namespace Barotrauma
|
||||
}
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -2064,6 +2064,8 @@ namespace Barotrauma.Networking
|
||||
bool autoRestartEnabled = inc.ReadBoolean();
|
||||
float autoRestartTimer = autoRestartEnabled ? inc.ReadSingle() : 0.0f;
|
||||
|
||||
bool radiationEnabled = inc.ReadBoolean();
|
||||
|
||||
//ignore the message if we already a more up-to-date one
|
||||
//or if we're still waiting for the initial update
|
||||
if (NetIdUtils.IdMoreRecent(updateID, GameMain.NetLobbyScreen.LastUpdateID) &&
|
||||
@@ -2119,7 +2121,7 @@ namespace Barotrauma.Networking
|
||||
GameMain.NetLobbyScreen.SetAllowSpectating(allowSpectating);
|
||||
GameMain.NetLobbyScreen.LevelSeed = levelSeed;
|
||||
GameMain.NetLobbyScreen.SetLevelDifficulty(levelDifficulty);
|
||||
GameMain.NetLobbyScreen.SetBotCount(botCount);
|
||||
GameMain.NetLobbyScreen.SetRadiationEnabled(radiationEnabled);
|
||||
GameMain.NetLobbyScreen.SetBotSpawnMode(botSpawnMode);
|
||||
GameMain.NetLobbyScreen.SetAutoRestart(autoRestartEnabled, autoRestartTimer);
|
||||
|
||||
@@ -2564,7 +2566,7 @@ namespace Barotrauma.Networking
|
||||
if (!(GameMain.GameSession?.GameMode is MultiPlayerCampaign campaign) || campaign.CampaignID != campaignID)
|
||||
{
|
||||
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.CampaignID = campaignID;
|
||||
GameMain.NetLobbyScreen.ToggleCampaignMode(true);
|
||||
@@ -2912,7 +2914,7 @@ namespace Barotrauma.Networking
|
||||
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.CampaignFrame.Visible = false;
|
||||
@@ -2927,6 +2929,7 @@ namespace Barotrauma.Networking
|
||||
msg.Write(mapSeed);
|
||||
msg.Write(sub.Name);
|
||||
msg.Write(sub.MD5Hash.Hash);
|
||||
settings.Serialize(msg);
|
||||
|
||||
clientPeer.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
@@ -147,13 +147,36 @@ namespace Barotrauma.Networking
|
||||
if (missingPackages.Count > 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;
|
||||
if (nonDownloadable.Count() == 1)
|
||||
{
|
||||
disconnectMsg = $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(missingPackages[0])}";
|
||||
disconnectMsg = $"DisconnectMessage.MissingContentPackage~[missingcontentpackage]={GetPackageStr(nonDownloadable.First())}";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -56,6 +56,7 @@ namespace Barotrauma.Networking
|
||||
Steamworks.SteamNetworking.AllowP2PPacketRelay(true);
|
||||
|
||||
ServerConnection = new SteamP2PConnection("Server", hostSteamId);
|
||||
ServerConnection.SetOwnerSteamIDIfUnknown(hostSteamId);
|
||||
|
||||
incomingInitializationMessages = new List<IReadMessage>();
|
||||
incomingDataMessages = new List<IReadMessage>();
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Barotrauma.Networking
|
||||
class RemotePeer
|
||||
{
|
||||
public UInt64 SteamID;
|
||||
public UInt64 OwnerSteamID;
|
||||
public double? DisconnectTime;
|
||||
public bool Authenticating;
|
||||
public bool Authenticated;
|
||||
@@ -31,6 +32,7 @@ namespace Barotrauma.Networking
|
||||
public RemotePeer(UInt64 steamId)
|
||||
{
|
||||
SteamID = steamId;
|
||||
OwnerSteamID = 0;
|
||||
DisconnectTime = null;
|
||||
Authenticating = false;
|
||||
Authenticated = false;
|
||||
@@ -90,10 +92,19 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (status == Steamworks.AuthResponse.OK)
|
||||
{
|
||||
remotePeer.OwnerSteamID = ownerID;
|
||||
remotePeer.Authenticated = true;
|
||||
remotePeer.Authenticating = false;
|
||||
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();
|
||||
Array.Resize(ref msgToSend, msg.Message.LengthBytes);
|
||||
ChildServerRelay.Write(msgToSend);
|
||||
@@ -131,6 +142,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
IWriteMessage outMsg = new WriteOnlyMessage();
|
||||
outMsg.Write(steamId);
|
||||
outMsg.Write(remotePeer.OwnerSteamID);
|
||||
outMsg.Write(data, 1, dataLength - 1);
|
||||
|
||||
DeliveryMethod deliveryMethod = (DeliveryMethod)data[0];
|
||||
@@ -142,34 +154,27 @@ namespace Barotrauma.Networking
|
||||
bool isServerMessage = (incByte & (byte)PacketHeader.IsServerMessage) != 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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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();
|
||||
outMsg.Write(selfSteamID);
|
||||
outMsg.Write(selfSteamID);
|
||||
outMsg.Write((byte)(PacketHeader.IsConnectionInitializationStep));
|
||||
outMsg.Write(Name);
|
||||
|
||||
@@ -428,6 +434,7 @@ namespace Barotrauma.Networking
|
||||
byte[] msgData = new byte[msg.LengthBytes];
|
||||
msg.PrepareForSending(ref msgData, out bool isCompressed, out int length);
|
||||
msgToSend.Write(selfSteamID);
|
||||
msgToSend.Write(selfSteamID);
|
||||
msgToSend.Write((byte)(isCompressed ? PacketHeader.IsCompressed : PacketHeader.None));
|
||||
msgToSend.Write((UInt16)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;
|
||||
|
||||
@@ -212,6 +212,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
outMsg.Write(autoRestart != null);
|
||||
outMsg.Write(autoRestart ?? false);
|
||||
outMsg.Write(radiationEnabled ?? RadiationEnabled);
|
||||
outMsg.WritePadBits();
|
||||
}
|
||||
|
||||
@@ -274,7 +275,7 @@ namespace Barotrauma.Networking
|
||||
if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) { ToggleSettingsFrame(btn, userData); }
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
new GUIButton(new RectTransform(Vector2.One, settingsFrame.RectTransform), "", style: null)
|
||||
{
|
||||
OnClicked = ToggleSettingsFrame
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Barotrauma
|
||||
|
||||
private GUIButton loadGameButton, deleteMpSaveButton;
|
||||
|
||||
public Action<SubmarineInfo, string, string> StartNewGame;
|
||||
public Action<SubmarineInfo, string, string, CampaignSettings> StartNewGame;
|
||||
public Action<string> LoadGame;
|
||||
|
||||
private enum CategoryFilter { All = 0, Vanilla = 1, Custom = 2 };
|
||||
@@ -40,6 +40,8 @@ namespace Barotrauma
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
public GUITickBox EnableRadiationToggle { get; set; }
|
||||
|
||||
private readonly bool isMultiplayer;
|
||||
|
||||
@@ -171,6 +173,8 @@ namespace Barotrauma
|
||||
string savePath = SaveUtil.CreateSavePath(isMultiplayer ? SaveUtil.SaveType.Multiplayer : SaveUtil.SaveType.Singleplayer, saveNameBox.Text);
|
||||
bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;
|
||||
|
||||
CampaignSettings settings = new CampaignSettings { RadiationEnabled = EnableRadiationToggle?.Selected ?? GameMain.NetLobbyScreen.IsRadiationEnabled() };
|
||||
|
||||
if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages)
|
||||
{
|
||||
if (!hasRequiredContentPackages)
|
||||
@@ -184,7 +188,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (GUIMessageBox.MessageBoxes.Count == 0)
|
||||
{
|
||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
|
||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
|
||||
if (isMultiplayer)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
||||
@@ -204,7 +208,7 @@ namespace Barotrauma
|
||||
|
||||
msgBox.Buttons[0].OnClicked = (button, obj) =>
|
||||
{
|
||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
|
||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
|
||||
if (isMultiplayer)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
||||
@@ -219,7 +223,7 @@ namespace Barotrauma
|
||||
}
|
||||
else
|
||||
{
|
||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text);
|
||||
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
|
||||
if (isMultiplayer)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
|
||||
@@ -230,8 +234,7 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), buttonContainer.RectTransform), "",
|
||||
font: isMultiplayer ? GUI.Style.SmallFont : GUI.Style.Font, textColor: GUI.Style.Green)
|
||||
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)
|
||||
{
|
||||
TextGetter = () =>
|
||||
{
|
||||
@@ -254,6 +257,12 @@ namespace Barotrauma
|
||||
|
||||
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")
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
|
||||
@@ -477,8 +477,8 @@ namespace Barotrauma
|
||||
}
|
||||
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),
|
||||
TextManager.GetWithVariable("missionreward", "[reward]", rewardText), wrap: true);
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), missionTextContent.RectTransform), mission.Description, 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, parseRichText: true);
|
||||
}
|
||||
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)
|
||||
@@ -562,6 +562,11 @@ namespace Barotrauma
|
||||
|
||||
public void SelectTab(CampaignMode.InteractionType tab)
|
||||
{
|
||||
if (Campaign.ShowCampaignUI || (Campaign.ForceMapUI && tab == CampaignMode.InteractionType.Map))
|
||||
{
|
||||
HintManager.OnShowCampaignInterface(tab);
|
||||
}
|
||||
|
||||
selectedTab = tab;
|
||||
for (int i = 0; i < tabs.Length; i++)
|
||||
{
|
||||
|
||||
@@ -1761,9 +1761,9 @@ namespace Barotrauma.CharacterEditor
|
||||
#endif
|
||||
// Add to the selected content package
|
||||
contentPackage.AddFile(configFilePath, ContentType.Character);
|
||||
Barotrauma.IO.Validation.DevException = true;
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
contentPackage.Save(contentPackage.Path);
|
||||
Barotrauma.IO.Validation.DevException = false;
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
DebugConsole.NewMessage(GetCharacterEditorTranslation("ContentPackageSaved").Replace("[path]", contentPackage.Path));
|
||||
|
||||
// Ragdoll
|
||||
|
||||
@@ -882,7 +882,7 @@ namespace Barotrauma
|
||||
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;
|
||||
|
||||
gameMode.SpawnOutpost = true;
|
||||
|
||||
@@ -296,7 +296,7 @@ namespace Barotrauma
|
||||
subInfo ??= SubmarineInfo.SavedSubmarines.GetRandom(s =>
|
||||
s.IsPlayer && !s.HasTag(SubmarineTag.Shuttle) &&
|
||||
!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.GameMode as TestGameMode).OnRoundEnd = () =>
|
||||
{
|
||||
|
||||
@@ -1043,7 +1043,7 @@ namespace Barotrauma
|
||||
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;
|
||||
|
||||
@@ -1082,7 +1082,7 @@ namespace Barotrauma
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -1134,6 +1134,7 @@ namespace Barotrauma
|
||||
(int)(campaignSetupUI.StartButton.TextBlock.TextSize.X * 1.5f),
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,8 @@ namespace Barotrauma
|
||||
|
||||
private GUIComponent jobVariantTooltip;
|
||||
|
||||
private SubmarinePreview submarinePreview;
|
||||
|
||||
private readonly GUITextBox chatInput;
|
||||
private readonly GUITextBox serverLogFilter;
|
||||
public GUITextBox ChatInput
|
||||
@@ -41,6 +43,8 @@ namespace Barotrauma
|
||||
|
||||
private readonly GUIScrollBar levelDifficultyScrollBar;
|
||||
|
||||
private readonly GUITickBox radiationEnabledTickBox;
|
||||
|
||||
private readonly GUIButton[] traitorProbabilityButtons;
|
||||
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();
|
||||
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);
|
||||
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 =
|
||||
!CampaignFrame.Visible && !CampaignSetupFrame.Visible && 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());
|
||||
}
|
||||
|
||||
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),
|
||||
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,
|
||||
color: ((chatBox.CountChildren % 2) == 0) ? Color.Transparent : Color.Black * 0.1f,
|
||||
wrap: true, font: GUI.SmallFont)
|
||||
|
||||
@@ -43,6 +43,13 @@ namespace Barotrauma
|
||||
private Dictionary<ulong, Steamworks.Ugc.Item?> pendingWorkshopDownloads = null;
|
||||
private string autoConnectName; private string autoConnectEndpoint;
|
||||
|
||||
private enum TernaryOption
|
||||
{
|
||||
Any,
|
||||
Enabled,
|
||||
Disabled
|
||||
}
|
||||
|
||||
private class FriendInfo
|
||||
{
|
||||
public UInt64 SteamID;
|
||||
@@ -146,16 +153,19 @@ namespace Barotrauma
|
||||
private GUITickBox filterFull;
|
||||
private GUITickBox filterEmpty;
|
||||
private GUITickBox filterWhitelisted;
|
||||
private GUITickBox filterFriendlyFire;
|
||||
private GUITickBox filterKarma;
|
||||
private GUITickBox filterTraitor;
|
||||
private GUITickBox filterModded;
|
||||
private GUITickBox filterVoip;
|
||||
private Dictionary<string, GUIDropDown> ternaryFilters;
|
||||
private Dictionary<string, GUITickBox> filterTickBoxes;
|
||||
private Dictionary<string, GUITickBox> playStyleTickBoxes;
|
||||
private Dictionary<string, GUITickBox> gameModeTickBoxes;
|
||||
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 GUIButton serverPreviewToggleButton;
|
||||
@@ -173,6 +183,49 @@ namespace Barotrauma
|
||||
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()
|
||||
{
|
||||
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);
|
||||
|
||||
ternaryFilters = new Dictionary<string, GUIDropDown>();
|
||||
filterTickBoxes = new Dictionary<string, GUITickBox>();
|
||||
|
||||
filterSameVersion = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("FilterSameVersion"))
|
||||
@@ -382,40 +436,11 @@ namespace Barotrauma
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
filterKarma = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), TextManager.Get("servertag.karma.true"))
|
||||
{
|
||||
UserData = TextManager.Get("servertag.karma.true"),
|
||||
OnSelected = (tickBox) => { FilterServers(); return true; }
|
||||
};
|
||||
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);
|
||||
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "karma", (value) => { filterKarmaValue = value; });
|
||||
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "traitors", (value) => { filterTraitorValue = value; });
|
||||
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "friendlyfire", (value) => { filterFriendlyFireValue = value; });
|
||||
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "voip", (value) => { filterVoipValue = value; });
|
||||
AddTernaryFilter(filters.Content.RectTransform, elementHeight, "modded", (value) => { filterModdedValue = value; });
|
||||
|
||||
// Play Style Selection
|
||||
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
|
||||
{
|
||||
bool incompatible =
|
||||
(!serverInfo.ContentPackageHashes.Any() && serverInfo.ContentPackagesMatch()) ||
|
||||
(serverInfo.ContentPackageHashes.Any() && !serverInfo.ContentPackagesMatch()) ||
|
||||
(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 =
|
||||
serverInfo.OwnerVerified &&
|
||||
serverInfo.ServerName.Contains(searchBox.Text, StringComparison.OrdinalIgnoreCase) &&
|
||||
@@ -1089,11 +1120,11 @@ namespace Barotrauma
|
||||
(!filterEmpty.Selected || serverInfo.PlayerCount > 0) &&
|
||||
(!filterWhitelisted.Selected || serverInfo.UsingWhiteList == true) &&
|
||||
(!filterOffensive.Selected || !ForbiddenWordFilter.IsForbidden(serverInfo.ServerName)) &&
|
||||
(!filterKarma.Selected || serverInfo.KarmaEnabled == true) &&
|
||||
(!filterFriendlyFire.Selected || serverInfo.FriendlyFireEnabled == false) &&
|
||||
(!filterTraitor.Selected || serverInfo.TraitorsEnabled == YesNoMaybe.Yes || serverInfo.TraitorsEnabled == YesNoMaybe.Maybe) &&
|
||||
(!filterVoip.Selected || serverInfo.VoipEnabled == false) &&
|
||||
(!filterModded.Selected || serverInfo.GetPlayStyleTags().Any(t => t.Contains("modded.true"))) &&
|
||||
karmaFilterPassed &&
|
||||
friendlyFireFilterPassed &&
|
||||
traitorsFilterPassed &&
|
||||
voipFilterPassed &&
|
||||
moddedFilterPassed &&
|
||||
((selectedTab == ServerListTab.All && (serverInfo.LobbyID != 0 || !string.IsNullOrWhiteSpace(serverInfo.Port))) ||
|
||||
(selectedTab == ServerListTab.Recent && serverInfo.Recent) ||
|
||||
(selectedTab == ServerListTab.Favorites && serverInfo.Favorite));
|
||||
@@ -2334,6 +2365,10 @@ namespace Barotrauma
|
||||
{
|
||||
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)
|
||||
@@ -2344,6 +2379,15 @@ namespace Barotrauma
|
||||
{
|
||||
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; }
|
||||
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 &&
|
||||
GameMain.VanillaContent.GetFilesOfType(ContentType.Submarine).Any(s => Path.GetFullPath(s) == subPath))
|
||||
GameMain.VanillaContent.Files.Any(s => Path.GetFullPath(s.Path) == subPath))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -870,7 +870,7 @@ namespace Barotrauma
|
||||
|
||||
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.GameMode as TestGameMode).OnRoundEnd = () =>
|
||||
{
|
||||
@@ -897,6 +897,8 @@ namespace Barotrauma
|
||||
|
||||
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)
|
||||
{
|
||||
if (!ep.Category.HasFlag(category)) { continue; }
|
||||
@@ -907,13 +909,14 @@ namespace Barotrauma
|
||||
}
|
||||
entityLists[category + ep.Subcategory].Add(ep);
|
||||
categoryKeys[category + ep.Subcategory] = category;
|
||||
string categoryName = TextManager.Get("subcategory." + ep.Subcategory, returnNull: true) ?? ep.Subcategory;
|
||||
if (categoryName != null)
|
||||
string subcategoryName = TextManager.Get("subcategory." + ep.Subcategory, returnNull: true) ?? ep.Subcategory;
|
||||
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;
|
||||
int entitiesPerRow = (int)Math.Ceiling(categorizedEntityList.Content.Rect.Width / Math.Max(125 * GUI.Scale, 60));
|
||||
foreach (string categoryKey in entityLists.Keys)
|
||||
@@ -926,19 +929,33 @@ namespace Barotrauma
|
||||
|
||||
new GUIFrame(new RectTransform(Vector2.One, categoryFrame.RectTransform), style: "HorizontalLine");
|
||||
|
||||
string categoryName = entityLists[categoryKey].First().Subcategory;
|
||||
categoryName = string.IsNullOrEmpty(categoryName) ?
|
||||
TextManager.Get("mapentitycategory.misc") :
|
||||
(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)
|
||||
string categoryName = TextManager.Get("MapEntityCategory." + entityLists[categoryKey].First().Category);
|
||||
string subCategoryName = entityLists[categoryKey].First().Subcategory;
|
||||
if (string.IsNullOrEmpty(subCategoryName))
|
||||
{
|
||||
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),
|
||||
style: null,
|
||||
@@ -959,7 +976,6 @@ namespace Barotrauma
|
||||
#if !DEBUG
|
||||
if (ep.HideInMenus) { continue; }
|
||||
#endif
|
||||
|
||||
CreateEntityElement(ep, entitiesPerRow, entityListInner.Content);
|
||||
}
|
||||
|
||||
@@ -976,6 +992,9 @@ namespace Barotrauma
|
||||
|
||||
foreach (MapEntityPrefab ep in MapEntityPrefab.List)
|
||||
{
|
||||
#if !DEBUG
|
||||
if (ep.HideInMenus) { continue; }
|
||||
#endif
|
||||
CreateEntityElement(ep, entitiesPerRow, allEntityList.Content);
|
||||
}
|
||||
}
|
||||
@@ -1354,7 +1373,7 @@ namespace Barotrauma
|
||||
{
|
||||
try
|
||||
{
|
||||
Barotrauma.IO.Validation.DevException = true;
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
TimeSpan time = DateTime.UtcNow - DateTime.MinValue;
|
||||
string filePath = Path.Combine(autoSavePath, $"AutoSave_{(ulong)time.TotalMilliseconds}.sub");
|
||||
SaveUtil.CompressStringToFile(filePath, doc.ToString());
|
||||
@@ -1390,7 +1409,7 @@ namespace Barotrauma
|
||||
}
|
||||
});
|
||||
|
||||
Barotrauma.IO.Validation.DevException = false;
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
CrossThread.RequestExecutionOnMainThread(DisplayAutoSavePrompt);
|
||||
}
|
||||
catch (Exception e)
|
||||
@@ -1558,9 +1577,9 @@ namespace Barotrauma
|
||||
msgBox.Buttons[0].OnClicked = (bt, userdata) =>
|
||||
{
|
||||
contentPackage.AddFile(savePath, ContentType.OutpostModule);
|
||||
Barotrauma.IO.Validation.DevException = true;
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = true;
|
||||
contentPackage.Save(contentPackage.Path, reload: false);
|
||||
Barotrauma.IO.Validation.DevException = false;
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
msgBox.Close();
|
||||
return true;
|
||||
};
|
||||
@@ -1635,7 +1654,7 @@ namespace Barotrauma
|
||||
|
||||
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)
|
||||
{
|
||||
bool savePreviewImage = true;
|
||||
@@ -1655,7 +1674,7 @@ namespace Barotrauma
|
||||
{
|
||||
Submarine.MainSub.SaveAs(savePath);
|
||||
}
|
||||
Barotrauma.IO.Validation.DevException = false;
|
||||
Barotrauma.IO.Validation.SkipValidationInDebugBuilds = false;
|
||||
|
||||
Submarine.MainSub.CheckForErrors();
|
||||
|
||||
@@ -4695,6 +4714,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
graphics.Clear(backgroundColor);
|
||||
|
||||
ImageManager.Draw(spriteBatch, cam);
|
||||
|
||||
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.NonPremultiplied, transformMatrix: cam.Transform);
|
||||
|
||||
@@ -63,8 +63,18 @@ namespace Barotrauma.Sounds
|
||||
ALFormat = reader.Channels == 1 ? Al.FormatMono16 : Al.FormatStereo16;
|
||||
SampleRate = reader.SampleRate;
|
||||
|
||||
if (Buffers != null && SoundBuffers.BuffersGenerated < SoundBuffers.MaxBuffers)
|
||||
{
|
||||
Buffers.RequestAlBuffers(); FillBuffers();
|
||||
}
|
||||
}
|
||||
|
||||
public override void FillBuffers()
|
||||
{
|
||||
if (!Stream)
|
||||
{
|
||||
reader.DecodedPosition = 0;
|
||||
|
||||
int bufferSize = (int)reader.TotalSamples * reader.Channels;
|
||||
|
||||
float[] floatBuffer = new float[bufferSize];
|
||||
@@ -86,7 +96,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
||||
|
||||
Al.BufferData(ALBuffer, ALFormat, shortBuffer,
|
||||
Al.BufferData(Buffers.AlBuffer, ALFormat, shortBuffer,
|
||||
readSamples * sizeof(short), SampleRate);
|
||||
|
||||
int alError = Al.GetError();
|
||||
@@ -99,7 +109,7 @@ namespace Barotrauma.Sounds
|
||||
|
||||
CastBuffer(floatBuffer, shortBuffer, readSamples);
|
||||
|
||||
Al.BufferData(ALMuffledBuffer, ALFormat, shortBuffer,
|
||||
Al.BufferData(Buffers.AlMuffledBuffer, ALFormat, shortBuffer,
|
||||
readSamples * sizeof(short), SampleRate);
|
||||
|
||||
alError = Al.GetError();
|
||||
|
||||
@@ -52,16 +52,10 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
}
|
||||
|
||||
private uint alBuffer;
|
||||
public uint ALBuffer
|
||||
private SoundBuffers buffers;
|
||||
public SoundBuffers Buffers
|
||||
{
|
||||
get { return !Stream ? alBuffer : 0; }
|
||||
}
|
||||
|
||||
private uint alMuffledBuffer;
|
||||
public uint ALMuffledBuffer
|
||||
{
|
||||
get { return !Stream ? alMuffledBuffer : 0; }
|
||||
get { return !Stream ? buffers : null; }
|
||||
}
|
||||
|
||||
public int ALFormat
|
||||
@@ -169,69 +163,20 @@ namespace Barotrauma.Sounds
|
||||
{
|
||||
if (!Stream)
|
||||
{
|
||||
Al.GenBuffer(out alBuffer);
|
||||
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!");
|
||||
}
|
||||
buffers = new SoundBuffers(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
alBuffer = 0;
|
||||
buffers = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void FillBuffers() { }
|
||||
|
||||
public virtual void DeleteALBuffers()
|
||||
{
|
||||
Owner.KillChannels(this);
|
||||
if (alBuffer != 0)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
buffers?.Dispose();
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
|
||||
@@ -334,7 +334,11 @@ namespace Barotrauma.Sounds
|
||||
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();
|
||||
if (alError != Al.NoError)
|
||||
@@ -506,17 +510,26 @@ namespace Barotrauma.Sounds
|
||||
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!");
|
||||
}
|
||||
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);
|
||||
alError = Al.GetError();
|
||||
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));
|
||||
@@ -528,7 +541,7 @@ namespace Barotrauma.Sounds
|
||||
}
|
||||
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);
|
||||
int alError = Al.GetError();
|
||||
if (alError != Al.NoError)
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace Barotrauma.Sounds
|
||||
private readonly SoundSourcePool[] sourcePools;
|
||||
|
||||
private readonly List<Sound> loadedSounds;
|
||||
public IReadOnlyList<Sound> LoadedSounds => loadedSounds;
|
||||
|
||||
private readonly SoundChannel[][] playingChannels = new SoundChannel[2][];
|
||||
private readonly object threadDeathMutex = new object();
|
||||
|
||||
|
||||
@@ -172,22 +172,22 @@ namespace Barotrauma
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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; }
|
||||
//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)
|
||||
{
|
||||
if (Texture == null) { return; }
|
||||
|
||||
@@ -5,14 +5,14 @@ namespace Barotrauma
|
||||
{
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -100,38 +100,6 @@ namespace Barotrauma
|
||||
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>
|
||||
/// Convert a RGB value into a HSV value.
|
||||
/// </summary>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.1300.0.0</Version>
|
||||
<Version>0.1300.0.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.1300.0.0</Version>
|
||||
<Version>0.1300.0.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma</Product>
|
||||
<Version>0.1300.0.0</Version>
|
||||
<Version>0.1300.0.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>Barotrauma</AssemblyName>
|
||||
|
||||
@@ -1,62 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- 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
|
||||
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. -->
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!--
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
</assembly>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||
<security>
|
||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- A list of the Windows versions that this application has been tested on
|
||||
and is designed to work with. Uncomment the appropriate elements
|
||||
and Windows will automatically select the most compatible environment. -->
|
||||
|
||||
<!-- Windows Vista -->
|
||||
<!--<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />-->
|
||||
|
||||
<!-- Windows 7 -->
|
||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
||||
|
||||
<!-- Windows 8 -->
|
||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
||||
|
||||
<!-- Windows 8.1 -->
|
||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||
|
||||
<!-- Windows 10 -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<!-- 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
|
||||
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. -->
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/pm</dpiAware>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
|
||||
<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->
|
||||
<!--
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="Microsoft.Windows.Common-Controls"
|
||||
version="6.0.0.0"
|
||||
processorArchitecture="*"
|
||||
publicKeyToken="6595b64144ccf1df"
|
||||
language="*"
|
||||
/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
-->
|
||||
|
||||
</assembly>
|
||||
|
||||
0
Barotrauma/BarotraumaClient/libSDL2-2.0.0.dylib
Normal file → Executable file
0
Barotrauma/BarotraumaClient/libSDL2-2.0.0.dylib
Normal file → Executable file
0
Barotrauma/BarotraumaClient/libfreetype6.dylib
Normal file → Executable file
0
Barotrauma/BarotraumaClient/libfreetype6.dylib
Normal file → Executable file
0
Barotrauma/BarotraumaClient/libwebm_mem_playback_x64.dylib
Normal file → Executable file
0
Barotrauma/BarotraumaClient/libwebm_mem_playback_x64.dylib
Normal file → Executable file
@@ -1,139 +1,139 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1300.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||
<Configurations>Debug;Release;Unstable</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>DEBUG;TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DefineConstants>TRACE;DEBUG;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||
<Content Include="DedicatedServer.exe" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||
<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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||
<PropertyGroup>
|
||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- write the hash to the temp file.-->
|
||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||
</Exec>
|
||||
<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 > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||
|
||||
<!-- read the version into the GitVersion itemGroup-->
|
||||
<ReadLinesFromFile File="$(VerFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildHash>@(GitVersion)</BuildHash>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- read the branch into the GitBranch itemGroup-->
|
||||
<ReadLinesFromFile File="$(BranchFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||
<PropertyGroup>
|
||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||
</PropertyGroup>
|
||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||
<ItemGroup>
|
||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||
</ItemGroup>
|
||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||
<ItemGroup>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitRevision</_Parameter1>
|
||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitBranch</_Parameter1>
|
||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>ProjectDir</_Parameter1>
|
||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
</ItemGroup>
|
||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1300.0.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||
<Configurations>Debug;Release;Unstable</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>DEBUG;TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DefineConstants>TRACE;DEBUG;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;LINUX;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||
<DefineConstants>TRACE;SERVER;LINUX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Linux\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||
<Content Include="DedicatedServer.exe" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||
<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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||
<PropertyGroup>
|
||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- write the hash to the temp file.-->
|
||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||
</Exec>
|
||||
<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 > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||
|
||||
<!-- read the version into the GitVersion itemGroup-->
|
||||
<ReadLinesFromFile File="$(VerFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildHash>@(GitVersion)</BuildHash>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- read the branch into the GitBranch itemGroup-->
|
||||
<ReadLinesFromFile File="$(BranchFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||
<PropertyGroup>
|
||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||
</PropertyGroup>
|
||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||
<ItemGroup>
|
||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||
</ItemGroup>
|
||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||
<ItemGroup>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitRevision</_Parameter1>
|
||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitBranch</_Parameter1>
|
||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>ProjectDir</_Parameter1>
|
||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
</ItemGroup>
|
||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -1,152 +1,152 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1300.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||
<ReleaseVersion>0.9.0.0</ReleaseVersion>
|
||||
<Configurations>Debug;Release;Unstable</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;DEBUG;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\DebugMac</OutputPath>
|
||||
<ConsolePause>true</ConsolePause>
|
||||
<CheckForOverflowUnderflow></CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DefineConstants>TRACE;DEBUG;SERVER;OSX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugType></DebugType>
|
||||
<OutputPath>..\bin\ReleaseMac</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0;UNSTABLE</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugType />
|
||||
<OutputPath>..\bin\ReleaseMac</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM;UNSTABLE</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||
<Content Remove="..\BarotraumaShared\libsteam_api64.dylib" />
|
||||
<Content Remove="..\BarotraumaShared\libsteam_api64.so" />
|
||||
<Content Remove="DedicatedServer.exe" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||
<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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||
<ItemGroup>
|
||||
<None Include="..\BarotraumaShared\libsteam_api64.dylib">
|
||||
<Link>libsteam_api64.dylib</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||
<PropertyGroup>
|
||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- write the hash to the temp file.-->
|
||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||
</Exec>
|
||||
<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 > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||
|
||||
<!-- read the version into the GitVersion itemGroup-->
|
||||
<ReadLinesFromFile File="$(VerFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildHash>@(GitVersion)</BuildHash>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- read the branch into the GitBranch itemGroup-->
|
||||
<ReadLinesFromFile File="$(BranchFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||
<PropertyGroup>
|
||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||
</PropertyGroup>
|
||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||
<ItemGroup>
|
||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||
</ItemGroup>
|
||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||
<ItemGroup>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitRevision</_Parameter1>
|
||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitBranch</_Parameter1>
|
||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>ProjectDir</_Parameter1>
|
||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
</ItemGroup>
|
||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1300.0.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||
<ReleaseVersion>0.9.0.0</ReleaseVersion>
|
||||
<Configurations>Debug;Release;Unstable</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;DEBUG;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\DebugMac</OutputPath>
|
||||
<ConsolePause>true</ConsolePause>
|
||||
<CheckForOverflowUnderflow></CheckForOverflowUnderflow>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DefineConstants>TRACE;DEBUG;SERVER;OSX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugType></DebugType>
|
||||
<OutputPath>..\bin\ReleaseMac</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;USE_STEAM;RELEASE;NETCOREAPP;NETCOREAPP3_0;UNSTABLE</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<DebugType />
|
||||
<OutputPath>..\bin\ReleaseMac</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||
<DefineConstants>TRACE;SERVER;OSX;X64;USE_STEAM;UNSTABLE</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Mac\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||
<Content Remove="..\BarotraumaShared\libsteam_api64.dylib" />
|
||||
<Content Remove="..\BarotraumaShared\libsteam_api64.so" />
|
||||
<Content Remove="DedicatedServer.exe" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||
<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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||
<ItemGroup>
|
||||
<None Include="..\BarotraumaShared\libsteam_api64.dylib">
|
||||
<Link>libsteam_api64.dylib</Link>
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||
<PropertyGroup>
|
||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- write the hash to the temp file.-->
|
||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||
</Exec>
|
||||
<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 > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||
|
||||
<!-- read the version into the GitVersion itemGroup-->
|
||||
<ReadLinesFromFile File="$(VerFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildHash>@(GitVersion)</BuildHash>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- read the branch into the GitBranch itemGroup-->
|
||||
<ReadLinesFromFile File="$(BranchFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||
<PropertyGroup>
|
||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||
</PropertyGroup>
|
||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||
<ItemGroup>
|
||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||
</ItemGroup>
|
||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||
<ItemGroup>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitRevision</_Parameter1>
|
||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitBranch</_Parameter1>
|
||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>ProjectDir</_Parameter1>
|
||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
</ItemGroup>
|
||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -26,6 +26,7 @@ namespace Barotrauma
|
||||
{
|
||||
msg.Write(ID);
|
||||
msg.Write(Name);
|
||||
msg.Write(OriginalName);
|
||||
msg.Write((byte)Gender);
|
||||
msg.Write((byte)Race);
|
||||
msg.Write((byte)HeadSpriteId);
|
||||
|
||||
@@ -17,6 +17,8 @@ namespace Barotrauma
|
||||
foreach (Character character in characters)
|
||||
{
|
||||
character.WriteSpawnData(msg, character.ID, restrictMessageSize: false);
|
||||
msg.Write(requireKill.Contains(character));
|
||||
msg.Write(requireRescue.Contains(character));
|
||||
msg.Write((ushort)characterItems[character].Count());
|
||||
foreach (Item item in characterItems[character])
|
||||
{
|
||||
|
||||
@@ -32,11 +32,11 @@ namespace Barotrauma
|
||||
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; }
|
||||
|
||||
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);
|
||||
SaveUtil.SaveGame(GameMain.GameSession.SavePath);
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Barotrauma
|
||||
DebugConsole.ShowQuestionPrompt("Enter a save name for the campaign:", (string 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
|
||||
@@ -667,13 +667,24 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
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;
|
||||
if (fireCharacter) { firedIdentifier = msg.ReadInt32(); }
|
||||
|
||||
Location location = map?.CurrentLocation;
|
||||
|
||||
List<CharacterInfo> hiredCharacters = new List<CharacterInfo>();
|
||||
CharacterInfo firedCharacter = null;
|
||||
|
||||
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 (validateHires)
|
||||
{
|
||||
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>();
|
||||
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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -721,25 +764,39 @@ namespace Barotrauma
|
||||
}
|
||||
location.HireManager.PendingHires = pendingHireInfos;
|
||||
}
|
||||
|
||||
location.HireManager.AvailableCharacters.ForEachMod(info =>
|
||||
{
|
||||
if(!location.HireManager.PendingHires.Contains(info))
|
||||
{
|
||||
location.HireManager.RenameCharacter(info, info.OriginalName);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// bounce back
|
||||
SendCrewState(validateHires, firedCharacter);
|
||||
if (renameCharacter && existingCrewMember)
|
||||
{
|
||||
SendCrewState(hiredCharacters, (renamedIdentifier, newName), firedCharacter);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendCrewState(hiredCharacters, default, firedCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the clients of the current bot situation like syncing pending and available hires
|
||||
/// available hires are also synced
|
||||
/// </summary>
|
||||
/// <param name="validateHires">When set to true notifies the clients that the hires have been validated.</param>
|
||||
/// <param name="firedCharacter">When not null will inform the clients that his character has been fired.</param>
|
||||
/// <param name="hiredCharacters">Inform the clients that these characters have been hired.</param>
|
||||
/// <param name="firedCharacter">Inform the clients that this character has been fired.</param>
|
||||
/// <remarks>
|
||||
/// 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
|
||||
/// their available hires are different from the server.
|
||||
/// </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> pendingHires = new List<CharacterInfo>();
|
||||
@@ -765,10 +822,26 @@ namespace Barotrauma
|
||||
msg.Write((ushort)pendingHires.Count);
|
||||
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);
|
||||
if (firedCharacter != null) { msg.Write(firedCharacter.GetIdentifier()); }
|
||||
@@ -786,6 +859,7 @@ namespace Barotrauma
|
||||
new XAttribute("purchasedhullrepairs", PurchasedHullRepairs),
|
||||
new XAttribute("purchaseditemrepairs", PurchasedItemRepairs),
|
||||
new XAttribute("cheatsenabled", CheatsEnabled));
|
||||
modeElement.Add(Settings.Save());
|
||||
CampaignMetadata?.Save(modeElement);
|
||||
Map.Save(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;
|
||||
if (IPAddress.IsLoopback(IP)) { return false; }
|
||||
var bannedPlayer = bannedPlayers.Find(bp =>
|
||||
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;
|
||||
return bannedPlayer != null;
|
||||
}
|
||||
@@ -166,6 +167,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
public void BanPlayer(string name, ulong steamID, string reason, TimeSpan? duration)
|
||||
{
|
||||
if (steamID == 0) { return; }
|
||||
BanPlayer(name, "", steamID, reason, duration);
|
||||
}
|
||||
|
||||
|
||||
@@ -284,6 +284,7 @@ namespace Barotrauma.Networking
|
||||
newClient.Connection = connection;
|
||||
newClient.Connection.Status = NetworkConnectionStatus.Connected;
|
||||
newClient.SteamID = connection.SteamID;
|
||||
newClient.OwnerSteamID = connection.OwnerSteamID;
|
||||
newClient.Language = connection.Language;
|
||||
ConnectedClients.Add(newClient);
|
||||
|
||||
@@ -308,12 +309,13 @@ namespace Barotrauma.Networking
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -475,12 +477,14 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
else if (isCrewDead && respawnManager == null)
|
||||
{
|
||||
#if !DEBUG
|
||||
if (endRoundTimer <= 0.0f)
|
||||
{
|
||||
SendChatMessage(TextManager.GetWithVariable("CrewDeadNoRespawns", "[time]", "60"), ChatMessageType.Server);
|
||||
}
|
||||
endRoundDelay = 60.0f;
|
||||
endRoundTimer += deltaTime;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -752,6 +756,7 @@ namespace Barotrauma.Networking
|
||||
string seed = inc.ReadString();
|
||||
string subName = inc.ReadString();
|
||||
string subHash = inc.ReadString();
|
||||
CampaignSettings settings = new CampaignSettings(inc);
|
||||
|
||||
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);
|
||||
if (connectedClient.HasPermission(ClientPermissions.SelectMode) || connectedClient.HasPermission(ClientPermissions.ManageCampaign))
|
||||
{
|
||||
MultiPlayerCampaign.StartNewCampaign(localSavePath, matchingSub.FilePath, seed);
|
||||
MultiPlayerCampaign.StartNewCampaign(localSavePath, matchingSub.FilePath, seed, settings);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string saveName = inc.ReadString();
|
||||
@@ -1853,6 +1858,8 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
outmsg.Write(autoRestartTimerRunning ? serverSettings.AutoRestartTimer : 0.0f);
|
||||
}
|
||||
|
||||
outmsg.Write(serverSettings.RadiationEnabled);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
private IEnumerable<object> StartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode)
|
||||
private IEnumerable<object> StartGame(SubmarineInfo selectedSub, SubmarineInfo selectedShuttle, GameModePreset selectedMode, CampaignSettings settings)
|
||||
{
|
||||
entityEventManager.Clear();
|
||||
|
||||
@@ -2067,7 +2074,7 @@ namespace Barotrauma.Networking
|
||||
//don't instantiate a new gamesession if we're playing a campaign
|
||||
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);
|
||||
@@ -2716,6 +2723,10 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
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)
|
||||
@@ -2735,6 +2746,10 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
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}";
|
||||
if (!string.IsNullOrWhiteSpace(reason))
|
||||
@@ -2784,7 +2799,7 @@ namespace Barotrauma.Networking
|
||||
client.HasSpawned = 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(reason))
|
||||
{
|
||||
@@ -3747,7 +3762,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -3826,6 +3841,7 @@ namespace Barotrauma.Networking
|
||||
public string Name;
|
||||
public string EndPoint;
|
||||
public UInt64 SteamID;
|
||||
public UInt64 OwnerSteamID;
|
||||
public float Karma;
|
||||
public int KarmaKickCount;
|
||||
public readonly List<Client> KickVoters = new List<Client>();
|
||||
@@ -3835,6 +3851,7 @@ namespace Barotrauma.Networking
|
||||
Name = c.Name;
|
||||
EndPoint = c.Connection?.EndPointString ?? "";
|
||||
SteamID = c.SteamID;
|
||||
OwnerSteamID = c.OwnerSteamID;
|
||||
}
|
||||
|
||||
public bool MatchesClient(Client c)
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace Barotrauma.Networking
|
||||
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
|
||||
inc.SenderConnection.Deny(DisconnectReason.Banned.ToString() + "/ " + banReason);
|
||||
@@ -233,7 +233,7 @@ namespace Barotrauma.Networking
|
||||
return;
|
||||
}
|
||||
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);
|
||||
return;
|
||||
@@ -308,7 +308,8 @@ namespace Barotrauma.Networking
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
@@ -316,6 +317,7 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (status == Steamworks.AuthResponse.OK)
|
||||
{
|
||||
pendingClient.OwnerSteamID = ownerID;
|
||||
pendingClient.InitializationStep = serverSettings.HasPassword ? ConnectionInitialization.Password : ConnectionInitialization.ContentPackageOrder;
|
||||
pendingClient.UpdateTime = Timing.TotalTime;
|
||||
}
|
||||
@@ -452,7 +454,7 @@ namespace Barotrauma.Networking
|
||||
pendingClient.AuthSessionStarted = true;
|
||||
}
|
||||
}
|
||||
else //TODO: could remove since this seems impossible
|
||||
else
|
||||
{
|
||||
if (pendingClient.SteamID != steamId)
|
||||
{
|
||||
|
||||
@@ -49,6 +49,16 @@ namespace Barotrauma.Networking
|
||||
Connection.SetSteamIDIfUnknown(value ?? 0);
|
||||
}
|
||||
}
|
||||
private UInt64? ownerSteamId;
|
||||
public UInt64? OwnerSteamID
|
||||
{
|
||||
get { return ownerSteamId; }
|
||||
set
|
||||
{
|
||||
ownerSteamId = value;
|
||||
Connection.SetOwnerSteamIDIfUnknown(value ?? 0);
|
||||
}
|
||||
}
|
||||
public Int32? PasswordSalt;
|
||||
public bool AuthSessionStarted;
|
||||
|
||||
@@ -59,6 +69,7 @@ namespace Barotrauma.Networking
|
||||
InitializationStep = ConnectionInitialization.SteamTicketAndVersion;
|
||||
Retries = 0;
|
||||
SteamID = null;
|
||||
OwnerSteamID = null;
|
||||
PasswordSalt = null;
|
||||
UpdateTime = Timing.TotalTime + Timing.Step * 3.0;
|
||||
TimeOut = NetworkConnection.TimeoutThreshold;
|
||||
@@ -107,8 +118,8 @@ namespace Barotrauma.Networking
|
||||
RemovePendingClient(pendingClient, DisconnectReason.InvalidVersion,
|
||||
$"DisconnectMessage.InvalidVersion~[version]={GameMain.Version}~[clientversion]={version}");
|
||||
|
||||
GameServer.Log(name + " (" + pendingClient.SteamID.ToString() + ") 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);
|
||||
GameServer.Log($"{name} ({steamId}) couldn't join the server (incompatible game version)", ServerLog.MessageType.Error);
|
||||
DebugConsole.NewMessage($"{name} ({steamId}) couldn't join the server (incompatible game version)", Microsoft.Xna.Framework.Color.Red);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,7 +130,7 @@ namespace Barotrauma.Networking
|
||||
if (nameTaken != null)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -172,6 +183,7 @@ namespace Barotrauma.Networking
|
||||
else if (pendingClient.Connection is SteamP2PConnection s)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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;
|
||||
return false;
|
||||
@@ -273,6 +286,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
Steam.SteamManager.StopAuthSession(pendingClient.SteamID.Value);
|
||||
pendingClient.SteamID = null;
|
||||
pendingClient.OwnerSteamID = null;
|
||||
pendingClient.AuthSessionStarted = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,7 @@ namespace Barotrauma.Networking
|
||||
if (!started) { return; }
|
||||
|
||||
UInt64 senderSteamId = inc.ReadUInt64();
|
||||
UInt64 ownerSteamId = inc.ReadUInt64();
|
||||
|
||||
byte incByte = inc.ReadByte();
|
||||
bool isCompressed = (incByte & (byte)PacketHeader.IsCompressed) != 0;
|
||||
@@ -145,7 +146,9 @@ namespace Barotrauma.Networking
|
||||
pendingClient?.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)
|
||||
{
|
||||
@@ -181,6 +184,10 @@ namespace Barotrauma.Networking
|
||||
|
||||
if (pendingClient != null)
|
||||
{
|
||||
if (ownerSteamId != 0)
|
||||
{
|
||||
pendingClient.Connection.SetOwnerSteamIDIfUnknown(ownerSteamId);
|
||||
}
|
||||
ReadConnectionInitializationStep(pendingClient, new ReadOnlyMessage(inc.Buffer, false, inc.BytePosition, inc.LengthBytes - inc.BytePosition, null));
|
||||
}
|
||||
else
|
||||
@@ -223,6 +230,7 @@ namespace Barotrauma.Networking
|
||||
{
|
||||
Language = GameMain.Config.Language
|
||||
};
|
||||
OwnerConnection.SetOwnerSteamIDIfUnknown(OwnerSteamID);
|
||||
|
||||
OnInitializationComplete?.Invoke(OwnerConnection);
|
||||
}
|
||||
|
||||
@@ -159,6 +159,8 @@ namespace Barotrauma.Networking
|
||||
AutoRestart = autoRestart;
|
||||
}
|
||||
|
||||
RadiationEnabled = incMsg.ReadBoolean();
|
||||
|
||||
changed |= true;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace Barotrauma
|
||||
private SubmarineInfo selectedSub;
|
||||
private SubmarineInfo selectedShuttle;
|
||||
|
||||
public bool RadiationEnabled = true;
|
||||
|
||||
public SubmarineInfo SelectedSub
|
||||
{
|
||||
get { return selectedSub; }
|
||||
|
||||
@@ -1,147 +1,147 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1300.0.0</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||
<Configurations>Debug;Release;Unstable</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>DEBUG;TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DefineConstants>TRACE;DEBUG;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DefineConstants>TRACE;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||
<DefineConstants>TRACE;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||
<Compile Remove="..\BarotraumaShared\SharedSource\Networking\Primitives\Message\WrapperMsg.cs" />
|
||||
<Content Remove="DedicatedServer.exe" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||
<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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||
<PropertyGroup>
|
||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- write the hash to the temp file.-->
|
||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||
</Exec>
|
||||
<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 > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||
|
||||
<!-- read the version into the GitVersion itemGroup-->
|
||||
<ReadLinesFromFile File="$(VerFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildHash>@(GitVersion)</BuildHash>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- read the branch into the GitBranch itemGroup-->
|
||||
<ReadLinesFromFile File="$(BranchFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||
<PropertyGroup>
|
||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||
</PropertyGroup>
|
||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||
<ItemGroup>
|
||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||
</ItemGroup>
|
||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||
<ItemGroup>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitRevision</_Parameter1>
|
||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitBranch</_Parameter1>
|
||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>ProjectDir</_Parameter1>
|
||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
</ItemGroup>
|
||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<RootNamespace>Barotrauma</RootNamespace>
|
||||
<Authors>FakeFish, Undertow Games</Authors>
|
||||
<Product>Barotrauma Dedicated Server</Product>
|
||||
<Version>0.1300.0.1</Version>
|
||||
<Copyright>Copyright © FakeFish 2018-2020</Copyright>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
<AssemblyName>DedicatedServer</AssemblyName>
|
||||
<ApplicationIcon>..\BarotraumaShared\Icon.ico</ApplicationIcon>
|
||||
<Configurations>Debug;Release;Unstable</Configurations>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>DEBUG;TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<DefineConstants>TRACE;DEBUG;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|AnyCPU'">
|
||||
<DefineConstants>TRACE;SERVER;WINDOWS;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<DefineConstants>TRACE;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Unstable|x64'">
|
||||
<DefineConstants>TRACE;SERVER;WINDOWS;X64;USE_STEAM</DefineConstants>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<OutputPath>..\bin\$(Configuration)Windows\</OutputPath>
|
||||
<DebugType>full</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="..\BarotraumaShared\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||
<Content Remove="..\BarotraumaShared\**\*.cs" />
|
||||
<Compile Include="..\BarotraumaShared\**\*.cs" />
|
||||
<Compile Remove="..\BarotraumaShared\SharedSource\Networking\Primitives\Message\WrapperMsg.cs" />
|
||||
<Content Remove="DedicatedServer.exe" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(Configuration)'!='Debug'">
|
||||
<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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Release" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(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\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\Lidgren.Network\Lidgren.NetStandard.csproj" AdditionalProperties="Configuration=Debug" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Sourced from https://stackoverflow.com/a/45248069 -->
|
||||
<Target Name="GetGitRevision" BeforeTargets="WriteGitRevision" Condition="'$(BuildHash)' == ''">
|
||||
<PropertyGroup>
|
||||
<!-- temp file for the git version (lives in "obj" folder)-->
|
||||
<VerFile>$(IntermediateOutputPath)gitver</VerFile>
|
||||
<BranchFile>$(IntermediateOutputPath)gitbranch</BranchFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- write the hash to the temp file.-->
|
||||
<Exec Command="git -C $(ProjectDir) rev-parse --short HEAD > $(VerFile)" ContinueOnError="true">
|
||||
<Output TaskParameter="exitcode" ItemName="exitcodes" />
|
||||
</Exec>
|
||||
<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 > $(BranchFile)" Condition="'%(exitcodes.identity)'>0" />
|
||||
|
||||
<!-- read the version into the GitVersion itemGroup-->
|
||||
<ReadLinesFromFile File="$(VerFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitVersion" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildHash>@(GitVersion)</BuildHash>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- read the branch into the GitBranch itemGroup-->
|
||||
<ReadLinesFromFile File="$(BranchFile)">
|
||||
<Output TaskParameter="Lines" ItemName="GitBranch" />
|
||||
</ReadLinesFromFile>
|
||||
<!-- Set the BuildHash property to contain the GitVersion, if it wasn't already set.-->
|
||||
<PropertyGroup>
|
||||
<BuildBranch>@(GitBranch)</BuildBranch>
|
||||
</PropertyGroup>
|
||||
</Target>
|
||||
|
||||
<Target Name="WriteGitRevision" BeforeTargets="CoreCompile">
|
||||
<!-- names the obj/.../CustomAssemblyInfo.cs file -->
|
||||
<PropertyGroup>
|
||||
<CustomAssemblyInfoFile>$(IntermediateOutputPath)CustomAssemblyInfo.cs</CustomAssemblyInfoFile>
|
||||
</PropertyGroup>
|
||||
<!-- includes the CustomAssemblyInfo for compilation into your project -->
|
||||
<ItemGroup>
|
||||
<Compile Include="$(CustomAssemblyInfoFile)" />
|
||||
</ItemGroup>
|
||||
<!-- defines the AssemblyMetadata attribute that will be written -->
|
||||
<ItemGroup>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitRevision</_Parameter1>
|
||||
<_Parameter2>$(BuildHash)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>GitBranch</_Parameter1>
|
||||
<_Parameter2>$(BuildBranch)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
<AssemblyAttributes Include="AssemblyMetadata">
|
||||
<_Parameter1>ProjectDir</_Parameter1>
|
||||
<_Parameter2>$(ProjectDir)</_Parameter2>
|
||||
</AssemblyAttributes>
|
||||
</ItemGroup>
|
||||
<!-- writes the attribute to the customAssemblyInfo file -->
|
||||
<WriteCodeFragment Language="C#" OutputFile="$(CustomAssemblyInfoFile)" AssemblyAttributes="@(AssemblyAttributes)" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
<Character file="Content/Characters/Balloon/Balloon.xml" />
|
||||
<Character file="Content/Characters/Carrier/Carrier.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/Crawler/Crawler.xml" />
|
||||
<Character file="Content/Characters/Crawlerhusk/Crawlerhusk.xml" />
|
||||
@@ -248,4 +249,6 @@
|
||||
<OutpostModule file="Content/Map/Outposts/Hall4wayModule_01_Abandoned.sub" />
|
||||
<BeaconStation file="Content/Map/BeaconStations/BeaconStation1.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>
|
||||
@@ -232,8 +232,7 @@ namespace Barotrauma
|
||||
|
||||
public bool IsWithinSector(Vector2 worldPosition)
|
||||
{
|
||||
if (sectorRad >= MathHelper.TwoPi) return true;
|
||||
|
||||
if (sectorRad >= MathHelper.TwoPi) { return true; }
|
||||
Vector2 diff = worldPosition - WorldPosition;
|
||||
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 string GetTargetingTag(AITarget aiTarget)
|
||||
{
|
||||
if (aiTarget.Entity == null) { return null; }
|
||||
if (aiTarget?.Entity == null) { return null; }
|
||||
string targetingTag = null;
|
||||
if (aiTarget.Entity is Character targetCharacter)
|
||||
{
|
||||
@@ -377,6 +377,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (DisableEnemyAI) { return; }
|
||||
base.Update(deltaTime);
|
||||
UpdateTriggers(deltaTime);
|
||||
|
||||
bool ignorePlatforms = Character.AnimController.TargetMovement.Y < -0.5f && (-Character.AnimController.TargetMovement.Y > Math.Abs(Character.AnimController.TargetMovement.X));
|
||||
if (steeringManager == insideSteering)
|
||||
@@ -462,7 +463,7 @@ namespace Barotrauma
|
||||
{
|
||||
updateTargetsTimer -= deltaTime;
|
||||
}
|
||||
else if (avoidTimer <= 0)
|
||||
else if (avoidTimer <= 0 || activeTriggers.Any() && returnTimer <= 0)
|
||||
{
|
||||
CharacterParams.TargetParams targetingParams = null;
|
||||
UpdateTargets(Character, out targetingParams);
|
||||
@@ -1448,8 +1449,12 @@ namespace Barotrauma
|
||||
break;
|
||||
case AttackPattern.Circle:
|
||||
if (IsCoolDownRunning) { break; }
|
||||
if (IsAttackRunning) { break; }
|
||||
if (IsAttackRunning && CirclePhase != CirclePhase.Strike) { 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)
|
||||
{
|
||||
case CirclePhase.Start:
|
||||
@@ -1471,22 +1476,31 @@ namespace Barotrauma
|
||||
circleOffset = Rand.Vector(MathHelper.Lerp(selectedTargetingParams.CircleMaxRandomOffset, 0, currentAttackIntensity * Rand.Range(0.9f, 1.1f)));
|
||||
canAttack = false;
|
||||
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;
|
||||
case CirclePhase.CloseIn:
|
||||
var sub = SelectedAiTarget.Entity?.Submarine;
|
||||
if (sub == null)
|
||||
{
|
||||
CirclePhase = CirclePhase.Start;
|
||||
break;
|
||||
}
|
||||
if (AttackingLimb != null && distance > 0 && distance < AttackingLimb.attack.Range * GetStrikeDistanceMultiplier(sub.Velocity))
|
||||
if (AttackingLimb != null && distance > 0 && distance < AttackingLimb.attack.Range * GetStrikeDistanceMultiplier(targetSub.Velocity))
|
||||
{
|
||||
strikeTimer = AttackingLimb.attack.CoolDown;
|
||||
CirclePhase = CirclePhase.Strike;
|
||||
}
|
||||
else if (!breakCircling && Vector2.DistanceSquared(WorldPosition, attackWorldPos) <= MathUtils.Pow2(circleFallbackDistance - 1000) &&
|
||||
sub.Velocity.LengthSquared() <= MathUtils.Pow2(GetTargetMaxSpeed()))
|
||||
else if (!breakCircling && sqrDistToSub <= MathUtils.Pow2(subSize + selectedTargetingParams.CircleStartDistance / 2) && targetSub.Velocity.LengthSquared() <= MathUtils.Pow2(GetTargetMaxSpeed()))
|
||||
{
|
||||
CirclePhase = CirclePhase.Advance;
|
||||
}
|
||||
@@ -1494,23 +1508,17 @@ namespace Barotrauma
|
||||
break;
|
||||
case CirclePhase.FallBack:
|
||||
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;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case CirclePhase.Advance:
|
||||
var targetSub = SelectedAiTarget.Entity?.Submarine;
|
||||
if (targetSub == null)
|
||||
{
|
||||
CirclePhase = CirclePhase.Start;
|
||||
break;
|
||||
}
|
||||
Vector2 subSpeed = targetSub.Velocity;
|
||||
float requiredDistMultiplier = 1;
|
||||
// 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;
|
||||
}
|
||||
@@ -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,
|
||||
// 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.
|
||||
if (targetSub.Borders.ContainsWorld(attackWorldPos + ConvertUnits.ToDisplayUnits(circleOffset)))
|
||||
if (AttackingLimb != null && sqrDistToSub < MathUtils.Pow2(subSize + circleFallbackDistance))
|
||||
{
|
||||
CirclePhase = CirclePhase.Strike;
|
||||
strikeTimer = AttackingLimb.attack.CoolDown;
|
||||
@@ -1646,15 +1654,15 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance, attackTargetLimb))
|
||||
{
|
||||
CirclePhase = CirclePhase.Start;
|
||||
}
|
||||
else
|
||||
if (!UpdateLimbAttack(deltaTime, AttackingLimb, attackSimPos, distance, attackTargetLimb))
|
||||
{
|
||||
IgnoreTarget(SelectedAiTarget);
|
||||
}
|
||||
}
|
||||
else if (IsAttackRunning)
|
||||
{
|
||||
AttackingLimb.attack.ResetAttackTimer();
|
||||
}
|
||||
}
|
||||
|
||||
private readonly List<Limb> attackLimbs = new List<Limb>();
|
||||
@@ -2060,6 +2068,7 @@ namespace Barotrauma
|
||||
targetValue = 0;
|
||||
selectedTargetMemory = null;
|
||||
targetingParams = null;
|
||||
bool isAnyTargetClose = false;
|
||||
|
||||
foreach (AITarget aiTarget in AITarget.List)
|
||||
{
|
||||
@@ -2163,6 +2172,14 @@ namespace Barotrauma
|
||||
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)
|
||||
{
|
||||
if (item.HasTag(prio.Tag))
|
||||
@@ -2379,18 +2396,16 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!aiTarget.IsWithinSector(WorldPosition)) { continue; }
|
||||
Vector2 toTarget = aiTarget.WorldPosition - character.WorldPosition;
|
||||
float dist = toTarget.Length();
|
||||
|
||||
float nonModifiedDist = dist;
|
||||
//if the target has been within range earlier, the character will notice it more easily
|
||||
if (targetMemories.ContainsKey(aiTarget))
|
||||
{
|
||||
dist *= 0.9f;
|
||||
}
|
||||
|
||||
if (!CanPerceive(aiTarget, dist)) { continue; }
|
||||
if (!aiTarget.IsWithinSector(WorldPosition)) { continue; }
|
||||
|
||||
//if the target is very close, the distance doesn't make much difference
|
||||
// -> just ignore the distance and attack whatever has the highest priority
|
||||
@@ -2405,14 +2420,26 @@ namespace Barotrauma
|
||||
|
||||
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))
|
||||
{
|
||||
// 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);
|
||||
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;
|
||||
selectedTargetMemory = targetMemory;
|
||||
targetValue = valueModifier;
|
||||
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 ||
|
||||
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 float stateResetTimer;
|
||||
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>
|
||||
/// 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.Remove(tag);
|
||||
}
|
||||
targetParams.Reset();
|
||||
ResetAITarget();
|
||||
// Enforce the idle state so that we don't keep following the target if there's one
|
||||
State = AIState.Idle;
|
||||
PreviousState = AIState.Idle;
|
||||
ResetParams(targetParams);
|
||||
return true;
|
||||
}
|
||||
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> 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)
|
||||
{
|
||||
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 float returnTimer;
|
||||
private void SteerInsideLevel(float deltaTime)
|
||||
{
|
||||
if (State == AIState.Attack) { return; }
|
||||
if (SteeringManager is IndoorsSteeringManager) { return; }
|
||||
if (Level.Loaded == null) { return; }
|
||||
Point levelSize = Level.Loaded.Size;
|
||||
float returnTime = 10;
|
||||
if (AIParams.AvoidAbyss)
|
||||
if (State == AIState.Attack && returnTimer <= 0) { return; }
|
||||
float returnTime = 5;
|
||||
if (!IsPositionInsideAllowedZone(WorldPosition, out Vector2 targetDir))
|
||||
{
|
||||
if (WorldPosition.Y < Level.Loaded.AbyssStart)
|
||||
{
|
||||
// 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
|
||||
returnDir = targetDir;
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Barotrauma
|
||||
|
||||
private readonly AIObjectiveManager objectiveManager;
|
||||
|
||||
private float sortTimer;
|
||||
public float SortTimer { get; set; }
|
||||
private float crouchRaycastTimer;
|
||||
private float reactTimer;
|
||||
private float unreachableClearTimer;
|
||||
@@ -131,7 +131,7 @@ namespace Barotrauma
|
||||
outsideSteering = new SteeringManager(this);
|
||||
objectiveManager = new AIObjectiveManager(c);
|
||||
reactTimer = GetReactionTime();
|
||||
sortTimer = Rand.Range(0f, sortObjectiveInterval);
|
||||
SortTimer = Rand.Range(0f, sortObjectiveInterval);
|
||||
}
|
||||
|
||||
public override void Update(float deltaTime)
|
||||
@@ -218,6 +218,7 @@ namespace Barotrauma
|
||||
foreach (Character c in Character.CharacterList)
|
||||
{
|
||||
if (c.Submarine != Character.Submarine) { continue; }
|
||||
if (c.Removed || c.IsDead || c.IsIncapacitated) { continue; }
|
||||
if (IsFriendly(c)) { continue; }
|
||||
Vector2 toTarget = c.WorldPosition - WorldPosition;
|
||||
float dist = toTarget.LengthSquared();
|
||||
@@ -264,14 +265,14 @@ namespace Barotrauma
|
||||
CheckCrouching(deltaTime);
|
||||
Character.ClearInputs();
|
||||
|
||||
if (sortTimer > 0.0f)
|
||||
if (SortTimer > 0.0f)
|
||||
{
|
||||
sortTimer -= deltaTime;
|
||||
SortTimer -= deltaTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
objectiveManager.SortObjectives();
|
||||
sortTimer = sortObjectiveInterval;
|
||||
SortTimer = sortObjectiveInterval;
|
||||
}
|
||||
objectiveManager.UpdateObjectives(deltaTime);
|
||||
|
||||
@@ -288,14 +289,14 @@ namespace Barotrauma
|
||||
{
|
||||
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 => RefreshHullSafety(h));
|
||||
VisibleHulls.ForEach(h => PropagateHullSafety(Character, h));
|
||||
}
|
||||
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)
|
||||
@@ -1065,7 +1066,9 @@ namespace Barotrauma
|
||||
{
|
||||
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
|
||||
{
|
||||
@@ -1192,7 +1195,7 @@ namespace Barotrauma
|
||||
{
|
||||
base.Reset();
|
||||
objectiveManager.SortObjectives();
|
||||
sortTimer = sortObjectiveInterval;
|
||||
SortTimer = sortObjectiveInterval;
|
||||
float waitDuration = characterWaitOnSwitch;
|
||||
if (ObjectiveManager.IsCurrentObjective<AIObjectiveIdle>())
|
||||
{
|
||||
@@ -1418,6 +1421,9 @@ namespace Barotrauma
|
||||
item.StolenDuringRound = true;
|
||||
otherCharacter.Speak(TextManager.Get("dialogstealwarning"), null, Rand.Range(0.5f, 1.0f), "thief", 10.0f);
|
||||
someoneSpoke = true;
|
||||
#if CLIENT
|
||||
HintManager.OnStoleItem(thief, item);
|
||||
#endif
|
||||
}
|
||||
// React if we are security
|
||||
if (!TriggerSecurity(otherHumanAI))
|
||||
@@ -1554,7 +1560,7 @@ namespace Barotrauma
|
||||
targetAdded = true;
|
||||
}
|
||||
}
|
||||
}, (caller.AIController as HumanAIController)?.ReportRange ?? float.PositiveInfinity);
|
||||
}, range: (caller.AIController as HumanAIController)?.ReportRange ?? float.PositiveInfinity);
|
||||
return targetAdded;
|
||||
}
|
||||
|
||||
@@ -1726,11 +1732,9 @@ namespace Barotrauma
|
||||
switch (myTeam)
|
||||
{
|
||||
case CharacterTeamType.None:
|
||||
// Only enemies are in the Team "None"
|
||||
return false;
|
||||
case CharacterTeamType.Team1:
|
||||
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;
|
||||
case CharacterTeamType.FriendlyNPC:
|
||||
// Friendly NPCs are friendly to both teams
|
||||
|
||||
@@ -221,6 +221,19 @@ namespace Barotrauma
|
||||
{
|
||||
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;
|
||||
|
||||
@@ -79,6 +79,7 @@ namespace Barotrauma
|
||||
private float coolDownTimer;
|
||||
private IEnumerable<Body> myBodies;
|
||||
private float aimTimer;
|
||||
private float reloadTimer;
|
||||
private float spreadTimer;
|
||||
|
||||
private bool canSeeTarget;
|
||||
@@ -147,6 +148,7 @@ namespace Barotrauma
|
||||
Mode = CombatMode.Retreat;
|
||||
}
|
||||
spreadTimer = Rand.Range(-10, 10);
|
||||
HumanAIController.SortTimer = 0;
|
||||
}
|
||||
|
||||
public override float GetPriority()
|
||||
@@ -170,6 +172,10 @@ namespace Barotrauma
|
||||
base.Update(deltaTime);
|
||||
ignoreWeaponTimer -= deltaTime;
|
||||
checkWeaponsTimer -= deltaTime;
|
||||
if (reloadTimer > 0)
|
||||
{
|
||||
reloadTimer -= deltaTime;
|
||||
}
|
||||
if (ignoreWeaponTimer < 0)
|
||||
{
|
||||
ignoredWeapons.Clear();
|
||||
@@ -219,7 +225,11 @@ namespace Barotrauma
|
||||
{
|
||||
OperateWeapon(deltaTime);
|
||||
}
|
||||
if (!HoldPosition && seekAmmunitionObjective == null && seekWeaponObjective == null)
|
||||
if (HoldPosition)
|
||||
{
|
||||
SteeringManager.Reset();
|
||||
}
|
||||
else if (seekAmmunitionObjective == null && seekWeaponObjective == null)
|
||||
{
|
||||
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));
|
||||
if (character.Inventory.TryPutItem(Weapon, character, slots))
|
||||
{
|
||||
aimTimer = Rand.Range(1f, 1.5f) / AimSpeed;
|
||||
aimTimer = Rand.Range(0.2f, 0.4f) / AimSpeed;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -912,7 +922,7 @@ namespace Barotrauma
|
||||
}
|
||||
if (!canSeeTarget)
|
||||
{
|
||||
aimTimer = Rand.Range(0.2f, 1f) / AimSpeed;
|
||||
aimTimer = Rand.Range(0.2f, 0.4f) / AimSpeed;
|
||||
return;
|
||||
}
|
||||
if (Weapon.RequireAimToUse)
|
||||
@@ -930,6 +940,7 @@ namespace Barotrauma
|
||||
aimTimer -= deltaTime;
|
||||
return;
|
||||
}
|
||||
if (reloadTimer > 0) { return; }
|
||||
if (Mode == CombatMode.Arrest && isLethalWeapon && Enemy.Stun > 1) { return; }
|
||||
if (holdFireCondition != null && holdFireCondition()) { return; }
|
||||
float sqrDist = Vector2.DistanceSquared(character.Position, Enemy.Position);
|
||||
@@ -1010,18 +1021,25 @@ namespace Barotrauma
|
||||
|
||||
private void UseWeapon(float deltaTime)
|
||||
{
|
||||
character.SetInput(InputType.Shoot, false, true);
|
||||
Weapon.Use(deltaTime, character);
|
||||
float reloadTime = 0;
|
||||
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)
|
||||
{
|
||||
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()
|
||||
@@ -1031,10 +1049,7 @@ namespace Barotrauma
|
||||
{
|
||||
Unequip();
|
||||
}
|
||||
if (!HoldPosition)
|
||||
{
|
||||
SteeringManager.Reset();
|
||||
}
|
||||
SteeringManager.Reset();
|
||||
}
|
||||
|
||||
protected override void OnAbandon()
|
||||
@@ -1044,10 +1059,7 @@ namespace Barotrauma
|
||||
{
|
||||
Unequip();
|
||||
}
|
||||
if (!HoldPosition)
|
||||
{
|
||||
SteeringManager.Reset();
|
||||
}
|
||||
SteeringManager.Reset();
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Barotrauma
|
||||
protected override float IgnoreListClearInterval => 30;
|
||||
public override bool IgnoreUnsafeHulls => true;
|
||||
|
||||
protected override float TargetUpdateTimeMultiplier => 0.2f;
|
||||
|
||||
public AIObjectiveFightIntruders(Character character, AIObjectiveManager objectiveManager, float priorityModifier = 1)
|
||||
: base(character, objectiveManager, priorityModifier) { }
|
||||
|
||||
@@ -48,7 +50,8 @@ namespace Barotrauma
|
||||
|
||||
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.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
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Barotrauma
|
||||
protected HashSet<T> ignoreList = new HashSet<T>();
|
||||
private float ignoreListTimer;
|
||||
protected float targetUpdateTimer;
|
||||
protected virtual float TargetUpdateTimeMultiplier { get; } = 1;
|
||||
|
||||
private float syncTimer;
|
||||
private readonly float syncTime = 1;
|
||||
@@ -61,7 +62,7 @@ namespace Barotrauma
|
||||
ignoreListTimer += deltaTime;
|
||||
}
|
||||
}
|
||||
if (targetUpdateTimer < 0)
|
||||
if (targetUpdateTimer <= 0)
|
||||
{
|
||||
UpdateTargets();
|
||||
}
|
||||
@@ -69,9 +70,9 @@ namespace Barotrauma
|
||||
{
|
||||
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
|
||||
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%
|
||||
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()
|
||||
{
|
||||
@@ -156,7 +157,7 @@ namespace Barotrauma
|
||||
|
||||
protected void UpdateTargets()
|
||||
{
|
||||
SetTargetUpdateTimer();
|
||||
CalculateTargetUpdateTimer();
|
||||
Targets.Clear();
|
||||
FindTargets();
|
||||
CreateObjectives();
|
||||
|
||||
@@ -386,7 +386,9 @@ namespace Barotrauma
|
||||
Abandon = true;
|
||||
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)
|
||||
{
|
||||
character.Speak(TextManager.GetWithVariable("DialogTargetHealed", "[targetname]", targetCharacter.Name),
|
||||
|
||||
@@ -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.
|
||||
// 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.
|
||||
return character == target || manager.CurrentOrder is AIObjectiveRescueAll ? (target.IsPlayer ? 100 : vitalityThresholdForOrders) : vitalityThreshold;
|
||||
// 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.HasOrder<AIObjectiveRescueAll>() ? (target.IsPlayer ? 100 : vitalityThresholdForOrders) : vitalityThreshold;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace Barotrauma
|
||||
if (character.AIController is HumanAIController humanAI)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -281,7 +281,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public const float MAX_SPEED = 30;
|
||||
public const float MAX_SPEED = 20;
|
||||
|
||||
public Vector2 TargetMovement
|
||||
{
|
||||
@@ -636,9 +636,12 @@ namespace Barotrauma
|
||||
//always collides with bodies other than structures
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -156,6 +156,8 @@ namespace Barotrauma
|
||||
|
||||
public Entity LastDamageSource;
|
||||
|
||||
public AttackResult LastDamage;
|
||||
|
||||
public float InvisibleTimer;
|
||||
|
||||
private CharacterPrefab prefab;
|
||||
@@ -199,7 +201,12 @@ namespace Barotrauma
|
||||
set => Params.Visibility = value;
|
||||
}
|
||||
|
||||
public bool IsTraitor;
|
||||
public bool IsTraitor
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string TraitorCurrentObjective = "";
|
||||
public bool IsHuman => SpeciesName.Equals(CharacterPrefab.HumanSpeciesName, StringComparison.OrdinalIgnoreCase);
|
||||
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
|
||||
public string customInteractHUDText;
|
||||
private Action<Character, Character> onCustomInteract;
|
||||
public ConversationAction ActiveConversation;
|
||||
|
||||
public bool AllowCustomInteract
|
||||
{
|
||||
@@ -349,6 +357,9 @@ namespace Barotrauma
|
||||
set
|
||||
{
|
||||
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;
|
||||
set
|
||||
{
|
||||
#if CLIENT
|
||||
HintManager.OnSetSelectedConstruction(this, _selectedConstruction, value);
|
||||
#endif
|
||||
_selectedConstruction = value;
|
||||
#if CLIENT
|
||||
if (Controlled == this)
|
||||
@@ -1661,6 +1675,12 @@ namespace Barotrauma
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (!CanInteract || inventory.Locked) { return false; }
|
||||
@@ -2857,6 +2890,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (character == this) { continue; }
|
||||
if (character.TeamID != TeamID) { continue; }
|
||||
if (!HumanAIController.IsActive(character)) { continue; }
|
||||
foreach (var currentOrder in character.CurrentOrders)
|
||||
{
|
||||
if (currentOrder.Order == null) { continue; }
|
||||
@@ -3268,12 +3302,13 @@ namespace Barotrauma
|
||||
//#endif
|
||||
// }
|
||||
|
||||
SetStun(stun);
|
||||
|
||||
if (attacker != null && attacker != this && GameMain.NetworkMember != null && !GameMain.NetworkMember.ServerSettings.AllowFriendlyFire)
|
||||
{
|
||||
if (attacker.TeamID == TeamID) { return new AttackResult(); }
|
||||
}
|
||||
|
||||
SetStun(stun);
|
||||
Vector2 dir = hitLimb.WorldPosition - worldPosition;
|
||||
if (Math.Abs(attackImpulse) > 0.0f)
|
||||
{
|
||||
@@ -3308,6 +3343,7 @@ namespace Barotrauma
|
||||
};
|
||||
if (attackResult.Damage > 0)
|
||||
{
|
||||
LastDamage = attackResult;
|
||||
ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
||||
hitLimb.ApplyStatusEffects(ActionType.OnDamaged, 1.0f);
|
||||
if (attacker != null)
|
||||
|
||||
@@ -153,6 +153,8 @@ namespace Barotrauma
|
||||
private static ushort idCounter;
|
||||
private const string disguiseName = "???";
|
||||
|
||||
public bool HasNickname => Name != OriginalName;
|
||||
public string OriginalName { get; private set; }
|
||||
public string Name;
|
||||
public string DisplayName
|
||||
{
|
||||
@@ -453,7 +455,7 @@ namespace Barotrauma
|
||||
public bool IsAttachmentsLoaded => HairIndex > -1 && BeardIndex > -1 && MoustacheIndex > -1 && FaceAttachmentIndex > -1;
|
||||
|
||||
// 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))
|
||||
{
|
||||
@@ -503,6 +505,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
}
|
||||
OriginalName = !string.IsNullOrEmpty(originalName) ? originalName : Name;
|
||||
personalityTrait = NPCPersonalityTrait.GetRandom(name + HeadSpriteId);
|
||||
Salary = CalculateSalary();
|
||||
if (ragdollFileName != null)
|
||||
@@ -518,6 +521,7 @@ namespace Barotrauma
|
||||
ID = idCounter;
|
||||
idCounter++;
|
||||
Name = infoElement.GetAttributeString("name", "");
|
||||
OriginalName = infoElement.GetAttributeString("originalname", null);
|
||||
string genderStr = infoElement.GetAttributeString("gender", "male").ToLowerInvariant();
|
||||
Salary = infoElement.GetAttributeInt("salary", 1000);
|
||||
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);
|
||||
string personalityName = infoElement.GetAttributeString("personality", "");
|
||||
ragdollFileName = infoElement.GetAttributeString("ragdoll", string.Empty);
|
||||
@@ -622,7 +631,17 @@ namespace Barotrauma
|
||||
|
||||
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 ^= (int)Race << 6;
|
||||
id ^= HairIndex << 12;
|
||||
@@ -939,12 +958,24 @@ namespace Barotrauma
|
||||
|
||||
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)
|
||||
{
|
||||
XElement charElement = new XElement("Character");
|
||||
|
||||
charElement.Add(
|
||||
new XAttribute("name", Name),
|
||||
new XAttribute("originalname", OriginalName),
|
||||
new XAttribute("speciesname", SpeciesName),
|
||||
new XAttribute("gender", Head.gender == Gender.Male ? "male" : "female"),
|
||||
new XAttribute("race", Head.race.ToString()),
|
||||
@@ -957,7 +988,7 @@ namespace Barotrauma
|
||||
new XAttribute("startitemsgiven", StartItemsGiven),
|
||||
new XAttribute("ragdoll", ragdollFileName),
|
||||
new XAttribute("personality", personalityTrait == null ? "" : personalityTrait.Name));
|
||||
|
||||
|
||||
// TODO: animations?
|
||||
|
||||
if (Character != null)
|
||||
|
||||
@@ -260,10 +260,13 @@ namespace Barotrauma
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
public void SetStrength(float strength) => _strength = strength;
|
||||
public void SetStrength(float strength)
|
||||
{
|
||||
_nonClampedStrength = strength;
|
||||
_strength = _nonClampedStrength;
|
||||
}
|
||||
|
||||
public bool ShouldShowIcon(Character afflictedCharacter)
|
||||
{
|
||||
|
||||
@@ -290,6 +290,9 @@ namespace Barotrauma
|
||||
//how high the strength has to be for the affliction icon to be shown with a health scanner
|
||||
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)
|
||||
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.");
|
||||
}
|
||||
|
||||
List<(AfflictionPrefab prefab, XElement element)> loadedAfflictions = new List<(AfflictionPrefab prefab, XElement element)>();
|
||||
|
||||
foreach (XElement element in mainElement.Elements())
|
||||
{
|
||||
bool isOverride = element.IsOverride();
|
||||
@@ -510,10 +516,18 @@ namespace Barotrauma
|
||||
|
||||
if (prefab != null)
|
||||
{
|
||||
loadedAfflictions.Add((prefab, element));
|
||||
Prefabs.Add(prefab, isOverride);
|
||||
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)
|
||||
@@ -565,6 +579,7 @@ namespace Barotrauma
|
||||
MaxStrength = element.GetAttributeFloat("maxstrength", 100.0f);
|
||||
|
||||
ShowInHealthScannerThreshold = element.GetAttributeFloat("showinhealthscannerthreshold", Math.Max(ActivationThreshold, 0.05f));
|
||||
TreatmentThreshold = element.GetAttributeFloat("treatmentthreshold", Math.Max(ActivationThreshold, 5.0f));
|
||||
|
||||
DamageOverlayAlpha = element.GetAttributeFloat("damageoverlayalpha", 0.0f);
|
||||
BurnOverlayAlpha = element.GetAttributeFloat("burnoverlayalpha", 0.0f);
|
||||
@@ -584,9 +599,6 @@ namespace Barotrauma
|
||||
case "icon":
|
||||
Icon = new Sprite(subElement);
|
||||
break;
|
||||
case "effect":
|
||||
effects.Add(new Effect(subElement, Name));
|
||||
break;
|
||||
case "periodiceffect":
|
||||
periodicEffects.Add(new PeriodicEffect(subElement, Name));
|
||||
break;
|
||||
@@ -614,6 +626,19 @@ namespace Barotrauma
|
||||
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()
|
||||
{
|
||||
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