Merge remote-tracking branch 'upstream/dev' into develop
This commit is contained in:
@@ -104,6 +104,7 @@ namespace Barotrauma
|
||||
|
||||
public struct CampaignSettingElements
|
||||
{
|
||||
public SettingValue<bool> TutorialEnabled;
|
||||
public SettingValue<bool> RadiationEnabled;
|
||||
public SettingValue<int> MaxMissionCount;
|
||||
public SettingValue<StartingBalanceAmount> StartingFunds;
|
||||
@@ -114,6 +115,7 @@ namespace Barotrauma
|
||||
{
|
||||
return new CampaignSettings(element: null)
|
||||
{
|
||||
TutorialEnabled = TutorialEnabled.GetValue(),
|
||||
RadiationEnabled = RadiationEnabled.GetValue(),
|
||||
MaxMissionCount = MaxMissionCount.GetValue(),
|
||||
StartingBalanceAmount = StartingFunds.GetValue(),
|
||||
@@ -159,7 +161,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
protected static CampaignSettingElements CreateCampaignSettingList(GUIComponent parent, CampaignSettings prevSettings)
|
||||
protected static CampaignSettingElements CreateCampaignSettingList(GUIComponent parent, CampaignSettings prevSettings, bool isSinglePlayer)
|
||||
{
|
||||
const float verticalSize = 0.14f;
|
||||
|
||||
@@ -180,6 +182,9 @@ namespace Barotrauma
|
||||
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);
|
||||
|
||||
ImmutableArray<SettingCarouselElement<Identifier>> startingSetOptions = StartItemSet.Sets.OrderBy(s => s.Order).Select(set => new SettingCarouselElement<Identifier>(set.Identifier, $"startitemset.{set.Identifier}")).ToImmutableArray();
|
||||
@@ -214,6 +219,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (o is CampaignSettings settings)
|
||||
{
|
||||
tutorialEnabled.SetValue(isSinglePlayer && settings.TutorialEnabled);
|
||||
radiationEnabled.SetValue(settings.RadiationEnabled);
|
||||
maxMissionCountInput.SetValue(settings.MaxMissionCount);
|
||||
startingFundsInput.SetValue(settings.StartingBalanceAmount);
|
||||
@@ -226,6 +232,7 @@ namespace Barotrauma
|
||||
|
||||
return new CampaignSettingElements
|
||||
{
|
||||
TutorialEnabled = tutorialEnabled,
|
||||
RadiationEnabled = radiationEnabled,
|
||||
MaxMissionCount = maxMissionCountInput,
|
||||
StartingFunds = startingFundsInput,
|
||||
|
||||
+5
-5
@@ -35,18 +35,18 @@ namespace Barotrauma
|
||||
};
|
||||
|
||||
// New game
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("SaveName"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft);
|
||||
saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform) { MinSize = new Point(0, 20) }, string.Empty)
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform) { MinSize = new Point(0, GUI.IntScale(24)) }, TextManager.Get("SaveName"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft);
|
||||
saveNameBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform), string.Empty)
|
||||
{
|
||||
textFilterFunction = ToolBox.RemoveInvalidFileNameChars
|
||||
};
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform) { MinSize = new Point(0, 20) }, TextManager.Get("MapSeed"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft);
|
||||
seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform) { MinSize = new Point(0, 20) }, ToolBox.RandomSeed(8));
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform) { MinSize = new Point(0, GUI.IntScale(24)) }, TextManager.Get("MapSeed"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft);
|
||||
seedBox = new GUITextBox(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform), ToolBox.RandomSeed(8));
|
||||
|
||||
nameSeedLayout.RectTransform.MinSize = new Point(0, nameSeedLayout.Children.Sum(c => c.RectTransform.MinSize.Y));
|
||||
|
||||
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingLayout, CampaignSettings.Empty);
|
||||
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingLayout, CampaignSettings.Empty, false);
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f),
|
||||
verticalLayout.RectTransform) { MaxSize = new Point(int.MaxValue, 60) }, childAnchor: Anchor.BottomRight, isHorizontal: true);
|
||||
|
||||
+5
-4
@@ -370,7 +370,7 @@ namespace Barotrauma
|
||||
GUILayoutGroup campaignSettingContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.8f), CampaignCustomizeSettings.Content.RectTransform, Anchor.TopCenter));
|
||||
|
||||
|
||||
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingContent, prevSettings);
|
||||
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingContent, prevSettings, true);
|
||||
CampaignCustomizeSettings.Buttons[0].OnClicked += (button, o) =>
|
||||
{
|
||||
|
||||
@@ -608,15 +608,16 @@ namespace Barotrauma
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
var saveFolder = SaveUtil.GetSaveFolder(SaveUtil.SaveType.Singleplayer);
|
||||
try
|
||||
{
|
||||
ToolBox.OpenFileWithShell(SaveUtil.SaveFolder);
|
||||
ToolBox.OpenFileWithShell(saveFolder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
new GUIMessageBox(
|
||||
TextManager.Get("error"),
|
||||
TextManager.GetWithVariables("showinfoldererror", ("[folder]", SaveUtil.SaveFolder), ("[errormessage]", e.Message)));
|
||||
TextManager.Get("error"),
|
||||
TextManager.GetWithVariables("showinfoldererror", ("[folder]", saveFolder), ("[errormessage]", e.Message)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -472,7 +472,12 @@ namespace Barotrauma
|
||||
{
|
||||
TextGetter = () =>
|
||||
{
|
||||
return TextManager.AddPunctuation(':', TextManager.Get("Missions"), $"{Campaign.NumberOfMissionsAtLocation(destination)}/{Campaign.Settings.TotalMaxMissionCount}");
|
||||
int missionCount = 0;
|
||||
if (GameMain.GameSession != null && Campaign.Map?.CurrentLocation?.SelectedMissions != null)
|
||||
{
|
||||
missionCount = Campaign.Map.CurrentLocation.SelectedMissions.Count(m => m.Locations.Contains(location) && !GameMain.GameSession.Missions.Contains(m));
|
||||
}
|
||||
return TextManager.AddPunctuation(':', TextManager.Get("Missions"), $"{missionCount}/{Campaign.Settings.TotalMaxMissionCount}");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+21
-9
@@ -39,6 +39,7 @@ namespace Barotrauma.CharacterEditor
|
||||
|
||||
private bool ShowExtraRagdollControls => editLimbs || editJoints;
|
||||
|
||||
public Character SpawnedCharacter => character;
|
||||
private Character character;
|
||||
private Vector2 spawnPosition;
|
||||
|
||||
@@ -1513,7 +1514,7 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
}
|
||||
|
||||
private Character SpawnCharacter(Identifier speciesName, RagdollParams ragdoll = null)
|
||||
public Character SpawnCharacter(Identifier speciesName, RagdollParams ragdoll = null)
|
||||
{
|
||||
DebugConsole.NewMessage(GetCharacterEditorTranslation("TryingToSpawnCharacter").Replace("[config]", speciesName.ToString()), Color.HotPink);
|
||||
OnPreSpawn();
|
||||
@@ -1765,9 +1766,15 @@ namespace Barotrauma.CharacterEditor
|
||||
var modProject = new ModProject(contentPackage);
|
||||
var newFile = ModProject.File.FromPath<CharacterFile>(configFilePath);
|
||||
modProject.AddFile(newFile);
|
||||
|
||||
modProject.Save(contentPackage.Path);
|
||||
contentPackage = ContentPackageManager.ReloadContentPackage(contentPackage);
|
||||
|
||||
var reloadResult = ContentPackageManager.ReloadContentPackage(contentPackage);
|
||||
if (!reloadResult.TryUnwrapSuccess(out var newPackage))
|
||||
{
|
||||
throw new Exception($"Failed to reload package",
|
||||
reloadResult.TryUnwrapFailure(out var exception) ? exception : null);
|
||||
}
|
||||
contentPackage = newPackage;
|
||||
|
||||
DebugConsole.NewMessage(GetCharacterEditorTranslation("ContentPackageSaved").Replace("[path]", contentPackage.Path));
|
||||
|
||||
@@ -3181,10 +3188,7 @@ namespace Barotrauma.CharacterEditor
|
||||
OnClicked = (button, data) =>
|
||||
{
|
||||
ResetView();
|
||||
CharacterParams.Serialize();
|
||||
RagdollParams.Serialize();
|
||||
AnimParams.ForEach(a => a.Serialize());
|
||||
Wizard.Instance.CopyExisting(CharacterParams, RagdollParams, AnimParams);
|
||||
PrepareCharacterCopy();
|
||||
Wizard.Instance.SelectTab(Wizard.Tab.Character);
|
||||
return true;
|
||||
}
|
||||
@@ -3209,9 +3213,17 @@ namespace Barotrauma.CharacterEditor
|
||||
|
||||
fileEditPanel.RectTransform.MinSize = new Point(0, (int)(layoutGroup.RectTransform.Children.Sum(c => c.MinSize.Y + layoutGroup.AbsoluteSpacing) * 1.2f));
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region ToggleButtons
|
||||
public void PrepareCharacterCopy()
|
||||
{
|
||||
CharacterParams.Serialize();
|
||||
RagdollParams.Serialize();
|
||||
AnimParams.ForEach(a => a.Serialize());
|
||||
Wizard.Instance.CopyExisting(CharacterParams, RagdollParams, AnimParams);
|
||||
}
|
||||
|
||||
#region ToggleButtons
|
||||
private enum Direction
|
||||
{
|
||||
Left,
|
||||
|
||||
@@ -101,7 +101,7 @@ namespace Barotrauma.CharacterEditor
|
||||
{
|
||||
bool isSamePackage = contentPackage.GetFiles<CharacterFile>().Any(f => Path.GetFileNameWithoutExtension(f.Path.Value) == name);
|
||||
LocalizedString verificationText = isSamePackage ? GetCharacterEditorTranslation("existingcharacterfoundreplaceverification") : GetCharacterEditorTranslation("existingcharacterfoundoverrideverification");
|
||||
var msgBox = new GUIMessageBox("", verificationText, new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") })
|
||||
var msgBox = new GUIMessageBox("", verificationText, new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") }, type: GUIMessageBox.Type.Warning)
|
||||
{
|
||||
UserData = "verificationprompt"
|
||||
};
|
||||
@@ -356,7 +356,7 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
if (ContentPackageManager.AllPackages.Any(cp => cp.Name.ToLower() == contentPackageNameElement.Text.ToLower()))
|
||||
{
|
||||
new GUIMessageBox("", TextManager.Get("charactereditor.contentpackagenameinuse", "leveleditorlevelobjnametaken"));
|
||||
new GUIMessageBox("", TextManager.Get("charactereditor.contentpackagenameinuse", "leveleditorlevelobjnametaken"), type: GUIMessageBox.Type.Warning);
|
||||
return false;
|
||||
}
|
||||
string modName = contentPackageNameElement.Text;
|
||||
@@ -428,17 +428,26 @@ namespace Barotrauma.CharacterEditor
|
||||
texturePathElement.Flash(useRectangleFlash: true);
|
||||
return false;
|
||||
}
|
||||
if (Name == CharacterPrefab.HumanSpeciesName && !IsCopy)
|
||||
{
|
||||
// Force a copy when trying to override a human, because handling the crash would be very difficult (we require humans to have certain definitions).
|
||||
if (!CharacterEditorScreen.Instance.SpawnedCharacter.IsHuman)
|
||||
{
|
||||
CharacterEditorScreen.Instance.SpawnCharacter(CharacterPrefab.HumanSpeciesName);
|
||||
}
|
||||
CharacterEditorScreen.Instance.PrepareCharacterCopy();
|
||||
}
|
||||
if (IsCopy)
|
||||
{
|
||||
SourceRagdoll.Texture = evaluatedTexturePath;
|
||||
SourceRagdoll.CanEnterSubmarine = CanEnterSubmarine;
|
||||
SourceRagdoll.CanWalk = CanWalk;
|
||||
SourceRagdoll.Serialize();
|
||||
Wizard.Instance.CreateCharacter(SourceRagdoll.MainElement, SourceCharacter.MainElement, SourceAnimations);
|
||||
Instance.CreateCharacter(SourceRagdoll.MainElement, SourceCharacter.MainElement, SourceAnimations);
|
||||
}
|
||||
else
|
||||
{
|
||||
Wizard.Instance.SelectTab(Tab.Ragdoll);
|
||||
Instance.SelectTab(Tab.Ragdoll);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
@@ -470,9 +479,6 @@ namespace Barotrauma.CharacterEditor
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.02f
|
||||
};
|
||||
// HTML
|
||||
GUIMessageBox htmlBox = null;
|
||||
var loadHtmlButton = new GUIButton(new RectTransform(new Point(content.Rect.Width / 3, elementSize), content.RectTransform), GetCharacterEditorTranslation("LoadFromHTML"));
|
||||
// Limbs
|
||||
var limbsElement = new GUIFrame(new RectTransform(new Vector2(1, 0.05f), content.RectTransform), style: null) { CanBeFocused = false };
|
||||
|
||||
@@ -689,69 +695,6 @@ namespace Barotrauma.CharacterEditor
|
||||
return true;
|
||||
}
|
||||
};
|
||||
loadHtmlButton.OnClicked = (b, d) =>
|
||||
{
|
||||
if (htmlBox == null)
|
||||
{
|
||||
htmlBox = new GUIMessageBox(GetCharacterEditorTranslation("LoadHTML"), string.Empty, new LocalizedString[] { TextManager.Get("Close"), TextManager.Get("Load") }, new Vector2(0.65f, 1f));
|
||||
htmlBox.Header.Font = GUIStyle.LargeFont;
|
||||
var element = new GUIFrame(new RectTransform(new Vector2(0.9f, 0.05f), htmlBox.Content.RectTransform), style: null, color: Color.Gray * 0.25f);
|
||||
//new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), element.RectTransform), GetCharacterEditorTranslation("HTMLPath"));
|
||||
var htmlPathElement = new GUITextBox(new RectTransform(new Vector2(0.7f, 1), element.RectTransform, Anchor.TopRight), GetCharacterEditorTranslation("HTMLPath").Value);
|
||||
LocalizedString title = GetCharacterEditorTranslation("SelectFile");
|
||||
new GUIButton(new RectTransform(new Vector2(0.3f, 1), element.RectTransform), title)
|
||||
{
|
||||
OnClicked = (button, data) =>
|
||||
{
|
||||
FileSelection.OnFileSelected = (file) =>
|
||||
{
|
||||
htmlPathElement.Text = file;
|
||||
};
|
||||
FileSelection.ClearFileTypeFilters();
|
||||
FileSelection.AddFileTypeFilter("HTML", "*.html, *.htm");
|
||||
FileSelection.AddFileTypeFilter("All files", "*.*");
|
||||
FileSelection.SelectFileTypeFilter("*.html, *.htm");
|
||||
FileSelection.Open = true;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
var list = new GUIListBox(new RectTransform(new Vector2(1, 0.8f), htmlBox.Content.RectTransform));
|
||||
var htmlOutput = new GUITextBlock(new RectTransform(Vector2.One, list.Content.RectTransform), string.Empty) { CanBeFocused = false };
|
||||
htmlBox.Buttons[0].OnClicked += (_b, _d) =>
|
||||
{
|
||||
htmlBox.Close();
|
||||
return true;
|
||||
};
|
||||
htmlBox.Buttons[1].OnClicked += (_b, _d) =>
|
||||
{
|
||||
LimbGUIElements.ForEach(l => l.RectTransform.Parent = null);
|
||||
LimbGUIElements.Clear();
|
||||
JointGUIElements.ForEach(j => j.RectTransform.Parent = null);
|
||||
JointGUIElements.Clear();
|
||||
LimbXElements.Clear();
|
||||
JointXElements.Clear();
|
||||
ParseRagdollFromHTML(htmlPathElement.Text, (id, limbName, limbType, rect) =>
|
||||
{
|
||||
CreateLimbGUIElement(limbsList.Content.RectTransform, elementSize, id, limbName, limbType, rect);
|
||||
}, (id1, id2, anchor1, anchor2, jointName) =>
|
||||
{
|
||||
CreateJointGUIElement(jointsList.Content.RectTransform, elementSize, id1, id2, anchor1, anchor2, jointName);
|
||||
});
|
||||
htmlOutput.Text = new XDocument(new XElement("Ragdoll", new object[]
|
||||
{
|
||||
new XAttribute("type", Name), LimbXElements.Values, JointXElements
|
||||
})).ToString();
|
||||
htmlOutput.CalculateHeightFromText();
|
||||
list.UpdateScrollBarSize();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIMessageBox.MessageBoxes.Add(htmlBox);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// Previous
|
||||
box.Buttons[0].OnClicked += (b, d) =>
|
||||
{
|
||||
@@ -1070,7 +1013,6 @@ namespace Barotrauma.CharacterEditor
|
||||
// Rectangles
|
||||
colliderAttributes.Add(new XAttribute("height", (int)(height * 0.85f)));
|
||||
colliderAttributes.Add(new XAttribute("width", (int)(width * 0.85f)));
|
||||
idToCodeName.TryGetValue(id, out string notes);
|
||||
LimbXElements.Add(id.ToString(), new XElement("limb",
|
||||
new XAttribute("id", id),
|
||||
new XAttribute("name", limbName),
|
||||
@@ -1107,188 +1049,6 @@ namespace Barotrauma.CharacterEditor
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<int, string> idToCodeName = new Dictionary<int, string>();
|
||||
protected void ParseRagdollFromHTML(string path, Action<int, string, LimbType, Rectangle> limbCallback = null, Action<int, int, Vector2, Vector2, string> jointCallback = null)
|
||||
{
|
||||
// TODO: parse as xml files -> allows to load ragdolls onto the wizard.
|
||||
//XDocument doc = XMLExtensions.TryLoadXml(path);
|
||||
//var xElements = doc.Elements().ToArray();
|
||||
string html = string.Empty;
|
||||
try
|
||||
{
|
||||
html = File.ReadAllText(path);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError(GetCharacterEditorTranslation("FailedToReadHTML").Replace("[path]", path), e);
|
||||
return;
|
||||
}
|
||||
|
||||
var lines = html.Split(new string[] { "<div", "</div>", Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Where(s => s.Contains("left") && s.Contains("top") && s.Contains("width") && s.Contains("height"));
|
||||
int id = 0;
|
||||
Dictionary<string, int> hierarchyToID = new Dictionary<string, int>();
|
||||
Dictionary<int, string> idToHierarchy = new Dictionary<int, string>();
|
||||
Dictionary<int, string> idToPositionCode = new Dictionary<int, string>();
|
||||
Dictionary<int, string> idToName = new Dictionary<int, string>();
|
||||
idToCodeName.Clear();
|
||||
foreach (var line in lines)
|
||||
{
|
||||
var codeNames = new string(line.SkipWhile(c => c != '>').Skip(1).ToArray()).Split(',');
|
||||
for (int i = 0; i < codeNames.Length; i++)
|
||||
{
|
||||
string codeName = codeNames[i].Trim();
|
||||
if (string.IsNullOrWhiteSpace(codeName)) { continue; }
|
||||
idToCodeName.Add(id, codeName);
|
||||
string limbName = new string(codeName.SkipWhile(c => c != '_').Skip(1).ToArray());
|
||||
if (string.IsNullOrWhiteSpace(limbName)) { continue; }
|
||||
idToName.Add(id, limbName);
|
||||
var parts = line.Split(' ');
|
||||
int ParseToInt(string selector)
|
||||
{
|
||||
string part = parts.First(p => p.Contains(selector));
|
||||
string s = new string(part.SkipWhile(c => c != ':').Skip(1).TakeWhile(c => char.IsNumber(c)).ToArray());
|
||||
int.TryParse(s, out int v);
|
||||
return v;
|
||||
};
|
||||
// example: 111311cr -> 111311
|
||||
string hierarchy = new string(codeName.TakeWhile(c => char.IsNumber(c)).ToArray());
|
||||
if (hierarchyToID.ContainsKey(hierarchy))
|
||||
{
|
||||
DebugConsole.ThrowError(GetCharacterEditorTranslation("MultipleItemsWithSameHierarchy").Replace("[hierarchy]", hierarchy).Replace("[name]", codeName));
|
||||
return;
|
||||
}
|
||||
hierarchyToID.Add(hierarchy, id);
|
||||
idToHierarchy.Add(id, hierarchy);
|
||||
string positionCode = new string(codeName.SkipWhile(c => char.IsNumber(c)).TakeWhile(c => c != '_').ToArray());
|
||||
idToPositionCode.Add(id, positionCode.ToLowerInvariant());
|
||||
int x = ParseToInt("left");
|
||||
int y = ParseToInt("top");
|
||||
int width = ParseToInt("width");
|
||||
int height = ParseToInt("height");
|
||||
// This is overridden when the data is loaded from the gui fields.
|
||||
LimbXElements.Add(hierarchy, new XElement("limb",
|
||||
new XAttribute("id", id),
|
||||
new XAttribute("name", limbName),
|
||||
new XAttribute("type", ParseLimbType(limbName).ToString()),
|
||||
new XElement("sprite",
|
||||
new XAttribute("texture", ""),
|
||||
new XAttribute("sourcerect", $"{x}, {y}, {width}, {height}"))
|
||||
));
|
||||
limbCallback?.Invoke(id, limbName, ParseLimbType(limbName), new Rectangle(x, y, width, height));
|
||||
id++;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < id; i++)
|
||||
{
|
||||
if (idToHierarchy.TryGetValue(i, out string hierarchy))
|
||||
{
|
||||
if (hierarchy != "0")
|
||||
{
|
||||
// NEW LOGIC: if hierarchy length == 1, parent to 0
|
||||
// Else parent to the last bone in the current hierarchy (11 is parented to 1, 212 is parented to 21 etc)
|
||||
string parent = hierarchy.Length > 1 ? hierarchy.Remove(hierarchy.Length - 1, 1) : "0";
|
||||
if (hierarchyToID.TryGetValue(parent, out int parentID))
|
||||
{
|
||||
Vector2 anchor1 = Vector2.Zero;
|
||||
Vector2 anchor2 = Vector2.Zero;
|
||||
idToName.TryGetValue(parentID, out string parentName);
|
||||
idToName.TryGetValue(i, out string limbName);
|
||||
string jointName = $"{GetCharacterEditorTranslation("Joint")} {parentName} - {limbName}";
|
||||
if (idToPositionCode.TryGetValue(i, out string positionCode))
|
||||
{
|
||||
float scalar = 0.8f;
|
||||
if (LimbXElements.TryGetValue(parent, out XElement parentElement))
|
||||
{
|
||||
Rectangle parentSourceRect = parentElement.Element("sprite").GetAttributeRect("sourcerect", Rectangle.Empty);
|
||||
float parentWidth = parentSourceRect.Width / 2 * scalar;
|
||||
float parentHeight = parentSourceRect.Height / 2 * scalar;
|
||||
switch (positionCode)
|
||||
{
|
||||
case "tl": // -1, 1
|
||||
anchor1 = new Vector2(-parentWidth, parentHeight);
|
||||
break;
|
||||
case "tc": // 0, 1
|
||||
anchor1 = new Vector2(0, parentHeight);
|
||||
break;
|
||||
case "tr": // -1, 1
|
||||
anchor1 = new Vector2(-parentWidth, parentHeight);
|
||||
break;
|
||||
case "cl": // -1, 0
|
||||
anchor1 = new Vector2(-parentWidth, 0);
|
||||
break;
|
||||
case "cr": // 1, 0
|
||||
anchor1 = new Vector2(parentWidth, 0);
|
||||
break;
|
||||
case "bl": // -1, -1
|
||||
anchor1 = new Vector2(-parentWidth, -parentHeight);
|
||||
break;
|
||||
case "bc": // 0, -1
|
||||
anchor1 = new Vector2(0, -parentHeight);
|
||||
break;
|
||||
case "br": // 1, -1
|
||||
anchor1 = new Vector2(parentWidth, -parentHeight);
|
||||
break;
|
||||
}
|
||||
if (LimbXElements.TryGetValue(hierarchy, out XElement element))
|
||||
{
|
||||
Rectangle sourceRect = element.Element("sprite").GetAttributeRect("sourcerect", Rectangle.Empty);
|
||||
float width = sourceRect.Width / 2 * scalar;
|
||||
float height = sourceRect.Height / 2 * scalar;
|
||||
switch (positionCode)
|
||||
{
|
||||
// Inverse
|
||||
case "tl":
|
||||
// br
|
||||
anchor2 = new Vector2(-width, -height);
|
||||
break;
|
||||
case "tc":
|
||||
// bc
|
||||
anchor2 = new Vector2(0, -height);
|
||||
break;
|
||||
case "tr":
|
||||
// bl
|
||||
anchor2 = new Vector2(-width, -height);
|
||||
break;
|
||||
case "cl":
|
||||
// cr
|
||||
anchor2 = new Vector2(width, 0);
|
||||
break;
|
||||
case "cr":
|
||||
// cl
|
||||
anchor2 = new Vector2(-width, 0);
|
||||
break;
|
||||
case "bl":
|
||||
// tr
|
||||
anchor2 = new Vector2(-width, height);
|
||||
break;
|
||||
case "bc":
|
||||
// tc
|
||||
anchor2 = new Vector2(0, height);
|
||||
break;
|
||||
case "br":
|
||||
// tl
|
||||
anchor2 = new Vector2(-width, height);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// This is overridden when the data is loaded from the gui fields.
|
||||
JointXElements.Add(new XElement("joint",
|
||||
new XAttribute("name", jointName),
|
||||
new XAttribute("limb1", parentID),
|
||||
new XAttribute("limb2", i),
|
||||
new XAttribute("limb1anchor", $"{anchor1.X.Format(2)}, {anchor1.Y.Format(2)}"),
|
||||
new XAttribute("limb2anchor", $"{anchor2.X.Format(2)}, {anchor2.Y.Format(2)}")
|
||||
));
|
||||
jointCallback?.Invoke(parentID, i, anchor1, anchor2, jointName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected LimbType ParseLimbType(string limbName)
|
||||
{
|
||||
var limbType = LimbType.None;
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace Barotrauma
|
||||
GameMain.LightManager.LosEnabled = true;
|
||||
Hull.EditFire = false;
|
||||
Hull.EditWater = false;
|
||||
#endif
|
||||
HumanAIController.DisableCrewAI = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected virtual void DeselectEditorSpecific() { }
|
||||
|
||||
@@ -10,8 +10,6 @@ namespace Barotrauma
|
||||
{
|
||||
partial class GameScreen : Screen
|
||||
{
|
||||
public override bool IsEditor => GameMain.GameSession?.GameMode is TestGameMode;
|
||||
|
||||
private RenderTarget2D renderTargetBackground;
|
||||
private RenderTarget2D renderTarget;
|
||||
private RenderTarget2D renderTargetWater;
|
||||
|
||||
@@ -47,7 +47,14 @@ namespace Barotrauma
|
||||
private GUITextBox serverNameBox, passwordBox, maxPlayersBox;
|
||||
private GUITickBox isPublicBox, wrongPasswordBanBox, karmaBox;
|
||||
private GUIDropDown serverExecutableDropdown;
|
||||
private readonly GUIButton joinServerButton, hostServerButton, steamWorkshopButton;
|
||||
private readonly GUIButton joinServerButton, hostServerButton;
|
||||
|
||||
private readonly GUIFrame modsButtonContainer;
|
||||
private readonly GUIButton modsButton, modUpdatesButton;
|
||||
private Task<IReadOnlyList<Steamworks.Ugc.Item>> modUpdateTask;
|
||||
private float modUpdateTimer = 0.0f;
|
||||
private const float ModUpdateInterval = 60.0f;
|
||||
|
||||
private readonly GameMain game;
|
||||
|
||||
private GUIImage playstyleBanner;
|
||||
@@ -268,15 +275,29 @@ namespace Barotrauma
|
||||
RelativeSpacing = 0.035f
|
||||
};
|
||||
|
||||
#if USE_STEAM
|
||||
steamWorkshopButton = new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SteamWorkshopButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
|
||||
modsButtonContainer = new GUIFrame(new RectTransform(Vector2.One, customizeList.RectTransform),
|
||||
style: null);
|
||||
|
||||
modsButton = new GUIButton(new RectTransform(Vector2.One, modsButtonContainer.RectTransform),
|
||||
TextManager.Get("settingstab.mods"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
|
||||
{
|
||||
ForceUpperCase = ForceUpperCase.Yes,
|
||||
Enabled = true,
|
||||
UserData = Tab.SteamWorkshop,
|
||||
OnClicked = SelectTab
|
||||
};
|
||||
#endif
|
||||
|
||||
modUpdatesButton = new GUIButton(new RectTransform(Vector2.One * 0.95f, modsButtonContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
|
||||
style: "GUIUpdateButton")
|
||||
{
|
||||
ToolTip = TextManager.Get("ModUpdatesAvailable"),
|
||||
OnClicked = (_, _) =>
|
||||
{
|
||||
BulkDownloader.PrepareUpdates();
|
||||
return false;
|
||||
},
|
||||
Visible = false
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), customizeList.RectTransform), TextManager.Get("SubEditorButton"), textAlignment: Alignment.Left, style: "MainMenuGUIButton")
|
||||
{
|
||||
@@ -334,7 +355,7 @@ namespace Barotrauma
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
string url = TextManager.Get("EditorDisclaimerWikiUrl").Fallback("https://barotraumagame.com/wiki").Value;
|
||||
GameMain.Instance.ShowOpenUrlInWebBrowserPrompt(url, promptExtensionTag: "wikinotice");
|
||||
GameMain.ShowOpenUrlInWebBrowserPrompt(url, promptExtensionTag: "wikinotice");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -485,13 +506,17 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
var tutorialPreview = new GUILayoutGroup(new RectTransform(new Vector2(0.6f, 1.0f), tutorialContent.RectTransform)) { RelativeSpacing = 0.05f, Stretch = true };
|
||||
var imageContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.6f), tutorialPreview.RectTransform), style: "InnerFrame");
|
||||
var imageContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), tutorialPreview.RectTransform), style: "InnerFrame");
|
||||
tutorialBanner = new GUIImage(new RectTransform(Vector2.One, imageContainer.RectTransform), style: null, scaleToFit: true);
|
||||
|
||||
var infoContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.4f), tutorialPreview.RectTransform), style: "GUIFrameListBox");
|
||||
var infoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), infoContainer.RectTransform, Anchor.Center), childAnchor: Anchor.TopCenter);
|
||||
var infoContainer = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.5f), tutorialPreview.RectTransform), style: "GUIFrameListBox");
|
||||
var infoContent = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), infoContainer.RectTransform, Anchor.Center), childAnchor: Anchor.TopLeft)
|
||||
{
|
||||
AbsoluteSpacing = GUI.IntScale(10)
|
||||
};
|
||||
|
||||
tutorialHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.75f), infoContent.RectTransform), string.Empty, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Center);
|
||||
tutorialHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), string.Empty, font: GUIStyle.SubHeadingFont);
|
||||
tutorialDescription = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), infoContent.RectTransform), string.Empty, wrap: true);
|
||||
|
||||
var startButton = new GUIButton(new RectTransform(new Vector2(0.5f, 0.0f), infoContent.RectTransform, Anchor.BottomRight), text: TextManager.Get("startgamebutton"))
|
||||
{
|
||||
@@ -522,6 +547,10 @@ namespace Barotrauma
|
||||
private void SelectTutorial(Tutorial tutorial)
|
||||
{
|
||||
tutorialHeader.Text = tutorial.DisplayName;
|
||||
tutorialHeader.CalculateHeightFromText();
|
||||
tutorialDescription.Text = tutorial.Description;
|
||||
tutorialDescription.CalculateHeightFromText();
|
||||
(tutorialDescription.Parent as GUILayoutGroup)?.Recalculate();
|
||||
tutorial.TutorialPrefab.Banner?.EnsureLazyLoaded();
|
||||
tutorialBanner.Sprite = tutorial.TutorialPrefab.Banner;
|
||||
tutorialBanner.Color = tutorial.TutorialPrefab.Banner == null ? Color.Black : Color.White;
|
||||
@@ -541,6 +570,8 @@ namespace Barotrauma
|
||||
{
|
||||
GameMain.LuaCs.Stop();
|
||||
|
||||
ResetModUpdateButton();
|
||||
|
||||
if (WorkshopItemsToUpdate.Any())
|
||||
{
|
||||
while (WorkshopItemsToUpdate.TryDequeue(out ulong workshopId))
|
||||
@@ -727,6 +758,13 @@ namespace Barotrauma
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void ResetModUpdateButton()
|
||||
{
|
||||
modUpdateTask = null;
|
||||
modUpdateTimer = 0;
|
||||
modUpdatesButton.Visible = false;
|
||||
}
|
||||
|
||||
public void QuickStart(bool fixedSeed = false, Identifier sub = default, float difficulty = 50, LevelGenerationParams levelGenerationParams = null)
|
||||
{
|
||||
if (fixedSeed)
|
||||
@@ -946,15 +984,36 @@ namespace Barotrauma
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
#if !DEBUG && USE_STEAM
|
||||
modUpdateTimer -= (float)deltaTime;
|
||||
if (modUpdateTimer <= 0.0f && modUpdateTask is not { IsCompleted: false })
|
||||
{
|
||||
modUpdateTask = BulkDownloader.GetItemsThatNeedUpdating();
|
||||
modUpdateTimer = ModUpdateInterval;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
hostServerButton.Enabled = true;
|
||||
#else
|
||||
if (GameSettings.CurrentConfig.UseSteamMatchmaking)
|
||||
{
|
||||
hostServerButton.Enabled = Steam.SteamManager.IsInitialized;
|
||||
hostServerButton.Enabled = SteamManager.IsInitialized;
|
||||
}
|
||||
steamWorkshopButton.Enabled = Steam.SteamManager.IsInitialized;
|
||||
#elif USE_STEAM
|
||||
steamWorkshopButton.Enabled = true;
|
||||
#endif
|
||||
|
||||
if (modUpdateTask is { IsCompletedSuccessfully: true })
|
||||
{
|
||||
modUpdatesButton.Visible = modUpdateTask.Result.Count > 0;
|
||||
}
|
||||
|
||||
if (modUpdatesButton.Visible)
|
||||
{
|
||||
var modButtonLabelSize =
|
||||
modsButton.Font.MeasureString(modsButton.Text).ToPoint()
|
||||
+ new Point(GUI.IntScale(25));
|
||||
modUpdatesButton.RectTransform.AbsoluteOffset =
|
||||
(modButtonLabelSize.X, modsButton.Rect.Height / 2 - modUpdatesButton.Rect.Height / 2);
|
||||
}
|
||||
|
||||
switch (selectedTab)
|
||||
{
|
||||
case Tab.NewGame:
|
||||
@@ -1035,7 +1094,7 @@ namespace Barotrauma
|
||||
GUI.DrawLine(spriteBatch, textPos, textPos - Vector2.UnitX * textSize.X, mouseOn ? Color.White : Color.White * 0.7f);
|
||||
if (mouseOn && PlayerInput.PrimaryMouseButtonClicked())
|
||||
{
|
||||
GameMain.Instance.ShowOpenUrlInWebBrowserPrompt("http://privacypolicy.daedalic.com");
|
||||
GameMain.ShowOpenUrlInWebBrowserPrompt("http://privacypolicy.daedalic.com");
|
||||
}
|
||||
}
|
||||
textPos.Y -= textSize.Y;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#nullable enable
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using Barotrauma.IO;
|
||||
@@ -40,6 +41,13 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
[DoesNotReturn]
|
||||
private static void LogAndThrowException(string errorMsg, string analyticsId)
|
||||
{
|
||||
GameAnalyticsManager.AddErrorEventOnce(analyticsId, GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new InvalidOperationException(errorMsg);
|
||||
}
|
||||
|
||||
public override void Select()
|
||||
{
|
||||
base.Select();
|
||||
@@ -74,20 +82,11 @@ namespace Barotrauma
|
||||
}
|
||||
};
|
||||
|
||||
if (!GameMain.Client.IsServerOwner)
|
||||
if (!GameMain.Client.IsServerOwner && GameMain.Client.ClientPeer.ServerContentPackages.Length == 0)
|
||||
{
|
||||
if (GameMain.Client.ClientPeer.ServerContentPackages.Length == 0)
|
||||
{
|
||||
string errorMsg = $"Error in ModDownloadScreen: the list of mods the server has enabled was empty. Content package list received: {GameMain.Client.ClientPeer.ContentPackageOrderReceived}";
|
||||
GameAnalyticsManager.AddErrorEventOnce("ModDownloadScreen.Select:NoContentPackages", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new InvalidOperationException(errorMsg);
|
||||
}
|
||||
if (GameMain.Client.ClientPeer.ServerContentPackages.None(p => p.CorePackage != null))
|
||||
{
|
||||
string errorMsg = $"Error in ModDownloadScreen: no core packages in the list of mods the server has enabled. Content package list received: {GameMain.Client.ClientPeer.ContentPackageOrderReceived}";
|
||||
GameAnalyticsManager.AddErrorEventOnce("ModDownloadScreen.Select:NoCorePackage", GameAnalyticsManager.ErrorSeverity.Error, errorMsg);
|
||||
throw new InvalidOperationException(errorMsg);
|
||||
}
|
||||
LogAndThrowException("Error in ModDownloadScreen: the list of mods the server has enabled was empty. "
|
||||
+$"Content package list received: {GameMain.Client.ClientPeer.ContentPackageOrderReceived}",
|
||||
analyticsId: "ModDownloadScreen.Select:NoContentPackages");
|
||||
}
|
||||
|
||||
var missingPackages = GameMain.Client.ClientPeer.ServerContentPackages
|
||||
@@ -96,11 +95,18 @@ namespace Barotrauma
|
||||
{
|
||||
if (!GameMain.Client.IsServerOwner)
|
||||
{
|
||||
var corePackage = GameMain.Client.ClientPeer.ServerContentPackages
|
||||
.Select(p => p.CorePackage)
|
||||
.OfType<CorePackage>().FirstOrDefault();
|
||||
if (corePackage is null)
|
||||
{
|
||||
LogAndThrowException($"Error in ModDownloadScreen: no core packages in the list of mods the server has enabled. " +
|
||||
$"Content package list received: {GameMain.Client.ClientPeer.ContentPackageOrderReceived}",
|
||||
analyticsId: "ModDownloadScreen.Select:NoCorePackage");
|
||||
}
|
||||
|
||||
ContentPackageManager.EnabledPackages.BackUp();
|
||||
ContentPackageManager.EnabledPackages.SetCore(
|
||||
GameMain.Client.ClientPeer.ServerContentPackages
|
||||
.Select(p => p.CorePackage)
|
||||
.OfType<CorePackage>().First());
|
||||
ContentPackageManager.EnabledPackages.SetCore(corePackage);
|
||||
List<RegularPackage> regularPackages =
|
||||
GameMain.Client.ClientPeer.ServerContentPackages
|
||||
.Select(p => p.RegularPackage)
|
||||
@@ -114,6 +120,15 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
if (missingPackages.FirstOrDefault(p => p.IsVanilla) is { } mismatchedVanilla)
|
||||
{
|
||||
LogAndThrowException("Error in ModDownloadScreen: mismatched Vanilla package: "
|
||||
+$"local hash is {ContentPackageManager.VanillaCorePackage?.Hash.StringRepresentation ?? "[NULL]"}, "
|
||||
+$"remote hash is {mismatchedVanilla.Hash.StringRepresentation}. "
|
||||
+$"Content package list received: {GameMain.Client.ClientPeer.ContentPackageOrderReceived}",
|
||||
analyticsId: "ModDownloadScreen.Select:MismatchedVanilla");
|
||||
}
|
||||
|
||||
GUIMessageBox msgBox = new GUIMessageBox(
|
||||
TextManager.Get("ModDownloadTitle"),
|
||||
"",
|
||||
@@ -292,14 +307,23 @@ namespace Barotrauma
|
||||
var serverPackages = GameMain.Client.ClientPeer.ServerContentPackages;
|
||||
CorePackage corePackage
|
||||
= downloadedPackages.FirstOrDefault(p => p is CorePackage) as CorePackage
|
||||
?? serverPackages.FirstOrDefault(p => p.CorePackage != null)
|
||||
?.CorePackage
|
||||
?? serverPackages.FirstOrDefault(p => p.CorePackage != null)?.CorePackage
|
||||
?? throw new Exception($"Failed to find core package to enable");
|
||||
|
||||
List<RegularPackage> regularPackages = new List<RegularPackage>();
|
||||
foreach (var p in serverPackages)
|
||||
{
|
||||
if (p.CorePackage != null) { continue; }
|
||||
if (p.CorePackage != null)
|
||||
{
|
||||
// This package is one of our installed core packages
|
||||
continue;
|
||||
}
|
||||
|
||||
if (corePackage.Hash.Equals(p.Hash))
|
||||
{
|
||||
// This package is the core package we downloaded from the server
|
||||
continue;
|
||||
}
|
||||
RegularPackage? matchingPackage =
|
||||
p.RegularPackage ?? downloadedPackages.FirstOrDefault(d => d is RegularPackage && d.Hash.Equals(p.Hash)) as RegularPackage;
|
||||
if (matchingPackage is null)
|
||||
@@ -357,9 +381,13 @@ namespace Barotrauma
|
||||
string dir = path.RemoveFromEnd(ModReceiver.Extension, StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
SaveUtil.DecompressToDirectory(path, dir, file => { });
|
||||
ContentPackage newPackage
|
||||
= ContentPackage.TryLoad($"{dir}/{ContentPackage.FileListFileName}")
|
||||
?? throw new Exception($"Failed to load downloaded mod \"{currentDownload.Name}\"");
|
||||
var result = ContentPackage.TryLoad(Path.Combine(dir, ContentPackage.FileListFileName));
|
||||
|
||||
if (!result.TryUnwrapSuccess(out var newPackage))
|
||||
{
|
||||
throw new Exception($"Failed to load downloaded mod \"{currentDownload.Name}\"",
|
||||
result.TryUnwrapFailure(out var exception) ? exception : null);
|
||||
}
|
||||
if (!currentDownload.Hash.Equals(newPackage.Hash))
|
||||
{
|
||||
throw new Exception($"Hash mismatch for downloaded mod \"{currentDownload.Name}\" (expected {currentDownload.Hash}, got {newPackage.Hash})");
|
||||
|
||||
@@ -103,6 +103,10 @@ namespace Barotrauma
|
||||
public GUIFrame JobPreferenceContainer;
|
||||
public GUIListBox JobList;
|
||||
|
||||
private Identifier micIconStyle;
|
||||
private float micCheckTimer;
|
||||
const float MicCheckInterval = 1.0f;
|
||||
|
||||
private float autoRestartTimer;
|
||||
|
||||
//persistent characterinfo provided by the server
|
||||
@@ -2656,27 +2660,9 @@ namespace Barotrauma
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
|
||||
if (GameMain.Client == null) { return; }
|
||||
|
||||
Identifier currMicStyle = micIcon.Style.Element.NameAsIdentifier();
|
||||
|
||||
Identifier targetMicStyle = "GUIMicrophoneEnabled".ToIdentifier();
|
||||
var voipCaptureDeviceNames = VoipCapture.CaptureDeviceNames;
|
||||
if (voipCaptureDeviceNames.Count == 0)
|
||||
{
|
||||
targetMicStyle = "GUIMicrophoneUnavailable".ToIdentifier();
|
||||
}
|
||||
else if (GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Disabled)
|
||||
{
|
||||
targetMicStyle = "GUIMicrophoneDisabled".ToIdentifier();
|
||||
}
|
||||
|
||||
if (targetMicStyle != currMicStyle)
|
||||
{
|
||||
GUIStyle.Apply(micIcon, targetMicStyle);
|
||||
}
|
||||
UpdateMicIcon((float)deltaTime);
|
||||
|
||||
foreach (GUIComponent child in PlayerList.Content.Children)
|
||||
{
|
||||
@@ -2738,6 +2724,35 @@ namespace Barotrauma
|
||||
if (!mouseRect.Contains(PlayerInput.MousePosition)) { jobVariantTooltip = null; }
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateMicIcon(float deltaTime)
|
||||
{
|
||||
micCheckTimer -= deltaTime;
|
||||
if (micCheckTimer > 0.0f) { return; }
|
||||
|
||||
Identifier newMicIconStyle = "GUIMicrophoneEnabled".ToIdentifier();
|
||||
if (GameSettings.CurrentConfig.Audio.VoiceSetting == VoiceMode.Disabled)
|
||||
{
|
||||
newMicIconStyle = "GUIMicrophoneDisabled".ToIdentifier();
|
||||
}
|
||||
else
|
||||
{
|
||||
var voipCaptureDeviceNames = VoipCapture.GetCaptureDeviceNames();
|
||||
if (voipCaptureDeviceNames.Count == 0)
|
||||
{
|
||||
newMicIconStyle = "GUIMicrophoneUnavailable".ToIdentifier();
|
||||
}
|
||||
}
|
||||
|
||||
if (newMicIconStyle != micIconStyle)
|
||||
{
|
||||
micIconStyle = newMicIconStyle;
|
||||
GUIStyle.Apply(micIcon, newMicIconStyle);
|
||||
}
|
||||
|
||||
micCheckTimer = MicCheckInterval;
|
||||
}
|
||||
|
||||
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
||||
{
|
||||
graphics.Clear(Color.Black);
|
||||
|
||||
@@ -1352,6 +1352,10 @@ namespace Barotrauma
|
||||
|
||||
private void AddToServerList(ServerInfo serverInfo, bool skipPing = false)
|
||||
{
|
||||
if (serverInfo.PlayerCount > serverInfo.MaxPlayers) { return; }
|
||||
if (serverInfo.PlayerCount < 0) { return; }
|
||||
if (serverInfo.MaxPlayers <= 0) { return; }
|
||||
|
||||
RemoveMsgFromServerList(MsgUserData.RefreshingServerList);
|
||||
RemoveMsgFromServerList(MsgUserData.NoServers);
|
||||
var serverFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.06f), serverList.Content.RectTransform) { MinSize = new Point(0, 35) },
|
||||
|
||||
@@ -379,6 +379,9 @@ namespace Barotrauma
|
||||
|
||||
void CreateSprite(ContentXElement element)
|
||||
{
|
||||
//empty element, probably an item variant?
|
||||
if (element.Attributes().None()) { return; }
|
||||
|
||||
string spriteFolder = "";
|
||||
ContentPath texturePath = null;
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace Barotrauma
|
||||
|
||||
private GUIFrame wiringToolPanel;
|
||||
|
||||
private DateTime editorSelectedTime;
|
||||
private Option<DateTime> editorSelectedTime;
|
||||
|
||||
private GUIImage previewImage;
|
||||
private GUILayoutGroup previewImageButtonHolder;
|
||||
@@ -354,9 +354,24 @@ namespace Barotrauma
|
||||
ToolTip = RichString.Rich(TextManager.Get("SaveSubButton") + "‖color:125,125,125‖\nCtrl + S‖color:end‖"),
|
||||
OnClicked = (btn, data) =>
|
||||
{
|
||||
#if DEBUG
|
||||
if (ContentPackageManager.EnabledPackages.All.Any(cp => cp != ContentPackageManager.VanillaCorePackage && cp.Files.Any(f => f is not BaseSubFile)))
|
||||
{
|
||||
var msgBox = new GUIMessageBox("DEBUG-ONLY WARNING", "You currently have some mods enabled. Are you sure you want to save the submarine? If the mods override any vanilla content, saving the submarine may cause unintended changes.",
|
||||
new LocalizedString[] { "Yes, I know what I'm doing", "Cancel" });
|
||||
msgBox.Buttons[0].OnClicked = (btn, data) =>
|
||||
{
|
||||
msgBox.Close();
|
||||
loadFrame = null;
|
||||
CreateSaveScreen();
|
||||
return true;
|
||||
};
|
||||
msgBox.Buttons[1].OnClicked += msgBox.Close;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
loadFrame = null;
|
||||
CreateSaveScreen();
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -984,6 +999,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (MapEntityCategory category in Enum.GetValues(typeof(MapEntityCategory)))
|
||||
{
|
||||
if (category == MapEntityCategory.None) { continue; }
|
||||
entityCategoryButtons.Add(new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), entityMenuTop.RectTransform, scaleBasis: ScaleBasis.BothHeight),
|
||||
"", style: "CategoryButton." + category.ToString())
|
||||
{
|
||||
@@ -1071,6 +1087,7 @@ namespace Barotrauma
|
||||
|
||||
foreach (MapEntityCategory category in Enum.GetValues(typeof(MapEntityCategory)))
|
||||
{
|
||||
if (category == MapEntityCategory.None) { continue; }
|
||||
LocalizedString categoryName = TextManager.Get("MapEntityCategory." + category);
|
||||
maxTextWidth = (int)Math.Max(maxTextWidth, GUIStyle.SubHeadingFont.MeasureString(categoryName.Replace(" ", "\n")).X + GUI.IntScale(50));
|
||||
foreach (MapEntityPrefab ep in MapEntityPrefab.List)
|
||||
@@ -1394,7 +1411,7 @@ namespace Barotrauma
|
||||
if (backedUpSubInfo != null) { name = backedUpSubInfo.Name; }
|
||||
subNameLabel.Text = ToolBox.LimitString(name, subNameLabel.Font, subNameLabel.Rect.Width);
|
||||
|
||||
editorSelectedTime = DateTime.Now;
|
||||
editorSelectedTime = Option<DateTime>.Some(DateTime.Now);
|
||||
|
||||
GUI.ForceMouseOn(null);
|
||||
SetMode(Mode.Default);
|
||||
@@ -1543,9 +1560,13 @@ namespace Barotrauma
|
||||
autoSaveLabel?.Parent?.RemoveChild(autoSaveLabel);
|
||||
autoSaveLabel = null;
|
||||
|
||||
TimeSpan timeInEditor = DateTime.Now - editorSelectedTime;
|
||||
#if USE_STEAM
|
||||
SteamAchievementManager.IncrementStat("hoursineditor".ToIdentifier(), (float)timeInEditor.TotalHours);
|
||||
if (editorSelectedTime.TryUnwrap(out DateTime selectedTime))
|
||||
{
|
||||
TimeSpan timeInEditor = DateTime.Now - selectedTime;
|
||||
SteamAchievementManager.IncrementStat("hoursineditor".ToIdentifier(), (float)timeInEditor.TotalHours);
|
||||
editorSelectedTime = Option<DateTime>.None();
|
||||
}
|
||||
#endif
|
||||
|
||||
GUI.ForceMouseOn(null);
|
||||
@@ -2490,7 +2511,7 @@ namespace Barotrauma
|
||||
{
|
||||
IntValue = MainSub.Info.Tier,
|
||||
MinValueInt = 1,
|
||||
MaxValueInt = 3,
|
||||
MaxValueInt = SubmarineInfo.HighestTier,
|
||||
OnValueChanged = (numberInput) =>
|
||||
{
|
||||
MainSub.Info.Tier = numberInput.IntValue;
|
||||
@@ -2498,7 +2519,7 @@ namespace Barotrauma
|
||||
};
|
||||
if (MainSub?.Info != null)
|
||||
{
|
||||
MainSub.Info.Tier = Math.Clamp(MainSub.Info.Tier, 1, 3);
|
||||
MainSub.Info.Tier = Math.Clamp(MainSub.Info.Tier, 1, SubmarineInfo.HighestTier);
|
||||
}
|
||||
|
||||
var crewSizeArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.25f), subSettingsContainer.RectTransform), isHorizontal: true)
|
||||
@@ -3074,11 +3095,17 @@ namespace Barotrauma
|
||||
|
||||
XDocument doc = new XDocument(ItemAssemblyPrefab.Save(MapEntity.SelectedList.ToList(), nameBox.Text, descriptionBox.Text, hideInMenus));
|
||||
doc.SaveSafe(filePath);
|
||||
|
||||
var resultPackage = ContentPackageManager.ReloadContentPackage(existingContentPackage) as RegularPackage;
|
||||
if (!ContentPackageManager.EnabledPackages.Regular.Contains(resultPackage))
|
||||
|
||||
var result = ContentPackageManager.ReloadContentPackage(existingContentPackage);
|
||||
if (!result.TryUnwrapSuccess(out var resultPackage))
|
||||
{
|
||||
ContentPackageManager.EnabledPackages.EnableRegular(resultPackage);
|
||||
throw new Exception($"Failed to reload content package \"{existingContentPackage.Name}\"",
|
||||
result.TryUnwrapFailure(out var exception) ? exception : null);
|
||||
}
|
||||
if (resultPackage is RegularPackage regularPackage
|
||||
&& !ContentPackageManager.EnabledPackages.Regular.Contains(regularPackage))
|
||||
{
|
||||
ContentPackageManager.EnabledPackages.EnableRegular(regularPackage);
|
||||
GameSettings.SaveCurrentConfig();
|
||||
}
|
||||
|
||||
@@ -3089,7 +3116,7 @@ namespace Barotrauma
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SnapToGrid()
|
||||
private static void SnapToGrid()
|
||||
{
|
||||
// First move components
|
||||
foreach (MapEntity e in MapEntity.SelectedList)
|
||||
@@ -3102,6 +3129,10 @@ namespace Barotrauma
|
||||
var wire = item.GetComponent<Wire>();
|
||||
if (wire != null) { continue; }
|
||||
item.Move(offset);
|
||||
if (item.GetComponent<Door>()?.LinkedGap is Gap linkedGap)
|
||||
{
|
||||
linkedGap.Move(item.Position - linkedGap.Position);
|
||||
}
|
||||
}
|
||||
else if (e is Structure structure)
|
||||
{
|
||||
@@ -3126,7 +3157,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<SubmarineInfo> GetLoadableSubs()
|
||||
private static IEnumerable<SubmarineInfo> GetLoadableSubs()
|
||||
{
|
||||
string downloadFolder = Path.GetFullPath(SaveUtil.SubmarineDownloadFolder);
|
||||
return SubmarineInfo.SavedSubmarines.Where(s
|
||||
@@ -3231,7 +3262,7 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
string pathWithoutUserName = Path.GetFullPath(sub.FilePath);
|
||||
string saveFolder = Path.GetFullPath(SaveUtil.SaveFolder);
|
||||
string saveFolder = Path.GetFullPath(SaveUtil.DefaultSaveFolder);
|
||||
if (pathWithoutUserName.StartsWith(saveFolder))
|
||||
{
|
||||
pathWithoutUserName = "..." + pathWithoutUserName[saveFolder.Length..];
|
||||
@@ -3513,9 +3544,18 @@ namespace Barotrauma
|
||||
public void LoadSub(SubmarineInfo info)
|
||||
{
|
||||
Submarine.Unload();
|
||||
var selectedSub = new Submarine(info);
|
||||
MainSub = selectedSub;
|
||||
MainSub.UpdateTransform(interpolate: false);
|
||||
Submarine selectedSub = null;
|
||||
try
|
||||
{
|
||||
selectedSub = new Submarine(info);
|
||||
MainSub = selectedSub;
|
||||
MainSub.UpdateTransform(interpolate: false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
DebugConsole.ThrowError("Failed to load the submarine. The submarine file might be corrupted.", e);
|
||||
return;
|
||||
}
|
||||
ClearUndoBuffer();
|
||||
CreateDummyCharacter();
|
||||
|
||||
@@ -4220,7 +4260,8 @@ namespace Barotrauma
|
||||
GUIListBox listBox = new GUIListBox(new RectTransform(new Vector2(0.9f, 0.9f), frame.RectTransform, Anchor.Center))
|
||||
{
|
||||
PlaySoundOnSelect = true,
|
||||
OnSelected = SelectWire
|
||||
OnSelected = SelectWire,
|
||||
CanTakeKeyBoardFocus = false
|
||||
};
|
||||
|
||||
List<ItemPrefab> wirePrefabs = new List<ItemPrefab>();
|
||||
@@ -5869,7 +5910,7 @@ namespace Barotrauma
|
||||
decimal realWorldDistance = decimal.Round((decimal) (Vector2.Distance(startPos, mouseWorldPos) * Physics.DisplayToRealWorldRatio), 2);
|
||||
|
||||
Vector2 offset = new Vector2(GUI.IntScale(24));
|
||||
GUI.DrawString(spriteBatch, PlayerInput.MousePosition + offset, $"{realWorldDistance}m", GUIStyle.TextColorNormal, font: GUIStyle.SubHeadingFont, backgroundColor: Color.Black, backgroundPadding: 4);
|
||||
GUI.DrawString(spriteBatch, PlayerInput.MousePosition + offset, $"{realWorldDistance} m", GUIStyle.TextColorNormal, font: GUIStyle.Font, backgroundColor: Color.Black, backgroundPadding: 4);
|
||||
}
|
||||
|
||||
spriteBatch.End();
|
||||
|
||||
@@ -21,6 +21,7 @@ namespace Barotrauma
|
||||
|
||||
public static Character? dummyCharacter;
|
||||
public static Effect? BlueprintEffect;
|
||||
public TabMenu? TabMenu;
|
||||
|
||||
public TestScreen()
|
||||
{
|
||||
@@ -49,9 +50,10 @@ namespace Barotrauma
|
||||
}
|
||||
|
||||
dummyCharacter = Character.Create(CharacterPrefab.HumanSpeciesName, Vector2.Zero, "", id: Entity.DummyID, hasAi: false);
|
||||
dummyCharacter.Info.Job = new Job(JobPrefab.Prefabs.Where(jp => TalentTree.JobTalentTrees.ContainsKey(jp.Identifier)).GetRandom(Rand.RandSync.Unsynced));
|
||||
dummyCharacter.Info.Job = new Job(JobPrefab.Prefabs.FirstOrDefault(static jp => jp.Identifier == "assistant"));
|
||||
dummyCharacter.Info.Name = "Galldren";
|
||||
dummyCharacter.Inventory.CreateSlots();
|
||||
dummyCharacter.Info.GiveExperience(999999);
|
||||
|
||||
miniMapItem = new Item(ItemPrefab.Find(null, "deconstructor".ToIdentifier()), Vector2.Zero, null, 1337, false);
|
||||
|
||||
@@ -61,6 +63,7 @@ namespace Barotrauma
|
||||
}
|
||||
Character.Controlled = dummyCharacter;
|
||||
GameMain.World.ProcessChanges();
|
||||
TabMenu = new TabMenu();
|
||||
}
|
||||
|
||||
public override void AddToGUIUpdateList()
|
||||
@@ -68,35 +71,37 @@ namespace Barotrauma
|
||||
Frame.AddToGUIUpdateList();
|
||||
CharacterHUD.AddToGUIUpdateList(dummyCharacter);
|
||||
dummyCharacter?.SelectedItem?.AddToGUIUpdateList();
|
||||
TabMenu?.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
public override void Update(double deltaTime)
|
||||
{
|
||||
base.Update(deltaTime);
|
||||
TabMenu?.Update((float)deltaTime);
|
||||
|
||||
if (dummyCharacter is { } dummy && miniMapItem is { } item)
|
||||
{
|
||||
if (dummy.SelectedItem != item)
|
||||
{
|
||||
dummy.SelectedItem = item;
|
||||
}
|
||||
|
||||
dummy.SelectedItem?.UpdateHUD(Cam, dummy, (float)deltaTime);
|
||||
Vector2 pos = FarseerPhysics.ConvertUnits.ToSimUnits(item.Position);
|
||||
|
||||
foreach (Limb limb in dummy.AnimController.Limbs)
|
||||
{
|
||||
limb.body.SetTransform(pos, 0.0f);
|
||||
}
|
||||
|
||||
if (dummy.AnimController?.Collider is { } collider)
|
||||
{
|
||||
collider.SetTransform(pos, 0);
|
||||
}
|
||||
|
||||
dummy.ControlLocalPlayer((float)deltaTime, Cam, false);
|
||||
dummy.Control((float)deltaTime, Cam);
|
||||
}
|
||||
// if (dummyCharacter is { } dummy && miniMapItem is { } item)
|
||||
// {
|
||||
// if (dummy.SelectedConstruction != item)
|
||||
// {
|
||||
// dummy.SelectedConstruction = item;
|
||||
// }
|
||||
//
|
||||
// dummy.SelectedConstruction?.UpdateHUD(Cam, dummy, (float)deltaTime);
|
||||
// Vector2 pos = FarseerPhysics.ConvertUnits.ToSimUnits(item.Position);
|
||||
//
|
||||
// foreach (Limb limb in dummy.AnimController.Limbs)
|
||||
// {
|
||||
// limb.body.SetTransform(pos, 0.0f);
|
||||
// }
|
||||
//
|
||||
// if (dummy.AnimController?.Collider is { } collider)
|
||||
// {
|
||||
// collider.SetTransform(pos, 0);
|
||||
// }
|
||||
//
|
||||
// dummy.ControlLocalPlayer((float)deltaTime, Cam, false);
|
||||
// dummy.Control((float)deltaTime, Cam);
|
||||
// }
|
||||
}
|
||||
|
||||
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
|
||||
|
||||
Reference in New Issue
Block a user