Faction Test v1.0.1.0

This commit is contained in:
Regalis11
2023-02-16 15:01:28 +02:00
parent caa5a2f762
commit 2c5a7923b0
309 changed files with 7502 additions and 4335 deletions
@@ -23,15 +23,12 @@ namespace Barotrauma
ScrollBarEnabled = false,
AllowMouseWheelScroll = false
};
new GUIButton(new RectTransform(new Vector2(0.1f), creditsPlayer.RectTransform, Anchor.BottomRight, maxSize: new Point(300, 50)) { AbsoluteOffset = new Point(GUI.IntScale(20)) },
TextManager.Get("close"))
creditsPlayer.CloseButton.OnClicked = (btn, userdata) =>
{
OnClicked = (btn, userdata) =>
{
creditsPlayer.Scroll = 1.0f;
return true;
}
creditsPlayer.Scroll = 1.0f;
return true;
};
cam = new Camera();
}
@@ -44,7 +41,16 @@ namespace Barotrauma
}
creditsPlayer.Restart();
creditsPlayer.Visible = false;
SteamAchievementManager.UnlockAchievement("campaigncompleted".ToIdentifier(), unlockClients: true);
UnlockAchievement("campaigncompleted");
UnlockAchievement(
GameMain.GameSession is { Campaign.Settings.RadiationEnabled: true } ?
"campaigncompleted_radiationenabled" :
"campaigncompleted_radiationdisabled");
static void UnlockAchievement(string id)
{
SteamAchievementManager.UnlockAchievement(id.ToIdentifier(), unlockClients: true);
}
}
public override void Deselect()
@@ -4,6 +4,7 @@ using System;
using System.Collections.Generic;
using Barotrauma.IO;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
@@ -37,7 +38,6 @@ namespace Barotrauma
protected set;
}
public CampaignSettings CurrentSettings = new CampaignSettings(element: null);
public GUIButton CampaignCustomizeButton { get; set; }
public GUIMessageBox CampaignCustomizeSettings { get; set; }
@@ -58,7 +58,7 @@ namespace Barotrauma
var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform) { MinSize = new Point(0, 45) }, style: "ListBoxElement")
{
UserData = saveInfo.FilePath
UserData = saveInfo
};
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform), Path.GetFileNameWithoutExtension(saveInfo.FilePath),
@@ -87,10 +87,9 @@ namespace Barotrauma
};
string saveTimeStr = string.Empty;
if (saveInfo.SaveTime > 0)
if (saveInfo.SaveTime.TryUnwrap(out var time))
{
DateTime time = ToolBox.Epoch.ToDateTime(saveInfo.SaveTime);
saveTimeStr = time.ToString();
saveTimeStr = time.ToLocalUserString();
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform),
text: saveTimeStr, textAlignment: Alignment.Right, font: GUIStyle.SmallFont)
@@ -102,8 +101,29 @@ namespace Barotrauma
return saveFrame;
}
protected void SortSaveList()
{
saveList.Content.RectTransform.SortChildren((c1, c2) =>
{
if (c1.GUIComponent.UserData is not CampaignMode.SaveInfo file1
|| c2.GUIComponent.UserData is not CampaignMode.SaveInfo file2)
{
return 0;
}
if (!file1.SaveTime.TryUnwrap(out var file1WriteTime)
|| !file2.SaveTime.TryUnwrap(out var file2WriteTime))
{
return 0;
}
return file2WriteTime.CompareTo(file1WriteTime);
});
}
public struct CampaignSettingElements
{
public SettingValue<string> SelectedPreset;
public SettingValue<bool> TutorialEnabled;
public SettingValue<bool> RadiationEnabled;
public SettingValue<int> MaxMissionCount;
@@ -115,6 +135,7 @@ namespace Barotrauma
{
return new CampaignSettings(element: null)
{
PresetName = SelectedPreset.GetValue(),
TutorialEnabled = TutorialEnabled.GetValue(),
RadiationEnabled = RadiationEnabled.GetValue(),
MaxMissionCount = MaxMissionCount.GetValue(),
@@ -165,9 +186,13 @@ namespace Barotrauma
{
const float verticalSize = 0.14f;
bool loadingPreset = false;
GUILayoutGroup presetDropdownLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, verticalSize), parent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), presetDropdownLayout.RectTransform), TextManager.Get("campaignsettingpreset"));
GUIDropDown presetDropdown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), presetDropdownLayout.RectTransform), elementCount: CampaignModePresets.List.Length);
GUIDropDown presetDropdown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), presetDropdownLayout.RectTransform), elementCount: CampaignModePresets.List.Length + 1);
presetDropdown.AddItem(TextManager.Get("karmapreset.custom"), null);
presetDropdown.Select(0);
presetDropdownLayout.RectTransform.MinSize = new Point(0, presetDropdown.Rect.Height);
@@ -175,21 +200,30 @@ namespace Barotrauma
{
string name = settings.PresetName;
presetDropdown.AddItem(TextManager.Get($"preset.{name}").Fallback(name), settings);
if (settings.PresetName.Equals(prevSettings.PresetName, StringComparison.OrdinalIgnoreCase))
{
presetDropdown.SelectItem(settings);
}
}
var presetValue = new SettingValue<string>(
get: () => presetDropdown.SelectedData is CampaignSettings settings ? settings.PresetName : string.Empty,
set: static _ => { }); // we do not need a way to set this value
GUIListBox settingsList = new GUIListBox(new RectTransform(new Vector2(1f, 1f - verticalSize), parent.RectTransform))
{
Spacing = GUI.IntScale(5)
};
SettingValue<bool> tutorialEnabled = isSinglePlayer ?
CreateTickbox(settingsList.Content, TextManager.Get("CampaignOption.EnableTutorial"), TextManager.Get("campaignoption.enabletutorial.tooltip"), prevSettings.TutorialEnabled, verticalSize) :
new SettingValue<bool>(() => false, b => { });
SettingValue<bool> radiationEnabled = CreateTickbox(settingsList.Content, TextManager.Get("CampaignOption.EnableRadiation"), TextManager.Get("campaignoption.enableradiation.tooltip"), prevSettings.RadiationEnabled, verticalSize);
CreateTickbox(settingsList.Content, TextManager.Get("CampaignOption.EnableTutorial"), TextManager.Get("campaignoption.enabletutorial.tooltip"), prevSettings.TutorialEnabled, verticalSize, OnValuesChanged) :
new SettingValue<bool>(static () => false, static _ => { });
SettingValue<bool> radiationEnabled = CreateTickbox(settingsList.Content, TextManager.Get("CampaignOption.EnableRadiation"), TextManager.Get("campaignoption.enableradiation.tooltip"), prevSettings.RadiationEnabled, verticalSize, OnValuesChanged);
ImmutableArray<SettingCarouselElement<Identifier>> startingSetOptions = StartItemSet.Sets.OrderBy(s => s.Order).Select(set => new SettingCarouselElement<Identifier>(set.Identifier, $"startitemset.{set.Identifier}")).ToImmutableArray();
SettingCarouselElement<Identifier> prevStartingSet = startingSetOptions.FirstOrNull(element => element.Value == prevSettings.StartItemSet) ?? startingSetOptions[1];
SettingValue<Identifier> startingSetInput = CreateSelectionCarousel(settingsList.Content, TextManager.Get("startitemset"), TextManager.Get("startitemsettooltip"), prevStartingSet, verticalSize, startingSetOptions);
SettingValue<Identifier> startingSetInput = CreateSelectionCarousel(settingsList.Content, TextManager.Get("startitemset"), TextManager.Get("startitemsettooltip"), prevStartingSet, verticalSize, startingSetOptions, OnValuesChanged);
ImmutableArray<SettingCarouselElement<StartingBalanceAmount>> fundOptions = ImmutableArray.Create(
new SettingCarouselElement<StartingBalanceAmount>(StartingBalanceAmount.Low, "startingfunds.low"),
@@ -198,7 +232,7 @@ namespace Barotrauma
);
SettingCarouselElement<StartingBalanceAmount> prevStartingFund = fundOptions.FirstOrNull(element => element.Value == prevSettings.StartingBalanceAmount) ?? fundOptions[1];
SettingValue<StartingBalanceAmount> startingFundsInput = CreateSelectionCarousel(settingsList.Content, TextManager.Get("startingfundsdescription"), TextManager.Get("startingfundstooltip"), prevStartingFund, verticalSize, fundOptions);
SettingValue<StartingBalanceAmount> startingFundsInput = CreateSelectionCarousel(settingsList.Content, TextManager.Get("startingfundsdescription"), TextManager.Get("startingfundstooltip"), prevStartingFund, verticalSize, fundOptions, OnValuesChanged);
ImmutableArray<SettingCarouselElement<GameDifficulty>> difficultyOptions = ImmutableArray.Create(
new SettingCarouselElement<GameDifficulty>(GameDifficulty.Easy, "difficulty.easy"),
@@ -208,30 +242,38 @@ namespace Barotrauma
);
SettingCarouselElement<GameDifficulty> prevDifficulty = difficultyOptions.FirstOrNull(element => element.Value == prevSettings.Difficulty) ?? difficultyOptions[1];
SettingValue<GameDifficulty> difficultyInput = CreateSelectionCarousel(settingsList.Content, TextManager.Get("leveldifficulty"), TextManager.Get("leveldifficultyexplanation"), prevDifficulty, verticalSize, difficultyOptions);
SettingValue<GameDifficulty> difficultyInput = CreateSelectionCarousel(settingsList.Content, TextManager.Get("leveldifficulty"), TextManager.Get("leveldifficultyexplanation"), prevDifficulty, verticalSize, difficultyOptions, OnValuesChanged);
SettingValue<int> maxMissionCountInput = CreateGUINumberInputCarousel(settingsList.Content, TextManager.Get("maxmissioncount"), TextManager.Get("maxmissioncounttooltip"),
prevSettings.MaxMissionCount,
valueStep: 1, minValue: CampaignSettings.MinMissionCountLimit, maxValue: CampaignSettings.MaxMissionCountLimit,
verticalSize);
verticalSize,
OnValuesChanged);
presetDropdown.OnSelected = (selected, o) =>
presetDropdown.OnSelected = (_, o) =>
{
if (o is CampaignSettings settings)
{
tutorialEnabled.SetValue(isSinglePlayer && settings.TutorialEnabled);
radiationEnabled.SetValue(settings.RadiationEnabled);
maxMissionCountInput.SetValue(settings.MaxMissionCount);
startingFundsInput.SetValue(settings.StartingBalanceAmount);
difficultyInput.SetValue(settings.Difficulty);
startingSetInput.SetValue(settings.StartItemSet);
return true;
}
return false;
if (o is not CampaignSettings settings) { return false; }
loadingPreset = true;
tutorialEnabled.SetValue(isSinglePlayer && settings.TutorialEnabled);
radiationEnabled.SetValue(settings.RadiationEnabled);
maxMissionCountInput.SetValue(settings.MaxMissionCount);
startingFundsInput.SetValue(settings.StartingBalanceAmount);
difficultyInput.SetValue(settings.Difficulty);
startingSetInput.SetValue(settings.StartItemSet);
loadingPreset = false;
return true;
};
void OnValuesChanged()
{
if (loadingPreset) { return; }
presetDropdown.Select(0);
}
return new CampaignSettingElements
{
SelectedPreset = presetValue,
TutorialEnabled = tutorialEnabled,
RadiationEnabled = radiationEnabled,
MaxMissionCount = maxMissionCountInput,
@@ -241,7 +283,7 @@ namespace Barotrauma
};
// Create a number input with plus and minus buttons because for some reason the default GUINumberInput buttons don't work when in a GUIMessageBox
static SettingValue<int> CreateGUINumberInputCarousel(GUIComponent parent, LocalizedString description, LocalizedString tooltip, int defaultValue, int valueStep, int minValue, int maxValue, float verticalSize)
static SettingValue<int> CreateGUINumberInputCarousel(GUIComponent parent, LocalizedString description, LocalizedString tooltip, int defaultValue, int valueStep, int minValue, int maxValue, float verticalSize, Action onChanged)
{
GUILayoutGroup inputContainer = CreateSettingBase(parent, description, tooltip, horizontalSize: 0.55f, verticalSize: verticalSize);
@@ -266,9 +308,11 @@ namespace Barotrauma
minusButton.OnClicked = plusButton.OnClicked = ChangeValue;
numberInput.OnValueChanged += _ => onChanged();
bool ChangeValue(GUIButton btn, object userData)
{
if (!(userData is int change)) { return false; }
if (userData is not int change) { return false; }
numberInput.IntValue += change;
return true;
@@ -278,7 +322,7 @@ namespace Barotrauma
}
static SettingValue<T> CreateSelectionCarousel<T>(GUIComponent parent, LocalizedString description, LocalizedString tooltip, SettingCarouselElement<T> defaultValue, float verticalSize,
ImmutableArray<SettingCarouselElement<T>> options)
ImmutableArray<SettingCarouselElement<T>> options, Action onChanged)
{
GUILayoutGroup inputContainer = CreateSettingBase(parent, description, tooltip, horizontalSize: 0.55f, verticalSize: verticalSize);
@@ -329,6 +373,8 @@ namespace Barotrauma
return true;
}
numberInput.OnValueChanged += _ => onChanged();
void SetValue(int value)
{
numberInput.IntValue = value;
@@ -338,7 +384,7 @@ namespace Barotrauma
return new SettingValue<T>(() => options[numberInput.IntValue].Value, t => SetValue(options.IndexOf(e => Equals(e.Value, t))));
}
static SettingValue<bool> CreateTickbox(GUIComponent parent, LocalizedString description, LocalizedString tooltip, bool defaultValue, float verticalSize)
static SettingValue<bool> CreateTickbox(GUIComponent parent, LocalizedString description, LocalizedString tooltip, bool defaultValue, float verticalSize, Action onChanged)
{
GUILayoutGroup inputContainer = CreateSettingBase(parent, description, tooltip, 0.7f, verticalSize);
GUILayoutGroup tickboxContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 1.0f), inputContainer.RectTransform), childAnchor: Anchor.Center);
@@ -350,6 +396,13 @@ namespace Barotrauma
tickBox.Box.IgnoreLayoutGroups = true;
tickBox.Box.RectTransform.SetPosition(Anchor.CenterRight);
inputContainer.RectTransform.Parent.MinSize = new Point(0, tickBox.RectTransform.MinSize.Y);
tickBox.OnSelected += _ =>
{
onChanged();
return true;
};
return new SettingValue<bool>(() => tickBox.Selected, b => tickBox.Selected = b);
}
@@ -367,5 +420,25 @@ namespace Barotrauma
return inputContainer;
}
}
public abstract void UpdateLoadMenu(IEnumerable<CampaignMode.SaveInfo> saveFiles = null);
protected bool DeleteSave(GUIButton button, object obj)
{
if (obj is not CampaignMode.SaveInfo saveInfo) { return false; }
var header = TextManager.Get("deletedialoglabel");
var body = TextManager.GetWithVariable("deletedialogquestion", "[file]", Path.GetFileNameWithoutExtension(saveInfo.FilePath));
EventEditorScreen.AskForConfirmation(header, body, () =>
{
SaveUtil.DeleteSave(saveInfo.FilePath);
prevSaveFiles?.RemoveAll(s => s.FilePath == saveInfo.FilePath);
UpdateLoadMenu(prevSaveFiles.ToList());
return true;
});
return true;
}
}
}
@@ -192,7 +192,7 @@ namespace Barotrauma
yield return CoroutineStatus.Success;
}
public void UpdateLoadMenu(IEnumerable<CampaignMode.SaveInfo> saveFiles = null)
public override void UpdateLoadMenu(IEnumerable<CampaignMode.SaveInfo> saveFiles = null)
{
prevSaveFiles?.Clear();
prevSaveFiles = null;
@@ -220,37 +220,16 @@ namespace Barotrauma
CreateSaveElement(saveInfo);
}
saveList.Content.RectTransform.SortChildren((c1, c2) =>
{
string file1 = c1.GUIComponent.UserData as string;
string file2 = c2.GUIComponent.UserData as string;
DateTime file1WriteTime = DateTime.MinValue;
DateTime file2WriteTime = DateTime.MinValue;
try
{
file1WriteTime = File.GetLastWriteTime(file1);
}
catch
{
//do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list
};
try
{
file2WriteTime = File.GetLastWriteTime(file2);
}
catch
{
//do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list
};
return file2WriteTime.CompareTo(file1WriteTime);
});
SortSaveList();
loadGameButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.12f), loadGameContainer.RectTransform, Anchor.BottomRight), TextManager.Get("LoadButton"))
{
OnClicked = (btn, obj) =>
{
if (string.IsNullOrWhiteSpace(saveList.SelectedData as string)) { return false; }
LoadGame?.Invoke(saveList.SelectedData as string);
if (saveList.SelectedData is not CampaignMode.SaveInfo saveInfo) { return false; }
if (string.IsNullOrWhiteSpace(saveInfo.FilePath)) { return false; }
LoadGame?.Invoke(saveInfo.FilePath);
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
return true;
},
@@ -264,37 +243,20 @@ namespace Barotrauma
};
}
private bool SelectSaveFile(GUIComponent component, object obj)
{
string fileName = (string)obj;
if (obj is not CampaignMode.SaveInfo saveInfo) { return true; }
string fileName = saveInfo.FilePath;
loadGameButton.Enabled = true;
deleteMpSaveButton.Visible = deleteMpSaveButton.Enabled = GameMain.Client.IsServerOwner;
deleteMpSaveButton.Enabled = GameMain.GameSession?.SavePath != fileName;
if (deleteMpSaveButton.Visible)
{
deleteMpSaveButton.UserData = obj as string;
deleteMpSaveButton.UserData = saveInfo;
}
return true;
}
private bool DeleteSave(GUIButton button, object obj)
{
string saveFile = obj as string;
if (obj == null) { return false; }
var header = TextManager.Get("deletedialoglabel");
var body = TextManager.GetWithVariable("deletedialogquestion", "[file]", Path.GetFileNameWithoutExtension(saveFile));
EventEditorScreen.AskForConfirmation(header, body, () =>
{
SaveUtil.DeleteSave(saveFile);
prevSaveFiles?.RemoveAll(s => s.FilePath == saveFile);
UpdateLoadMenu(prevSaveFiles.ToList());
return true;
});
return true;
}
}
}
@@ -194,7 +194,7 @@ namespace Barotrauma
{
TextGetter = () =>
{
int initialMoney = CurrentSettings.InitialMoney;
int initialMoney = CampaignSettings.CurrentSettings.InitialMoney;
if (subList.SelectedData is SubmarineInfo subInfo)
{
initialMoney -= subInfo.Price;
@@ -208,15 +208,15 @@ namespace Barotrauma
{
OnClicked = (tb, userdata) =>
{
CreateCustomizeWindow(CurrentSettings, settings =>
CreateCustomizeWindow(CampaignSettings.CurrentSettings, settings =>
{
CampaignSettings prevSettings = CurrentSettings;
CurrentSettings = settings;
CampaignSettings prevSettings = CampaignSettings.CurrentSettings;
CampaignSettings.CurrentSettings = settings;
if (prevSettings.InitialMoney != settings.InitialMoney)
{
object selectedData = subList.SelectedData;
UpdateSubList(SubmarineInfo.SavedSubmarines);
if (selectedData is SubmarineInfo selectedSub && selectedSub.Price <= CurrentSettings.InitialMoney)
if (selectedData is SubmarineInfo selectedSub && selectedSub.Price <= CampaignSettings.CurrentSettings.InitialMoney)
{
subList.Select(selectedData);
}
@@ -375,6 +375,7 @@ namespace Barotrauma
{
onClosed?.Invoke(elements.CreateSettings());
GameSettings.SaveCurrentConfig();
return CampaignCustomizeSettings.Close(button, o);
};
}
@@ -399,7 +400,7 @@ namespace Barotrauma
SubmarineInfo selectedSub = null;
if (!(subList.SelectedData is SubmarineInfo)) { return false; }
if (subList.SelectedData is not SubmarineInfo) { return false; }
selectedSub = subList.SelectedData as SubmarineInfo;
if (selectedSub.SubmarineClass == SubmarineClass.Undefined)
@@ -419,7 +420,7 @@ namespace Barotrauma
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Singleplayer, saveNameBox.Text);
bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;
CampaignSettings settings = CurrentSettings;
CampaignSettings settings = CampaignSettings.CurrentSettings;
if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages)
{
@@ -476,7 +477,7 @@ namespace Barotrauma
{
foreach (GUIComponent child in subList.Content.Children)
{
if (!(child.UserData is SubmarineInfo sub)) { return; }
if (child.UserData is not SubmarineInfo sub) { return; }
child.Visible = string.IsNullOrEmpty(filter) || sub.DisplayName.Contains(filter.ToLower(), StringComparison.OrdinalIgnoreCase);
}
}
@@ -487,9 +488,9 @@ namespace Barotrauma
(subPreviewContainer.Parent as GUILayoutGroup)?.Recalculate();
subPreviewContainer.ClearChildren();
if (!(obj is SubmarineInfo sub)) { return true; }
if (obj is not SubmarineInfo sub) { return true; }
#if !DEBUG
if (sub.Price > CurrentSettings.InitialMoney && !GameMain.DebugDraw)
if (sub.Price > CampaignSettings.CurrentSettings.InitialMoney && !GameMain.DebugDraw)
{
SetPage(0);
nextButton.Enabled = false;
@@ -551,7 +552,7 @@ namespace Barotrauma
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), infoContainer.RectTransform),
TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", sub.Price)), textAlignment: Alignment.BottomRight, font: GUIStyle.SmallFont)
{
TextColor = sub.Price > CurrentSettings.InitialMoney ? GUIStyle.Red : textBlock.TextColor * 0.8f,
TextColor = sub.Price > CampaignSettings.CurrentSettings.InitialMoney ? GUIStyle.Red : textBlock.TextColor * 0.8f,
ToolTip = textBlock.ToolTip
};
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), infoContainer.RectTransform),
@@ -563,7 +564,7 @@ namespace Barotrauma
#if !DEBUG
if (!GameMain.DebugDraw)
{
if (sub.Price > CurrentSettings.InitialMoney || !sub.IsCampaignCompatible)
if (sub.Price > CampaignSettings.CurrentSettings.InitialMoney || !sub.IsCampaignCompatible)
{
textBlock.CanBeFocused = false;
textBlock.TextColor *= 0.5f;
@@ -573,7 +574,7 @@ namespace Barotrauma
}
if (SubmarineInfo.SavedSubmarines.Any())
{
var validSubs = subsToShow.Where(s => s.IsCampaignCompatible && s.Price <= CurrentSettings.InitialMoney).ToList();
var validSubs = subsToShow.Where(s => s.IsCampaignCompatible && s.Price <= CampaignSettings.CurrentSettings.InitialMoney).ToList();
if (validSubs.Count > 0)
{
subList.Select(validSubs[Rand.Int(validSubs.Count)]);
@@ -581,7 +582,7 @@ namespace Barotrauma
}
}
public void UpdateLoadMenu(IEnumerable<CampaignMode.SaveInfo> saveFiles = null)
public override void UpdateLoadMenu(IEnumerable<CampaignMode.SaveInfo> saveFiles = null)
{
prevSaveFiles?.Clear();
prevSaveFiles = null;
@@ -649,46 +650,27 @@ namespace Barotrauma
}
}
saveList.Content.RectTransform.SortChildren((c1, c2) =>
{
string file1 = c1.GUIComponent.UserData as string;
string file2 = c2.GUIComponent.UserData as string;
DateTime file1WriteTime = DateTime.MinValue;
DateTime file2WriteTime = DateTime.MinValue;
try
{
file1WriteTime = File.GetLastWriteTime(file1);
}
catch
{
//do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list
};
try
{
file2WriteTime = File.GetLastWriteTime(file2);
}
catch
{
//do nothing - DateTime.MinValue will be used and the element will get sorted at the bottom of the list
};
return file2WriteTime.CompareTo(file1WriteTime);
});
SortSaveList();
loadGameButton = new GUIButton(new RectTransform(new Vector2(0.45f, 0.12f), loadGameContainer.RectTransform, Anchor.BottomRight), TextManager.Get("LoadButton"))
{
OnClicked = (btn, obj) =>
{
if (string.IsNullOrWhiteSpace(saveList.SelectedData as string)) { return false; }
LoadGame?.Invoke(saveList.SelectedData as string);
if (saveList.SelectedData is not CampaignMode.SaveInfo saveInfo) { return false; }
if (string.IsNullOrWhiteSpace(saveInfo.FilePath)) { return false; }
LoadGame?.Invoke(saveInfo.FilePath);
return true;
},
Enabled = false
};
}
}
private bool SelectSaveFile(GUIComponent component, object obj)
{
string fileName = (string)obj;
if (obj is not CampaignMode.SaveInfo saveInfo) { return true; }
string fileName = saveInfo.FilePath;
XDocument doc = SaveUtil.LoadGameSessionDoc(fileName);
if (doc?.Root == null)
@@ -701,72 +683,55 @@ namespace Barotrauma
RemoveSaveFrame();
string subName = doc.Root.GetAttributeString("submarine", "");
string saveTime = doc.Root.GetAttributeString("savetime", "unknown");
DateTime? time = null;
if (long.TryParse(saveTime, out long unixTime))
{
time = ToolBox.Epoch.ToDateTime(unixTime);
saveTime = time.ToString();
}
string subName = saveInfo.SubmarineName;
LocalizedString saveTime = saveInfo.SaveTime
.Select(t => (LocalizedString)t.ToLocalUserString())
.Fallback(TextManager.Get("Unknown"));
string mapseed = doc.Root.GetAttributeString("mapseed", "unknown");
var saveFileFrame = new GUIFrame(new RectTransform(new Vector2(0.45f, 0.6f), loadGameContainer.RectTransform, Anchor.TopRight)
{
RelativeOffset = new Vector2(0.0f, 0.1f)
}, style: "InnerFrame")
var saveFileFrame = new GUIFrame(
new RectTransform(new Vector2(0.45f, 0.6f), loadGameContainer.RectTransform, Anchor.TopRight)
{
RelativeOffset = new Vector2(0.0f, 0.1f)
}, style: "InnerFrame")
{
UserData = "savefileframe"
};
var titleText = new GUITextBlock(new RectTransform(new Vector2(0.9f, 0.2f), saveFileFrame.RectTransform, Anchor.TopCenter)
{
RelativeOffset = new Vector2(0, 0.05f)
},
var titleText = new GUITextBlock(
new RectTransform(new Vector2(0.9f, 0.2f), saveFileFrame.RectTransform, Anchor.TopCenter)
{
RelativeOffset = new Vector2(0, 0.05f)
},
Path.GetFileNameWithoutExtension(fileName), font: GUIStyle.LargeFont, textAlignment: Alignment.Center);
titleText.Text = ToolBox.LimitString(titleText.Text, titleText.Font, titleText.Rect.Width);
var layoutGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.5f), saveFileFrame.RectTransform, Anchor.Center)
{
RelativeOffset = new Vector2(0, 0.1f)
});
var layoutGroup = new GUILayoutGroup(
new RectTransform(new Vector2(0.8f, 0.5f), saveFileFrame.RectTransform, Anchor.Center)
{
RelativeOffset = new Vector2(0, 0.1f)
});
new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform), $"{TextManager.Get("Submarine")} : {subName}", font: GUIStyle.SmallFont);
new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform), $"{TextManager.Get("LastSaved")} : {saveTime}", font: GUIStyle.SmallFont);
new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform), $"{TextManager.Get("MapSeed")} : {mapseed}", font: GUIStyle.SmallFont);
new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform),
$"{TextManager.Get("Submarine")} : {subName}", font: GUIStyle.SmallFont);
new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform),
$"{TextManager.Get("LastSaved")} : {saveTime}", font: GUIStyle.SmallFont);
new GUITextBlock(new RectTransform(new Vector2(1, 0), layoutGroup.RectTransform),
$"{TextManager.Get("MapSeed")} : {mapseed}", font: GUIStyle.SmallFont);
new GUIButton(new RectTransform(new Vector2(0.4f, 0.15f), saveFileFrame.RectTransform, Anchor.BottomCenter)
{
RelativeOffset = new Vector2(0, 0.1f)
}, TextManager.Get("Delete"), style: "GUIButtonSmall")
{
UserData = fileName,
UserData = saveInfo,
OnClicked = DeleteSave
};
return true;
}
private bool DeleteSave(GUIButton button, object obj)
{
string saveFile = obj as string;
if (obj == null) { return false; }
LocalizedString header = TextManager.Get("deletedialoglabel");
LocalizedString body = TextManager.GetWithVariable("deletedialogquestion", "[file]", Path.GetFileNameWithoutExtension(saveFile));
EventEditorScreen.AskForConfirmation(header, body, () =>
{
SaveUtil.DeleteSave(saveFile);
prevSaveFiles?.RemoveAll(s => s.FilePath == saveFile);
UpdateLoadMenu(prevSaveFiles.ToList());
return true;
});
return true;
}
private void RemoveSaveFrame()
{
GUIComponent prevFrame = null;
@@ -352,7 +352,7 @@ namespace Barotrauma
if (!availableMissions.Any()) { availableMissions.Insert(0, null); }
availableMissions.AddRange(location.AvailableMissions);
availableMissions.AddRange(location.AvailableMissions.Where(m => m.Locations[0] == m.Locations[1]));
missionList.Content.ClearChildren();
@@ -571,7 +571,7 @@ namespace Barotrauma
//locationInfoPanel?.UpdateAuto(1.0f);
}
public void SelectTab(CampaignMode.InteractionType tab, Identifier storeIdentifier = default)
public void SelectTab(CampaignMode.InteractionType tab, Character npc = null)
{
if (Campaign.ShowCampaignUI || (Campaign.ForceMapUI && tab == CampaignMode.InteractionType.Map))
{
@@ -592,7 +592,7 @@ namespace Barotrauma
switch (selectedTab)
{
case CampaignMode.InteractionType.Store:
Store.SelectStore(storeIdentifier);
Store.SelectStore(npc);
break;
case CampaignMode.InteractionType.Crew:
CrewManagement.UpdateCrew();
@@ -602,6 +602,7 @@ namespace Barotrauma
submarineSelection.RefreshSubmarineDisplay(true, setTransferOptionToTrue: true);
break;
case CampaignMode.InteractionType.Map:
GameMain.GameSession?.Map?.ResetPendingSub();
//refresh mission rewards (may have been changed by e.g. a pending submarine switch)
foreach (GUITextBlock rewardText in missionRewardTexts)
{
@@ -25,14 +25,11 @@ namespace Barotrauma.CharacterEditor
{
get
{
if (cam == null)
cam ??= new Camera()
{
cam = new Camera()
{
MinZoom = 0.1f,
MaxZoom = 5.0f
};
}
MinZoom = 0.1f,
MaxZoom = 5.0f
};
return cam;
}
}
@@ -90,26 +87,26 @@ namespace Barotrauma.CharacterEditor
private float spriteSheetZoom = 1;
private float spriteSheetMinZoom = 0.25f;
private float spriteSheetMaxZoom = 1;
private int spriteSheetOffsetY = 20;
private int spriteSheetOffsetX = 30;
private const int spriteSheetOffsetY = 20;
private const int spriteSheetOffsetX = 30;
private bool hideBodySheet;
private Color backgroundColor = new Color(0.2f, 0.2f, 0.2f, 1.0f);
private Vector2 cameraOffset;
private List<LimbJoint> selectedJoints = new List<LimbJoint>();
private List<Limb> selectedLimbs = new List<Limb>();
private HashSet<Character> editedCharacters = new HashSet<Character>();
private readonly List<LimbJoint> selectedJoints = new List<LimbJoint>();
private readonly List<Limb> selectedLimbs = new List<Limb>();
private readonly HashSet<Character> editedCharacters = new HashSet<Character>();
private bool isEndlessRunner;
private Rectangle spriteSheetRect;
private Rectangle CalculateSpritesheetRectangle() =>
private Rectangle CalculateSpritesheetRectangle() =>
Textures == null || Textures.None() ? Rectangle.Empty :
new Rectangle(
spriteSheetOffsetX,
spriteSheetOffsetY,
(int)(Textures.OrderByDescending(t => t.Width).First().Width * spriteSheetZoom),
spriteSheetOffsetX,
spriteSheetOffsetY,
(int)(Textures.OrderByDescending(t => t.Width).First().Width * spriteSheetZoom),
(int)(Textures.Sum(t => t.Height) * spriteSheetZoom));
private const string screenTextTag = "CharacterEditor.";
@@ -146,7 +143,7 @@ namespace Barotrauma.CharacterEditor
var humanSpeciesName = CharacterPrefab.HumanSpeciesName;
if (humanSpeciesName.IsEmpty)
{
SpawnCharacter(AllSpecies.First());
SpawnCharacter(VisibleSpecies.First());
}
else
{
@@ -195,7 +192,7 @@ namespace Barotrauma.CharacterEditor
jointEndLimb = null;
anchor1Pos = null;
jointStartLimb = null;
allSpecies = null;
visibleSpecies = null;
onlyShowSourceRectForSelectedLimbs = false;
unrestrictSpritesheet = false;
editedCharacters.Clear();
@@ -217,15 +214,12 @@ namespace Barotrauma.CharacterEditor
private void Reset(IEnumerable<Character> characters = null)
{
if (characters == null)
{
characters = editedCharacters;
}
characters ??= editedCharacters;
characters.ForEach(c => ResetParams(c));
ResetVariables();
}
private void ResetParams(Character character)
private static void ResetParams(Character character)
{
character.Params.Reset(true);
foreach (var animation in character.AnimController.AllAnimParams)
@@ -262,7 +256,10 @@ namespace Barotrauma.CharacterEditor
#endif
}
GameMain.Instance.ResolutionChanged -= OnResolutionChanged;
GameMain.LightManager.LightingEnabled = true;
if (!GameMain.DevMode)
{
GameMain.LightManager.LightingEnabled = true;
}
ClearWidgets();
ClearSelection();
}
@@ -280,6 +277,7 @@ namespace Barotrauma.CharacterEditor
#region Main methods
public override void AddToGUIUpdateList()
{
if (rightArea == null || leftArea == null) { return; }
rightArea.AddToGUIUpdateList();
leftArea.AddToGUIUpdateList();
@@ -718,7 +716,7 @@ namespace Barotrauma.CharacterEditor
cameraOffset = Vector2.Clamp(cameraOffset, min, max);
}
Cam.Position = targetPos + cameraOffset;
MapEntity.mapEntityList.ForEach(e => e.IsHighlighted = false);
MapEntity.ClearHighlightedEntities();
// Update widgets
jointSelectionWidgets.Values.ForEach(w => w.Update((float)deltaTime));
limbEditWidgets.Values.ForEach(w => w.Update((float)deltaTime));
@@ -778,7 +776,7 @@ namespace Barotrauma.CharacterEditor
scaledMouseSpeed = PlayerInput.MouseSpeedPerSecond * (float)deltaTime;
Cam.UpdateTransform(true);
Submarine.CullEntities(Cam);
Submarine.MainSub.UpdateTransform();
Submarine.MainSub?.UpdateTransform();
// Lightmaps
if (GameMain.LightManager.LightingEnabled)
@@ -1362,7 +1360,7 @@ namespace Barotrauma.CharacterEditor
private class WallGroup
{
public readonly List<Structure> walls;
public WallGroup(List<Structure> walls)
{
this.walls = walls;
@@ -1373,7 +1371,7 @@ namespace Barotrauma.CharacterEditor
var clones = new List<Structure>();
walls.ForEachMod(w => clones.Add(w.Clone() as Structure));
return new WallGroup(clones);
}
}
}
private void CloneWalls()
@@ -1390,7 +1388,7 @@ namespace Barotrauma.CharacterEditor
else if (i == 2)
{
clones[i].walls[j].Move(new Vector2(-originalWall.walls[j].Rect.Width, 0));
}
}
}
}
}
@@ -1403,8 +1401,8 @@ namespace Barotrauma.CharacterEditor
private WallGroup SelectLastClone(bool right)
{
var lastWall = right
? clones.SelectMany(c => c.walls).OrderBy(w => w.Rect.Right).Last()
var lastWall = right
? clones.SelectMany(c => c.walls).OrderBy(w => w.Rect.Right).Last()
: clones.SelectMany(c => c.walls).OrderBy(w => w.Rect.Left).First();
return clones.Where(c => c.walls.Contains(lastWall)).FirstOrDefault();
}
@@ -1439,33 +1437,35 @@ namespace Barotrauma.CharacterEditor
private Identifier currentCharacterIdentifier;
private Identifier selectedJob = Identifier.Empty;
private List<Identifier> allSpecies;
private List<Identifier> AllSpecies
private List<Identifier> visibleSpecies;
private List<Identifier> VisibleSpecies
{
get
{
if (allSpecies == null)
{
#if DEBUG
allSpecies = CharacterPrefab.Prefabs.Keys.OrderBy(p => p).ToList();
#else
allSpecies = CharacterPrefab.Prefabs.Keys.Where(p => !p.Contains("variant")).OrderBy(p => p).ToList();
#endif
allSpecies.ForEach(f => DebugConsole.NewMessage(f.Value, Color.White));
}
return allSpecies;
visibleSpecies ??= CharacterPrefab.Prefabs.Where(ShowCreature).OrderBy(p => p.Identifier).Select(p => p.Identifier).ToList();
return visibleSpecies;
}
}
private List<CharacterFile> vanillaCharacters;
private List<CharacterFile> VanillaCharacters
private bool ShowCreature(CharacterPrefab prefab)
{
Identifier speciesName = prefab.Identifier;
if (speciesName == CharacterPrefab.HumanSpeciesName) { return true; }
if (!VanillaCharacters.Contains(prefab.ContentFile))
{
// Always show all custom characters.
return true;
}
if (CreatureMetrics.UnlockAll) { return true; }
return CreatureMetrics.Unlocked.Contains(speciesName);
}
private IEnumerable<CharacterFile> vanillaCharacters;
private IEnumerable<CharacterFile> VanillaCharacters
{
get
{
if (vanillaCharacters == null)
{
vanillaCharacters = GameMain.VanillaContent.GetFiles<CharacterFile>().ToList();
}
vanillaCharacters ??= GameMain.VanillaContent.GetFiles<CharacterFile>();
return vanillaCharacters;
}
}
@@ -1474,7 +1474,7 @@ namespace Barotrauma.CharacterEditor
{
GetCurrentCharacterIndex();
IncreaseIndex();
currentCharacterIdentifier = AllSpecies[characterIndex];
currentCharacterIdentifier = VisibleSpecies[characterIndex];
return currentCharacterIdentifier;
}
@@ -1482,19 +1482,19 @@ namespace Barotrauma.CharacterEditor
{
GetCurrentCharacterIndex();
ReduceIndex();
currentCharacterIdentifier = AllSpecies[characterIndex];
currentCharacterIdentifier = VisibleSpecies[characterIndex];
return currentCharacterIdentifier;
}
private void GetCurrentCharacterIndex()
{
characterIndex = AllSpecies.IndexOf(character.SpeciesName);
characterIndex = VisibleSpecies.IndexOf(character.SpeciesName);
}
private void IncreaseIndex()
{
characterIndex++;
if (characterIndex > AllSpecies.Count - 1)
if (characterIndex > VisibleSpecies.Count - 1)
{
characterIndex = 0;
}
@@ -1505,7 +1505,7 @@ namespace Barotrauma.CharacterEditor
characterIndex--;
if (characterIndex < 0)
{
characterIndex = AllSpecies.Count - 1;
characterIndex = VisibleSpecies.Count - 1;
}
}
@@ -1570,10 +1570,7 @@ namespace Barotrauma.CharacterEditor
{
wayPoint = WayPoint.GetRandom(spawnType: SpawnType.Human, sub: Submarine.MainSub);
}
if (wayPoint == null)
{
wayPoint = WayPoint.GetRandom(sub: Submarine.MainSub);
}
wayPoint ??= WayPoint.GetRandom(sub: Submarine.MainSub);
spawnPosition = wayPoint.WorldPosition;
}
@@ -1689,7 +1686,7 @@ namespace Barotrauma.CharacterEditor
XElement overrideElement = null;
if (duplicate != null)
{
allSpecies = null;
visibleSpecies = null;
if (!File.Exists(configFilePath))
{
// If the file exists, we just want to overwrite it.
@@ -1825,9 +1822,9 @@ namespace Barotrauma.CharacterEditor
AnimationParams.Create(fullPath, name, animType, type);
}
}
if (!AllSpecies.Contains(name))
if (!VisibleSpecies.Contains(name))
{
AllSpecies.Add(name);
VisibleSpecies.Add(name);
}
SpawnCharacter(name, ragdollParams);
limbPairEditing = false;
@@ -2680,23 +2677,33 @@ namespace Barotrauma.CharacterEditor
{
Stretch = true
};
// Character selection
var characterLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), GetCharacterEditorTranslation("CharacterPanel"), font: GUIStyle.LargeFont);
var characterDropDown = new GUIDropDown(new RectTransform(new Vector2(1, 0.2f), content.RectTransform)
{
RelativeOffset = new Vector2(0, 0.2f)
}, elementCount: 8, style: null);
characterDropDown.ListBox.Color = new Color(characterDropDown.ListBox.Color.R, characterDropDown.ListBox.Color.G, characterDropDown.ListBox.Color.B, byte.MaxValue);
foreach (var file in AllSpecies)
foreach (CharacterPrefab prefab in CharacterPrefab.Prefabs.OrderByDescending(p => p.Identifier))
{
characterDropDown.AddItem(file.Value.CapitaliseFirstInvariant(), file);
Identifier speciesName = prefab.Identifier;
if (ShowCreature(prefab))
{
characterDropDown.AddItem(speciesName.Value.CapitaliseFirstInvariant(), speciesName).SetAsFirstChild();
}
else if (!CreatureMetrics.Encountered.Contains(speciesName))
{
// Using a matching placeholder string here ("hidden").
var element = characterDropDown.AddItem(TextManager.Get("hiddensubmarines"), Identifier.Empty, textColor: Color.Gray * 0.75f);
element.SetAsLastChild();
element.Enabled = false;
}
}
characterDropDown.SelectItem(currentCharacterIdentifier);
characterDropDown.OnSelected = (component, data) =>
{
Identifier characterIdentifier = (Identifier)data;
if (characterIdentifier.IsEmpty) { return true; }
try
{
SpawnCharacter(characterIdentifier);
@@ -2797,7 +2804,7 @@ namespace Barotrauma.CharacterEditor
saveAllButton.OnClicked += (button, userData) =>
{
#if !DEBUG
if (VanillaCharacters != null && VanillaCharacters.Contains(CharacterPrefab.Prefabs[currentCharacterIdentifier].ContentFile))
if (VanillaCharacters.Contains(CharacterPrefab.Prefabs[currentCharacterIdentifier].ContentFile))
{
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), GUIStyle.Red, font: GUIStyle.LargeFont);
return false;
@@ -2837,7 +2844,7 @@ namespace Barotrauma.CharacterEditor
box.Buttons[1].OnClicked += (b, d) =>
{
#if !DEBUG
if (VanillaCharacters != null && VanillaCharacters.Contains(CharacterPrefab.Prefabs[currentCharacterIdentifier].ContentFile))
if (VanillaCharacters.Contains(CharacterPrefab.Prefabs[currentCharacterIdentifier].ContentFile))
{
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), GUIStyle.Red, font: GUIStyle.LargeFont);
box.Close();
@@ -2975,7 +2982,7 @@ namespace Barotrauma.CharacterEditor
box.Buttons[1].OnClicked += (b, d) =>
{
#if !DEBUG
if (VanillaCharacters != null && VanillaCharacters.Contains(CharacterPrefab.Prefabs[currentCharacterIdentifier].ContentFile))
if (VanillaCharacters.Contains(CharacterPrefab.Prefabs[currentCharacterIdentifier].ContentFile))
{
GUI.AddMessage(GetCharacterEditorTranslation("CannotEditVanillaCharacters"), GUIStyle.Red, font: GUIStyle.LargeFont);
box.Close();
@@ -3214,7 +3221,7 @@ namespace Barotrauma.CharacterEditor
Wizard.Instance.CopyExisting(CharacterParams, RagdollParams, AnimParams);
}
#region ToggleButtons
#region ToggleButtons
private enum Direction
{
Left,
@@ -3998,7 +4005,7 @@ namespace Barotrauma.CharacterEditor
};
}).Draw(spriteBatch, deltaTime);
}
else
else if (groundedParams != null)
{
GetAnimationWidget("HeadPosition", color, Color.Black, initMethod: w =>
{
@@ -4107,7 +4114,7 @@ namespace Barotrauma.CharacterEditor
};
}).Draw(spriteBatch, deltaTime);
}
else
else if (groundedParams != null)
{
GetAnimationWidget("TorsoPosition", color, Color.Black, initMethod: w =>
{
@@ -6,7 +6,7 @@ namespace Barotrauma
{
private GUIListBox listBox;
private ContentXElement configElement;
private readonly ContentXElement configElement;
private float scrollSpeed;
@@ -35,6 +35,8 @@ namespace Barotrauma
set { listBox.BarScroll = value; }
}
public readonly GUIButton CloseButton;
public CreditsPlayer(RectTransform rectT, string configFile) : base(null, rectT)
{
@@ -49,6 +51,10 @@ namespace Barotrauma
configElement = doc.Root.FromPackage(ContentPackageManager.VanillaCorePackage);
Load();
CloseButton = new GUIButton(new RectTransform(new Vector2(0.1f), RectTransform, Anchor.BottomRight, maxSize: new Point(GUI.IntScale(300), GUI.IntScale(50)))
{ AbsoluteOffset = new Point(GUI.IntScale(20), GUI.IntScale(20) + (Rect.Bottom - GameMain.GraphicsHeight)) },
TextManager.Get("close"));
}
private void Load()
@@ -1,7 +1,6 @@
using Barotrauma.Extensions;
using Barotrauma.Lights;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Diagnostics;
@@ -28,7 +27,7 @@ namespace Barotrauma
public Effect ThresholdTintEffect { get; private set; }
public Effect BlueprintEffect { get; set; }
public GameScreen(GraphicsDevice graphics, ContentManager content)
public GameScreen(GraphicsDevice graphics)
{
cam = new Camera();
cam.Translate(new Vector2(-10.0f, 50.0f));
@@ -39,20 +38,13 @@ namespace Barotrauma
CreateRenderTargets(graphics);
};
Effect LoadEffect(string path)
=> content.Load<Effect>(path
#if LINUX || OSX
+"_opengl"
#endif
);
//var blurEffect = LoadEffect("Effects/blurshader");
damageEffect = LoadEffect("Effects/damageshader");
PostProcessEffect = LoadEffect("Effects/postprocess");
GradientEffect = LoadEffect("Effects/gradientshader");
GrainEffect = LoadEffect("Effects/grainshader");
ThresholdTintEffect = LoadEffect("Effects/thresholdtint");
BlueprintEffect = LoadEffect("Effects/blueprintshader");
damageEffect = EffectLoader.Load("Effects/damageshader");
PostProcessEffect = EffectLoader.Load("Effects/postprocess");
GradientEffect = EffectLoader.Load("Effects/gradientshader");
GrainEffect = EffectLoader.Load("Effects/grainshader");
ThresholdTintEffect = EffectLoader.Load("Effects/thresholdtint");
BlueprintEffect = EffectLoader.Load("Effects/blueprintshader");
damageStencil = TextureLoader.FromFile("Content/Map/walldamage.png");
damageEffect.Parameters["xStencil"].SetValue(damageStencil);
@@ -46,7 +46,7 @@ namespace Barotrauma
private GUITextBox serverNameBox, passwordBox, maxPlayersBox;
private GUITickBox isPublicBox, wrongPasswordBanBox, karmaBox;
private GUIDropDown serverExecutableDropdown;
private GUIDropDown languageDropdown, serverExecutableDropdown;
private readonly GUIButton joinServerButton, hostServerButton;
private readonly GUIFrame modsButtonContainer;
@@ -466,6 +466,11 @@ namespace Barotrauma
var creditsContainer = new GUIFrame(new RectTransform(new Vector2(0.75f, 1.5f), menuTabs[Tab.Credits].RectTransform, Anchor.CenterRight), style: "OuterGlow", color: Color.Black * 0.8f);
creditsPlayer = new CreditsPlayer(new RectTransform(Vector2.One, creditsContainer.RectTransform), "Content/Texts/Credits.xml");
creditsPlayer.CloseButton.OnClicked = (btn, userdata) =>
{
SelectTab(Tab.Empty);
return true;
};
}
private void CreateTutorialTab()
@@ -893,12 +898,14 @@ namespace Barotrauma
#endif
}
string arguments = "-name \"" + ToolBox.EscapeCharacters(name) + "\"" +
" -public " + isPublicBox.Selected.ToString() +
" -playstyle " + ((PlayStyle)playstyleBanner.UserData).ToString() +
" -banafterwrongpassword " + wrongPasswordBanBox.Selected.ToString() +
" -karmaenabled " + (!karmaBox.Selected).ToString() +
" -maxplayers " + maxPlayersBox.Text;
string arguments =
"-name \"" + ToolBox.EscapeCharacters(name) + "\"" +
" -public " + isPublicBox.Selected.ToString() +
" -playstyle " + ((PlayStyle)playstyleBanner.UserData).ToString() +
" -banafterwrongpassword " + wrongPasswordBanBox.Selected.ToString() +
" -karmaenabled " + (!karmaBox.Selected).ToString() +
" -maxplayers " + maxPlayersBox.Text +
$" -language \"{(LanguageIdentifier)languageDropdown.SelectedData}\"";
if (!string.IsNullOrWhiteSpace(passwordBox.Text))
{
@@ -994,7 +1001,7 @@ namespace Barotrauma
|| item.IsDownloadPending
|| (item.InstallTime.TryGetValue(out var workshopInstallTime)
&& pkg.InstallTime.TryUnwrap(out var localInstallTime)
&& localInstallTime < workshopInstallTime)));
&& localInstallTime.ToUtcValue() < workshopInstallTime)));
modUpdateStatus = (DateTime.Now + ModUpdateInterval, count);
}
@@ -1099,7 +1106,7 @@ namespace Barotrauma
if (i == 0)
{
GUI.DrawLine(spriteBatch, textPos, textPos - Vector2.UnitX * textSize.X, mouseOn ? Color.White : Color.White * 0.7f);
if (mouseOn && PlayerInput.PrimaryMouseButtonClicked())
if (mouseOn && PlayerInput.PrimaryMouseButtonClicked() && GUI.MouseOn == null)
{
GameMain.ShowOpenUrlInWebBrowserPrompt("http://privacypolicy.daedalic.com");
}
@@ -1204,45 +1211,28 @@ namespace Barotrauma
{
menuTabs[Tab.HostServer].ClearChildren();
string name = "";
string password = "";
int maxPlayers = 8;
bool isPublic = true;
bool banAfterWrongPassword = false;
bool karmaEnabled = true;
string selectedKarmaPreset = "";
PlayStyle selectedPlayStyle = PlayStyle.Casual;
if (File.Exists(ServerSettings.SettingsFile))
var serverSettings = XMLExtensions.TryLoadXml(ServerSettings.SettingsFile, out _)?.Root ?? new XElement("serversettings");
var name = serverSettings.GetAttributeString("name", "");
var password = serverSettings.GetAttributeString("password", "");
var isPublic = serverSettings.GetAttributeBool("IsPublic", true);
var banAfterWrongPassword = serverSettings.GetAttributeBool("banafterwrongpassword", false);
int maxPlayersElement = serverSettings.GetAttributeInt("maxplayers", 8);
if (maxPlayersElement > NetConfig.MaxPlayers)
{
XDocument settingsDoc = XMLExtensions.TryLoadXml(ServerSettings.SettingsFile);
if (settingsDoc != null)
{
name = settingsDoc.Root.GetAttributeString("name", name);
password = settingsDoc.Root.GetAttributeString("password", password);
isPublic = settingsDoc.Root.GetAttributeBool("public", isPublic);
banAfterWrongPassword = settingsDoc.Root.GetAttributeBool("banafterwrongpassword", banAfterWrongPassword);
int maxPlayersElement = settingsDoc.Root.GetAttributeInt("maxplayers", maxPlayers);
if (maxPlayersElement > NetConfig.MaxPlayers)
{
DebugConsole.IsOpen = true;
DebugConsole.NewMessage($"Setting the maximum amount of players to {maxPlayersElement} failed due to exceeding the limit of {NetConfig.MaxPlayers} players per server. Using the maximum of {NetConfig.MaxPlayers} instead.", Color.Red);
maxPlayersElement = NetConfig.MaxPlayers;
}
maxPlayers = maxPlayersElement;
karmaEnabled = settingsDoc.Root.GetAttributeBool("karmaenabled", true);
selectedKarmaPreset = settingsDoc.Root.GetAttributeString("karmapreset", "default");
string playStyleStr = settingsDoc.Root.GetAttributeString("playstyle", "Casual");
Enum.TryParse(playStyleStr, out selectedPlayStyle);
}
DebugConsole.AddWarning($"Setting the maximum amount of players to {maxPlayersElement} failed due to exceeding the limit of {NetConfig.MaxPlayers} players per server. Using the maximum of {NetConfig.MaxPlayers} instead.");
}
int maxPlayers = Math.Clamp(maxPlayersElement, min: 1, max: NetConfig.MaxPlayers);
var karmaEnabled = serverSettings.GetAttributeBool("karmaenabled", true);
var selectedPlayStyle = serverSettings.GetAttributeEnum("playstyle", PlayStyle.Casual);
Vector2 textLabelSize = new Vector2(1.0f, 0.05f);
Alignment textAlignment = Alignment.CenterLeft;
Vector2 textFieldSize = new Vector2(0.5f, 1.0f);
Vector2 tickBoxSize = new Vector2(0.4f, 0.04f);
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 0.9f), menuTabs[Tab.HostServer].RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.7f, 0.95f), menuTabs[Tab.HostServer].RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter)
{
RelativeSpacing = 0.01f,
Stretch = true
@@ -1320,7 +1310,7 @@ namespace Barotrauma
//other settings -----------------------------------------------------
//spacing
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.05f), content.RectTransform), style: null);
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.025f), content.RectTransform), style: null);
var label = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform), TextManager.Get("ServerName"), textAlignment: textAlignment);
serverNameBox = new GUITextBox(new RectTransform(textFieldSize, label.RectTransform, Anchor.CenterRight), text: name, textAlignment: textAlignment)
@@ -1372,6 +1362,21 @@ namespace Barotrauma
};
label.RectTransform.IsFixedSize = true;
var languageLabel = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform),
TextManager.Get("Language"), textAlignment: textAlignment);
languageDropdown = new GUIDropDown(new RectTransform(textFieldSize, languageLabel.RectTransform, Anchor.CenterRight));
foreach (var language in ServerLanguageOptions.Options)
{
languageDropdown.AddItem(language.Label, language.Identifier);
}
var defaultLanguage = ServerLanguageOptions.PickLanguage(GameSettings.CurrentConfig.Language);
var settingsLanguage = serverSettings.GetAttributeIdentifier("language", defaultLanguage.Value).ToLanguageIdentifier();
if (!ServerLanguageOptions.Options.Any(o => o.Identifier == settingsLanguage))
{
settingsLanguage = defaultLanguage;
}
languageDropdown.Select(ServerLanguageOptions.Options.FindIndex(o => o.Identifier == settingsLanguage));
var serverExecutableLabel = new GUITextBlock(new RectTransform(textLabelSize, parent.RectTransform),
TextManager.Get("ServerExecutable"), textAlignment: textAlignment);
const string vanillaServerOption = "Vanilla";
@@ -189,7 +189,8 @@ namespace Barotrauma
}
public IReadOnlyList<SubmarineInfo> GetSubList()
=> SubList.Content.Children.Select(c => c.UserData as SubmarineInfo).ToArray();
=> (IReadOnlyList<SubmarineInfo>)GameMain.Client?.ServerSubmarines
?? Array.Empty<SubmarineInfo>();
public readonly GUIListBox PlayerList;
@@ -300,7 +301,7 @@ namespace Barotrauma
levelSeed = value;
int intSeed = ToolBox.StringToInt(levelSeed);
backgroundSprite = LocationType.Random(new MTRandom(intSeed))?.GetPortrait(intSeed);
backgroundSprite = LocationType.Random(new MTRandom(intSeed), predicate: lt => lt.UsePortraitInRandomLoadingScreens)?.GetPortrait(intSeed);
SeedBox.Text = levelSeed;
}
}
@@ -929,6 +930,8 @@ namespace Barotrauma
var modeTitle = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), modeContent.RectTransform), mode.Name, font: GUIStyle.SubHeadingFont);
var modeDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), modeContent.RectTransform), mode.Description, font: GUIStyle.SmallFont, wrap: true);
//leave some padding for the vote count text
modeDescription.Padding = new Vector4(modeDescription.Padding.X, modeDescription.Padding.Y, GUI.IntScale(30), modeDescription.Padding.W);
modeTitle.HoverColor = modeDescription.HoverColor = modeTitle.SelectedColor = modeDescription.SelectedColor = Color.Transparent;
modeTitle.HoverTextColor = modeDescription.HoverTextColor = modeTitle.TextColor;
modeTitle.TextColor = modeDescription.TextColor = modeTitle.TextColor * 0.5f;
@@ -981,7 +984,7 @@ namespace Barotrauma
}
else
{
GameMain.Client.RequestSelectMode(ModeList.Content.GetChildIndex(ModeList.Content.GetChildByUserData(GameModePreset.Sandbox)));
GameMain.Client.RequestRoundEnd(save: false, quitCampaign: true);
}
return true;
}
@@ -1931,7 +1934,7 @@ namespace Barotrauma
var selectedSub = component.UserData as SubmarineInfo;
if (SelectedMode == GameModePreset.MultiPlayerCampaign && CampaignSetupUI != null)
{
if (selectedSub.Price > CampaignSetupUI.CurrentSettings.InitialMoney)
if (selectedSub.Price > CampaignSettings.CurrentSettings.InitialMoney)
{
new GUIMessageBox(TextManager.Get("warning"), TextManager.Get("campaignsubtooexpensive"));
}
@@ -3289,16 +3292,15 @@ namespace Barotrauma
{
//campaign running
settingsBlocker.Visible = true;
CampaignFrame.Visible = GameMain.Client.HasPermission(ClientPermissions.ManageCampaign);
ContinueCampaignButton.Enabled = !GameMain.Client.GameStarted && (GameMain.Client.HasPermission(ClientPermissions.ManageCampaign) || GameMain.Client.HasPermission(ClientPermissions.ManageRound));
QuitCampaignButton.Enabled = GameMain.Client.HasPermission(ClientPermissions.ManageCampaign);
CampaignFrame.Visible = QuitCampaignButton.Enabled = CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageRound);
ContinueCampaignButton.Enabled = !GameMain.Client.GameStarted && CampaignFrame.Visible;
CampaignSetupFrame.Visible = false;
}
else
{
CampaignFrame.Visible = false;
CampaignSetupFrame.Visible = true;
if (!GameMain.Client.HasPermission(ClientPermissions.ManageCampaign))
if (!CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageRound))
{
CampaignSetupFrame.ClearChildren();
new GUITextBlock(new RectTransform(new Vector2(0.8f, 0.5f), CampaignSetupFrame.RectTransform, Anchor.Center),
@@ -3311,7 +3313,7 @@ namespace Barotrauma
foreach (var subElement in SubList.Content.Children)
{
var sub = subElement.UserData as SubmarineInfo;
bool tooExpensive = sub.Price > CampaignSetupUI.CurrentSettings.InitialMoney;
bool tooExpensive = sub.Price > CampaignSettings.CurrentSettings.InitialMoney;
if (tooExpensive || !sub.IsCampaignCompatible)
{
foreach (var textBlock in subElement.GetAllChildren<GUITextBlock>())
@@ -3362,7 +3364,7 @@ namespace Barotrauma
CampaignFrame.Visible = CampaignSetupFrame.Visible = false;
}
RefreshEnabledElements();
if (enabled)
if (enabled && SelectedMode != GameModePreset.MultiPlayerCampaign)
{
ModeList.Select(GameModePreset.MultiPlayerCampaign, GUIListBox.Force.Yes);
}
@@ -7,8 +7,6 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Xml.Linq;
namespace Barotrauma
@@ -241,6 +239,7 @@ namespace Barotrauma
private GUITickBox filterPassword;
private GUITickBox filterFull;
private GUITickBox filterEmpty;
private GUIDropDown languageDropdown;
private Dictionary<Identifier, GUIDropDown> ternaryFilters;
private Dictionary<Identifier, GUITickBox> filterTickBoxes;
private Dictionary<Identifier, GUITickBox> playStyleTickBoxes;
@@ -255,6 +254,7 @@ namespace Barotrauma
private TernaryOption filterModdedValue = TernaryOption.Any;
private ColumnLabel sortedBy;
private bool sortedAscending = true;
private const float sidebarWidth = 0.2f;
public ServerListScreen()
@@ -425,10 +425,13 @@ namespace Barotrauma
ternaryFilters = new Dictionary<Identifier, GUIDropDown>();
filterTickBoxes = new Dictionary<Identifier, GUITickBox>();
RectTransform createFilterRectT()
=> new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform);
GUITickBox addTickBox(Identifier key, LocalizedString text = null, bool defaultState = false, bool addTooltip = false)
{
text ??= TextManager.Get(key);
var tickBox = new GUITickBox(new RectTransform(new Vector2(1.0f, elementHeight), filters.Content.RectTransform), text)
var tickBox = new GUITickBox(createFilterRectT(), text)
{
UserData = text,
Selected = defaultState,
@@ -450,6 +453,109 @@ namespace Barotrauma
filterEmpty = addTickBox("FilterEmptyServers".ToIdentifier());
filterOffensive = addTickBox("FilterOffensiveServers".ToIdentifier());
// Language filter
if (ServerLanguageOptions.Options.Any())
{
var languageKey = "Language".ToIdentifier();
var allLanguagesKey = "AllLanguages".ToIdentifier();
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get(languageKey), font: GUIStyle.SubHeadingFont)
{
CanBeFocused = false
};
languageDropdown = new GUIDropDown(createFilterRectT(), selectMultiple: true);
languageDropdown.AddItem(TextManager.Get(allLanguagesKey), allLanguagesKey);
var allTickbox = languageDropdown.ListBox.Content.FindChild(allLanguagesKey)?.GetChild<GUITickBox>();
// Spacer between "All" and the individual languages
new GUIFrame(new RectTransform(new Vector2(1.0f, 0.0f), languageDropdown.ListBox.Content.RectTransform)
{
MinSize = new Point(0, GUI.IntScaleCeiling(2))
}, style: null)
{
Color = Color.DarkGray,
CanBeFocused = false
};
var selectedLanguages
= ServerListFilters.Instance.GetAttributeLanguageIdentifierArray(
languageKey,
Array.Empty<LanguageIdentifier>());
foreach (var (label, identifier, _) in ServerLanguageOptions.Options)
{
languageDropdown.AddItem(label, identifier);
}
if (!selectedLanguages.Any())
{
selectedLanguages = ServerLanguageOptions.Options.Select(o => o.Identifier).ToArray();
}
foreach (var lang in selectedLanguages)
{
languageDropdown.SelectItem(lang);
}
if (ServerLanguageOptions.Options.All(o => selectedLanguages.Any(l => o.Identifier == l)))
{
languageDropdown.SelectItem(allLanguagesKey);
languageDropdown.Text = TextManager.Get(allLanguagesKey);
}
var langTickboxes = languageDropdown.ListBox.Content.Children
.Where(c => c.UserData is LanguageIdentifier)
.Select(c => c.GetChild<GUITickBox>())
.ToArray();
bool inSelectedCall = false;
languageDropdown.OnSelected = (_, userData) =>
{
if (inSelectedCall) { return true; }
try
{
inSelectedCall = true;
if (Equals(allLanguagesKey, userData))
{
foreach (var tb in langTickboxes)
{
tb.Selected = allTickbox.Selected;
}
}
bool noneSelected = langTickboxes.All(tb => !tb.Selected);
bool allSelected = langTickboxes.All(tb => tb.Selected);
if (allSelected != allTickbox.Selected)
{
allTickbox.Selected = allSelected;
}
if (allSelected)
{
languageDropdown.Text = TextManager.Get(allLanguagesKey);
}
else if (noneSelected)
{
languageDropdown.Text = TextManager.Get("None");
}
var languages = languageDropdown.SelectedDataMultiple.OfType<LanguageIdentifier>();
ServerListFilters.Instance.SetAttribute(languageKey, string.Join(", ", languages));
GameSettings.SaveCurrentConfig();
return true;
}
finally
{
inSelectedCall = false;
FilterServers();
}
};
}
// Filter Tags
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.05f), filters.Content.RectTransform), TextManager.Get("servertags"), font: GUIStyle.SubHeadingFont)
{
@@ -713,7 +819,7 @@ namespace Barotrauma
private void SortList(ColumnLabel sortBy, bool toggle)
{
if (!(labelHolder.GetChildByUserData(sortBy) is GUIButton button)) { return; }
if (labelHolder.GetChildByUserData(sortBy) is not GUIButton button) { return; }
sortedBy = sortBy;
@@ -730,51 +836,74 @@ namespace Barotrauma
}
}
bool ascending = arrowUp.Visible;
sortedAscending = arrowUp.Visible;
if (toggle)
{
ascending = !ascending;
sortedAscending = !sortedAscending;
}
arrowUp.Visible = ascending;
arrowDown.Visible = !ascending;
arrowUp.Visible = sortedAscending;
arrowDown.Visible = !sortedAscending;
serverList.Content.RectTransform.SortChildren((c1, c2) =>
{
if (!(c1.GUIComponent.UserData is ServerInfo s1)) { return 0; }
if (!(c2.GUIComponent.UserData is ServerInfo s2)) { return 0; }
switch (sortBy)
{
case ColumnLabel.ServerListCompatible:
bool s1Compatible = NetworkMember.IsCompatible(GameMain.Version, s1.GameVersion);
bool s2Compatible = NetworkMember.IsCompatible(GameMain.Version, s2.GameVersion);
if (s1Compatible == s2Compatible) { return 0; }
return (s1Compatible ? 1 : -1) * (ascending ? 1 : -1);
case ColumnLabel.ServerListHasPassword:
if (s1.HasPassword == s2.HasPassword) { return 0; }
return (s1.HasPassword ? 1 : -1) * (ascending ? 1 : -1);
case ColumnLabel.ServerListName:
// I think we actually want culture-specific sorting here?
return string.Compare(s1.ServerName, s2.ServerName, StringComparison.CurrentCulture) * (ascending ? 1 : -1);
case ColumnLabel.ServerListRoundStarted:
if (s1.GameStarted == s2.GameStarted) { return 0; }
return (s1.GameStarted ? 1 : -1) * (ascending ? 1 : -1);
case ColumnLabel.ServerListPlayers:
return s2.PlayerCount.CompareTo(s1.PlayerCount) * (ascending ? 1 : -1);
case ColumnLabel.ServerListPing:
return (s1.Ping.TryUnwrap(out var s1Ping), s2.Ping.TryUnwrap(out var s2Ping)) switch
{
(false, false) => 0,
(true, true) => s2Ping.CompareTo(s1Ping) * (ascending ? 1 : -1),
(false, true) => 1,
(true, false) => -1
};
default:
return 0;
}
if (c1.GUIComponent.UserData is not ServerInfo s1) { return 0; }
if (c2.GUIComponent.UserData is not ServerInfo s2) { return 0; }
int comparison = sortedAscending ? 1 : -1;
return CompareServer(sortBy, s1, s2) * comparison;
});
}
private void InsertServer(ServerInfo serverInfo, GUIComponent component)
{
var children = serverList.Content.RectTransform.Children.Reverse().ToList();
int comparison = sortedAscending ? 1 : -1;
foreach (var child in children)
{
if (child.GUIComponent.UserData is not ServerInfo serverInfo2 || serverInfo.Equals(serverInfo2)) { continue; }
if (CompareServer(sortedBy, serverInfo, serverInfo2) * comparison >= 0)
{
var index = serverList.Content.RectTransform.GetChildIndex(child);
component.RectTransform.RepositionChildInHierarchy(index + 1);
return;
}
}
component.RectTransform.SetAsFirstChild();
}
private static int CompareServer(ColumnLabel sortBy, ServerInfo s1, ServerInfo s2)
{
switch (sortBy)
{
case ColumnLabel.ServerListCompatible:
bool s1Compatible = NetworkMember.IsCompatible(GameMain.Version, s1.GameVersion);
bool s2Compatible = NetworkMember.IsCompatible(GameMain.Version, s2.GameVersion);
if (s1Compatible == s2Compatible) { return 0; }
return s1Compatible ? -1 : 1;
case ColumnLabel.ServerListHasPassword:
if (s1.HasPassword == s2.HasPassword) { return 0; }
return s1.HasPassword ? 1 : -1;
case ColumnLabel.ServerListName:
// I think we actually want culture-specific sorting here?
return string.Compare(s1.ServerName, s2.ServerName, StringComparison.CurrentCulture);
case ColumnLabel.ServerListRoundStarted:
if (s1.GameStarted == s2.GameStarted) { return 0; }
return s1.GameStarted ? 1 : -1;
case ColumnLabel.ServerListPlayers:
return s2.PlayerCount.CompareTo(s1.PlayerCount);
case ColumnLabel.ServerListPing:
return (s1.Ping.TryUnwrap(out var s1Ping), s2.Ping.TryUnwrap(out var s2Ping)) switch
{
(false, false) => 0,
(true, true) => s2Ping.CompareTo(s1Ping),
(false, true) => 1,
(true, false) => -1
};
default:
return 0;
}
}
public override void Select()
{
@@ -821,6 +950,7 @@ namespace Barotrauma
UpdateFriendsList();
panelAnimator?.Update();
scanServersButton.Enabled = (DateTime.Now - lastRefreshTime) >= AllowedRefreshInterval;
if (PlayerInput.PrimaryMouseButtonClicked())
@@ -840,7 +970,7 @@ namespace Barotrauma
RemoveMsgFromServerList(MsgUserData.NoMatchingServers);
foreach (GUIComponent child in serverList.Content.Children)
{
if (!(child.UserData is ServerInfo serverInfo)) { continue; }
if (child.UserData is not ServerInfo serverInfo) { continue; }
child.Visible = ShouldShowServer(serverInfo);
}
@@ -851,6 +981,20 @@ namespace Barotrauma
serverList.UpdateScrollBarSize();
}
private bool AllLanguagesVisible
{
get
{
if (languageDropdown is null) { return true; }
// CountChildren-1 because there's a separator element in there that can't be selected
int tickBoxCount = languageDropdown.ListBox.Content.CountChildren - 1;
int selectedCount = languageDropdown.SelectedIndexMultiple.Count();
return selectedCount >= tickBoxCount;
}
}
private bool ShouldShowServer(ServerInfo serverInfo)
{
#if !DEBUG
@@ -918,6 +1062,14 @@ namespace Barotrauma
}
}
if (!AllLanguagesVisible)
{
if (!languageDropdown.SelectedDataMultiple.OfType<LanguageIdentifier>().Contains(serverInfo.Language))
{
return false;
}
}
foreach (GUITickBox tickBox in gameModeTickBoxes.Values)
{
var gameMode = (Identifier)tickBox.UserData;
@@ -1031,8 +1183,8 @@ namespace Barotrauma
if (!(userdata is FriendInfo { IsInServer: true } info)) { return false; }
if (info.IsInServer
&& info.ConnectCommand is Some<ConnectCommand> { Value: { EndpointOrLobby: var endpointOrLobby } }
&& endpointOrLobby.TryGet(out ConnectCommand.NameAndEndpoint nameAndEndpoint))
&& info.ConnectCommand.TryUnwrap(out var command)
&& command.EndpointOrLobby.TryGet(out ConnectCommand.NameAndEndpoint nameAndEndpoint))
{
const int framePadding = 5;
@@ -1270,7 +1422,7 @@ namespace Barotrauma
serverPreview.Content.ClearChildren();
panelAnimator.RightEnabled = false;
joinButton.Enabled = false;
selectedServer = null;
selectedServer = Option.None;
if (selectedTab == TabEnum.All)
{
@@ -1370,8 +1522,7 @@ namespace Barotrauma
UpdateServerInfoUI(serverInfo);
if (!skipPing) { PingUtils.GetServerPing(serverInfo, UpdateServerInfoUI); }
SortList(sortedBy, toggle: false);
FilterServers();
InsertServer(serverInfo, serverFrame);
}
private void UpdateServerInfoUI(ServerInfo serverInfo)
@@ -1629,7 +1780,7 @@ namespace Barotrauma
#endif
}
private Color GetPingTextColor(int ping)
private static Color GetPingTextColor(int ping)
{
if (ping < 0) { return Color.DarkRed; }
return ToolBox.GradientLerp(ping / 200.0f, GUIStyle.Green, GUIStyle.Orange, GUIStyle.Red);
@@ -1664,6 +1815,7 @@ namespace Barotrauma
{
ServerListFilters.Instance.SetAttribute(ternaryFilter.Key, ternaryFilter.Value.SelectedData.ToString());
}
GameSettings.SaveCurrentConfig();
}
public void LoadServerFilters()
@@ -1158,7 +1158,7 @@ namespace Barotrauma
foreach (MapEntityPrefab ep in entityLists[categoryKey])
{
#if !DEBUG
if (ep.HideInMenus) { continue; }
if (ep.HideInMenus && !GameMain.DebugDraw) { continue; }
#endif
CreateEntityElement(ep, entitiesPerRow, entityListInner.Content);
}
@@ -1177,7 +1177,7 @@ namespace Barotrauma
foreach (MapEntityPrefab ep in MapEntityPrefab.List)
{
#if !DEBUG
if (ep.HideInMenus) { continue; }
if (ep.HideInMenus && !GameMain.DebugDraw) { continue; }
#endif
CreateEntityElement(ep, entitiesPerRow, allEntityList.Content);
}
@@ -1306,7 +1306,6 @@ namespace Barotrauma
try
{
assemblyPrefab.Delete();
UpdateEntityList();
OpenEntityMenu(MapEntityCategory.ItemAssembly);
}
catch (Exception e)
@@ -2725,11 +2724,13 @@ namespace Barotrauma
previewImageButtonHolder.RectTransform.MinSize = new Point(0, previewImageButtonHolder.RectTransform.Children.Max(c => c.MinSize.Y));
var contentPackageTabber = new GUILayoutGroup(new RectTransform((1.0f, 0.06f), rightColumn.RectTransform), isHorizontal: true);
var contentPackageTabber = new GUILayoutGroup(new RectTransform((1.0f, 0.075f), rightColumn.RectTransform), isHorizontal: true);
GUIButton createTabberBtn(string labelTag)
{
var btn = new GUIButton(new RectTransform((0.5f, 1.0f), contentPackageTabber.RectTransform, Anchor.BottomCenter, Pivot.BottomCenter), TextManager.Get(labelTag), style: "GUITabButton");
btn.TextBlock.Wrap = true;
btn.TextBlock.SetTextPos();
btn.RectTransform.MaxSize = RectTransform.MaxPoint;
btn.Children.ForEach(c => c.RectTransform.MaxSize = RectTransform.MaxPoint);
btn.Font = GUIStyle.SmallFont;
@@ -3088,9 +3089,17 @@ namespace Barotrauma
string newPackagePath = ContentPackageManager.LocalPackages.SaveRegularMod(modProject);
existingContentPackage = ContentPackageManager.LocalPackages.GetRegularModByPath(newPackagePath);
}
XDocument doc = new XDocument(ItemAssemblyPrefab.Save(MapEntity.SelectedList.ToList(), nameBox.Text, descriptionBox.Text, hideInMenus));
doc.SaveSafe(filePath);
try
{
doc.SaveSafe(filePath);
}
catch (Exception e)
{
DebugConsole.ThrowError($"Failed to save the item assembly to \"{filePath}\".", e);
return;
}
var result = ContentPackageManager.ReloadContentPackage(existingContentPackage);
if (!result.TryUnwrapSuccess(out var resultPackage))
@@ -3644,6 +3653,8 @@ namespace Barotrauma
private void OpenEntityMenu(MapEntityCategory? entityCategory)
{
UpdateEntityList();
foreach (GUIButton categoryButton in entityCategoryButtons)
{
categoryButton.Selected = entityCategory.HasValue ?
@@ -3771,14 +3782,14 @@ namespace Barotrauma
{
if (GUIContextMenu.CurrentContextMenu != null) { return; }
List<MapEntity> targets = MapEntity.mapEntityList.Any(me => me.IsHighlighted && !MapEntity.SelectedList.Contains(me)) ?
MapEntity.mapEntityList.Where(me => me.IsHighlighted).ToList() :
List<MapEntity> targets = MapEntity.HighlightedEntities.Any(me => !MapEntity.SelectedList.Contains(me)) ?
MapEntity.HighlightedEntities.ToList() :
new List<MapEntity>(MapEntity.SelectedList);
Item target = null;
var single = targets.Count == 1 ? targets.Single() : null;
if (single is Item item && item.Components.Any(ic => !(ic is ConnectionPanel) && !(ic is Repairable) && ic.GuiFrame != null))
if (single is Item item && item.Components.Any(ic => !(ic is ConnectionPanel) && ic is not Repairable && ic.GuiFrame != null))
{
// Do not offer the ability to open the inventory if the inventory should never be drawn
var container = item.GetComponent<ItemContainer>();
@@ -4023,7 +4034,7 @@ namespace Barotrauma
pickerMutex = new object(),
hexMutex = new object();
Vector2 relativeSize = new Vector2(GUI.IsFourByThree() ? 0.4f : 0.3f, 0.3f);
Vector2 relativeSize = new Vector2(0.4f * GUI.AspectRatioAdjustment, 0.3f);
GUIMessageBox msgBox = new GUIMessageBox(string.Empty, string.Empty, Array.Empty<LocalizedString>(), relativeSize, type: GUIMessageBox.Type.Vote)
{
@@ -4062,24 +4073,31 @@ namespace Barotrauma
GUILayoutGroup sliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - colorPicker.RectTransform.RelativeSize.X, 1f), colorLayout.RectTransform), childAnchor: Anchor.TopRight);
float currentHue = colorPicker.SelectedHue / 360f;
GUILayoutGroup hueSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.25f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
GUILayoutGroup hueSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.25f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { Stretch = true };
new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.2f), hueSliderLayout.RectTransform), text: "H:", font: GUIStyle.SubHeadingFont) { Padding = Vector4.Zero, ToolTip = "Hue" };
GUIScrollBar hueScrollBar = new GUIScrollBar(new RectTransform(new Vector2(0.7f, 1f), hueSliderLayout.RectTransform), style: "GUISlider", barSize: 0.05f) { BarScroll = currentHue };
GUINumberInput hueTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), hueSliderLayout.RectTransform), inputType: NumberType.Float) { FloatValue = currentHue, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
GUINumberInput hueTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), hueSliderLayout.RectTransform) { MinSize = new Point(GUI.IntScale(100), 0) },
inputType: NumberType.Float) { FloatValue = currentHue, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
GUILayoutGroup satSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.2f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
GUILayoutGroup satSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.2f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { Stretch = true };
new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.2f), satSliderLayout.RectTransform), text: "S:", font: GUIStyle.SubHeadingFont) { Padding = Vector4.Zero, ToolTip = "Saturation"};
GUIScrollBar satScrollBar = new GUIScrollBar(new RectTransform(new Vector2(0.7f, 1f), satSliderLayout.RectTransform), style: "GUISlider", barSize: 0.05f) { BarScroll = colorPicker.SelectedSaturation };
GUINumberInput satTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), satSliderLayout.RectTransform), inputType: NumberType.Float) { FloatValue = colorPicker.SelectedSaturation, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
GUINumberInput satTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), satSliderLayout.RectTransform) { MinSize = new Point(GUI.IntScale(100), 0) },
inputType: NumberType.Float) { FloatValue = colorPicker.SelectedSaturation, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
GUILayoutGroup valueSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.2f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
GUILayoutGroup valueSliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.2f), sliderLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft) { Stretch = true };
new GUITextBlock(new RectTransform(new Vector2(0.1f, 0.2f), valueSliderLayout.RectTransform), text: "V:", font: GUIStyle.SubHeadingFont) { Padding = Vector4.Zero, ToolTip = "Value"};
GUIScrollBar valueScrollBar = new GUIScrollBar(new RectTransform(new Vector2(0.7f, 1f), valueSliderLayout.RectTransform), style: "GUISlider", barSize: 0.05f) { BarScroll = colorPicker.SelectedValue };
GUINumberInput valueTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), valueSliderLayout.RectTransform), inputType: NumberType.Float) { FloatValue = colorPicker.SelectedValue, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
GUINumberInput valueTextBox = new GUINumberInput(new RectTransform(new Vector2(0.2f, 1f), valueSliderLayout.RectTransform) { MinSize = new Point(GUI.IntScale(100), 0) },
inputType: NumberType.Float) { FloatValue = colorPicker.SelectedValue, MaxValueFloat = 1f, MinValueFloat = 0f, DecimalsToDisplay = 2 };
GUILayoutGroup colorInfoLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.3f), sliderLayout.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true) { RelativeSpacing = 0.15f };
GUILayoutGroup colorInfoLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.3f), sliderLayout.RectTransform), childAnchor: Anchor.CenterLeft, isHorizontal: true)
{
Stretch = true,
RelativeSpacing = 0.1f
};
new GUICustomComponent(new RectTransform(new Vector2(0.4f, 0.8f), colorInfoLayout.RectTransform), (batch, component) =>
new GUICustomComponent(new RectTransform(Vector2.One, colorInfoLayout.RectTransform, scaleBasis: ScaleBasis.BothHeight), (batch, component) =>
{
Rectangle rect = component.Rect;
Point areaSize = new Point(rect.Width, rect.Height / 2);
@@ -5251,9 +5269,9 @@ namespace Barotrauma
{
if (dummyCharacter.SelectedItem == null)
{
foreach (var entity in MapEntity.mapEntityList)
foreach (var entity in MapEntity.HighlightedEntities)
{
if (entity is Item item && entity.IsHighlighted && item.Components.Any(ic => !(ic is ConnectionPanel) && !(ic is Repairable) && ic.GuiFrame != null))
if (entity is Item item && item.Components.Any(ic => ic is not ConnectionPanel && ic is not Repairable && ic.GuiFrame != null))
{
var container = item.GetComponents<ItemContainer>().ToList();
if (!container.Any() || container.Any(ic => ic?.DrawInventory ?? false))
@@ -1,6 +1,5 @@
#nullable enable
using System.Linq;
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@@ -34,7 +33,7 @@ namespace Barotrauma
{
BlueprintEffect.Dispose();
GameMain.Instance.Content.Unload();
BlueprintEffect = GameMain.Instance.Content.Load<Effect>("Effects/blueprintshader_opengl");
BlueprintEffect = EffectLoader.Load("Effects/blueprintshader");
GameMain.GameScreen.BlueprintEffect = BlueprintEffect;
return true;
}