v1.4.4.1 (Blood in the Water Update)

This commit is contained in:
Regalis11
2024-04-24 18:09:05 +03:00
parent 89b91d1c3e
commit ff1b8951a7
397 changed files with 15250 additions and 6479 deletions
@@ -1,12 +1,10 @@
using Barotrauma.Extensions;
using Barotrauma.Extensions;
using Barotrauma.IO;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using Barotrauma.IO;
using System.Collections.Immutable;
using System.Globalization;
using System.Linq;
using System.Xml.Linq;
namespace Barotrauma
{
@@ -56,12 +54,16 @@ namespace Barotrauma
return null;
}
var saveFrame = new GUIFrame(new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform) { MinSize = new Point(0, 45) }, style: "ListBoxElement")
var saveFrame = new GUIFrame(
new RectTransform(new Vector2(1.0f, 0.1f), saveList.Content.RectTransform) { MinSize = new Point(0, 45) },
style: "ListBoxElement")
{
UserData = saveInfo
};
var nameText = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform), Path.GetFileNameWithoutExtension(saveInfo.FilePath),
var nameText = new GUITextBlock(
new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform),
Path.GetFileNameWithoutExtension(saveInfo.FilePath),
textColor: GUIStyle.TextColorBright)
{
CanBeFocused = false
@@ -79,8 +81,10 @@ namespace Barotrauma
prevSaveFiles ??= new List<CampaignMode.SaveInfo>();
prevSaveFiles.Add(saveInfo);
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
text: saveInfo.SubmarineName, font: GUIStyle.SmallFont)
new GUITextBlock(
new RectTransform(new Vector2(1.0f, 0.5f), saveFrame.RectTransform, Anchor.BottomLeft),
text: saveInfo.SubmarineName,
font: GUIStyle.SmallFont)
{
CanBeFocused = false,
UserData = saveInfo.FilePath
@@ -91,8 +95,11 @@ namespace Barotrauma
{
saveTimeStr = time.ToLocalUserString();
}
new GUITextBlock(new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform),
text: saveTimeStr, textAlignment: Alignment.Right, font: GUIStyle.SmallFont)
new GUITextBlock(
new RectTransform(new Vector2(1.0f, 1.0f), saveFrame.RectTransform),
text: saveTimeStr,
textAlignment: Alignment.Right,
font: GUIStyle.SmallFont)
{
CanBeFocused = false,
UserData = saveInfo.FilePath
@@ -127,9 +134,19 @@ namespace Barotrauma
public SettingValue<bool> TutorialEnabled;
public SettingValue<bool> RadiationEnabled;
public SettingValue<int> MaxMissionCount;
public SettingValue<StartingBalanceAmount> StartingFunds;
public SettingValue<GameDifficulty> Difficulty;
public SettingValue<StartingBalanceAmountOption> StartingFunds;
public SettingValue<WorldHostilityOption> WorldHostility;
public SettingValue<Identifier> StartItemSet;
public SettingValue<float> CrewVitalityMultiplier;
public SettingValue<float> NonCrewVitalityMultiplier;
public SettingValue<float> OxygenMultiplier;
public SettingValue<float> FuelMultiplier;
public SettingValue<float> MissionRewardMultiplier;
public SettingValue<float> ShopPriceMultiplier;
public SettingValue<float> ShipyardPriceMultiplier;
public SettingValue<float> RepairFailMultiplier;
public SettingValue<PatdownProbabilityOption> PatdownProbability;
public SettingValue<bool> ShowHuskWarning;
public readonly CampaignSettings CreateSettings()
{
@@ -140,8 +157,18 @@ namespace Barotrauma
RadiationEnabled = RadiationEnabled.GetValue(),
MaxMissionCount = MaxMissionCount.GetValue(),
StartingBalanceAmount = StartingFunds.GetValue(),
Difficulty = Difficulty.GetValue(),
StartItemSet = StartItemSet.GetValue()
WorldHostility = WorldHostility.GetValue(),
StartItemSet = StartItemSet.GetValue(),
CrewVitalityMultiplier = CrewVitalityMultiplier.GetValue(),
NonCrewVitalityMultiplier = NonCrewVitalityMultiplier.GetValue(),
OxygenMultiplier = OxygenMultiplier.GetValue(),
FuelMultiplier = FuelMultiplier.GetValue(),
MissionRewardMultiplier = MissionRewardMultiplier.GetValue(),
ShopPriceMultiplier = ShopPriceMultiplier.GetValue(),
ShipyardPriceMultiplier = ShipyardPriceMultiplier.GetValue(),
RepairFailMultiplier = RepairFailMultiplier.GetValue(),
PatdownProbability = PatdownProbability.GetValue(),
ShowHuskWarning = ShowHuskWarning.GetValue(),
};
}
}
@@ -188,9 +215,16 @@ namespace Barotrauma
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 + 1);
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 + 1);
presetDropdown.AddItem(TextManager.Get("karmapreset.custom"), null);
presetDropdown.Select(0);
@@ -216,37 +250,235 @@ 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, 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);
// GENERAL CAMPAIGN SETTINGS:
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, OnValuesChanged);
NetLobbyScreen.CreateSubHeader("campaignsettingcategories.general", settingsList.Content);
ImmutableArray<SettingCarouselElement<StartingBalanceAmount>> fundOptions = ImmutableArray.Create(
new SettingCarouselElement<StartingBalanceAmount>(StartingBalanceAmount.Low, "startingfunds.low"),
new SettingCarouselElement<StartingBalanceAmount>(StartingBalanceAmount.Medium, "startingfunds.medium"),
new SettingCarouselElement<StartingBalanceAmount>(StartingBalanceAmount.High, "startingfunds.high")
// Tutorial
SettingValue<bool> tutorialEnabled = isSinglePlayer
? CreateTickbox(
settingsList.Content,
TextManager.Get("CampaignOption.EnableTutorial"),
TextManager.Get("campaignoption.enabletutorial.tooltip"),
prevSettings.TutorialEnabled,
verticalSize,
OnValuesChanged)
: new SettingValue<bool>(static () => false, static _ => { });
// Jovian radiation
SettingValue<bool> radiationEnabled = CreateTickbox(
settingsList.Content,
TextManager.Get("CampaignOption.EnableRadiation"),
TextManager.Get("campaignoption.enableradiation.tooltip"),
prevSettings.RadiationEnabled,
verticalSize,
OnValuesChanged);
// RESOURCE-RELATED CAMPAIGN SETTINGS:
NetLobbyScreen.CreateSubHeader("campaignsettingcategories.resources", settingsList.Content);
// Starting set
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,
OnValuesChanged);
// Starting money
ImmutableArray<SettingCarouselElement<StartingBalanceAmountOption>> fundOptions = ImmutableArray.Create(
new SettingCarouselElement<StartingBalanceAmountOption>(StartingBalanceAmountOption.Low, "startingfunds.low"),
new SettingCarouselElement<StartingBalanceAmountOption>(StartingBalanceAmountOption.Medium, "startingfunds.medium"),
new SettingCarouselElement<StartingBalanceAmountOption>(StartingBalanceAmountOption.High, "startingfunds.high")
);
SettingCarouselElement<StartingBalanceAmountOption> prevStartingFund = fundOptions
.FirstOrNull(element => element.Value == prevSettings.StartingBalanceAmount)
?? fundOptions[1];
SettingValue<StartingBalanceAmountOption> startingFundsInput = CreateSelectionCarousel(
settingsList.Content,
TextManager.Get("startingfundsdescription"),
TextManager.Get("startingfundstooltip"),
prevStartingFund,
verticalSize,
fundOptions,
OnValuesChanged);
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, OnValuesChanged);
ImmutableArray<SettingCarouselElement<GameDifficulty>> difficultyOptions = ImmutableArray.Create(
new SettingCarouselElement<GameDifficulty>(GameDifficulty.Easy, "difficulty.easy"),
new SettingCarouselElement<GameDifficulty>(GameDifficulty.Medium, "difficulty.medium"),
new SettingCarouselElement<GameDifficulty>(GameDifficulty.Hard, "difficulty.hard"),
new SettingCarouselElement<GameDifficulty>(GameDifficulty.Hellish, "difficulty.hellish", isHidden: true)
);
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, OnValuesChanged);
SettingValue<int> maxMissionCountInput = CreateGUINumberInputCarousel(settingsList.Content, TextManager.Get("maxmissioncount"), TextManager.Get("maxmissioncounttooltip"),
// Max mission count
SettingValue<int> maxMissionCountInput = CreateGUIIntegerInputCarousel(
settingsList.Content,
TextManager.Get("maxmissioncount"),
TextManager.Get("maxmissioncounttooltip"),
prevSettings.MaxMissionCount,
valueStep: 1, minValue: CampaignSettings.MinMissionCountLimit, maxValue: CampaignSettings.MaxMissionCountLimit,
valueStep: 1,
minValue: CampaignSettings.MinMissionCountLimit,
maxValue: CampaignSettings.MaxMissionCountLimit,
verticalSize,
OnValuesChanged);
// Mission reward multiplier
CampaignSettings.MultiplierSettings rewardMultiplierSettings = CampaignSettings.GetMultiplierSettings("MissionRewardMultiplier");
SettingValue<float> rewardMultiplier = CreateGUIFloatInputCarousel(
settingsList.Content,
TextManager.Get("campaignoption.missionrewardmultiplier"),
TextManager.Get("campaignoption.missionrewardmultiplier.tooltip"),
prevSettings.MissionRewardMultiplier,
valueStep: rewardMultiplierSettings.Step,
minValue: rewardMultiplierSettings.Min,
maxValue: rewardMultiplierSettings.Max,
verticalSize,
OnValuesChanged);
// Shop buying prices multiplier
CampaignSettings.MultiplierSettings shopPriceMultiplierSettings = CampaignSettings.GetMultiplierSettings("ShopPriceMultiplier");
SettingValue<float> shopPriceMultiplier = CreateGUIFloatInputCarousel(
settingsList.Content,
TextManager.Get("campaignoption.shoppricemultiplier"),
TextManager.Get("campaignoption.shoppricemultiplier.tooltip"),
prevSettings.ShopPriceMultiplier,
valueStep: shopPriceMultiplierSettings.Step,
minValue: shopPriceMultiplierSettings.Min,
maxValue: shopPriceMultiplierSettings.Max,
verticalSize,
OnValuesChanged);
// Shipyard prices multiplier
CampaignSettings.MultiplierSettings shipyardPriceMultiplierSettings = CampaignSettings.GetMultiplierSettings("ShipyardPriceMultiplier");
SettingValue<float> shipyardPriceMultiplier = CreateGUIFloatInputCarousel(
settingsList.Content,
TextManager.Get("campaignoption.shipyardpricemultiplier"),
TextManager.Get("campaignoption.shipyardpricemultiplier.tooltip"),
prevSettings.ShipyardPriceMultiplier,
valueStep: shipyardPriceMultiplierSettings.Step,
minValue: shipyardPriceMultiplierSettings.Min,
maxValue: shipyardPriceMultiplierSettings.Max,
verticalSize,
OnValuesChanged);
// OVERALL HAZARD-RELATED CAMPAIGN SETTINGS:
NetLobbyScreen.CreateSubHeader("campaignsettingcategories.hazards", settingsList.Content);
// World hostility (used to be "Difficulty" or level difficulty)
ImmutableArray<SettingCarouselElement<WorldHostilityOption>> hostilityOptions = ImmutableArray.Create(
new SettingCarouselElement<WorldHostilityOption>(WorldHostilityOption.Low, "worldhostility.low"),
new SettingCarouselElement<WorldHostilityOption>(WorldHostilityOption.Medium, "worldhostility.medium"),
new SettingCarouselElement<WorldHostilityOption>(WorldHostilityOption.High, "worldhostility.high"),
new SettingCarouselElement<WorldHostilityOption>(WorldHostilityOption.Hellish, "worldhostility.hellish", isHidden: true)
);
SettingCarouselElement<WorldHostilityOption> prevHostility = hostilityOptions
.FirstOrNull(element => element.Value == prevSettings.WorldHostility)
?? hostilityOptions[1];
SettingValue<WorldHostilityOption> hostilityInput = CreateSelectionCarousel(
settingsList.Content,
TextManager.Get("worldhostility"),
TextManager.Get("worldhostility.tooltip"),
prevHostility,
verticalSize,
hostilityOptions,
OnValuesChanged);
// Crew max vitality multiplier
CampaignSettings.MultiplierSettings crewVitalityMultiplierSettings = CampaignSettings.GetMultiplierSettings("CrewVitalityMultiplier");
SettingValue<float> crewVitalityMultiplier = CreateGUIFloatInputCarousel(
settingsList.Content,
TextManager.Get("campaignoption.maxvitalitymultipliercrew"),
TextManager.Get("campaignoption.maxvitalitymultipliercrew.tooltip"),
prevSettings.CrewVitalityMultiplier,
valueStep: crewVitalityMultiplierSettings.Step,
minValue: crewVitalityMultiplierSettings.Min,
maxValue: crewVitalityMultiplierSettings.Max,
verticalSize,
OnValuesChanged);
// Non-crew max vitality multiplier
CampaignSettings.MultiplierSettings nonCrewVitalityMultiplierSettings = CampaignSettings.GetMultiplierSettings("NonCrewVitalityMultiplier");
SettingValue<float> nonCrewVitalityMultiplier = CreateGUIFloatInputCarousel(
settingsList.Content,
TextManager.Get("campaignoption.maxvitalitymultipliernoncrew"),
TextManager.Get("campaignoption.maxvitalitymultipliernoncrew.tooltip"),
prevSettings.NonCrewVitalityMultiplier,
valueStep: nonCrewVitalityMultiplierSettings.Step,
minValue: nonCrewVitalityMultiplierSettings.Min,
maxValue: nonCrewVitalityMultiplierSettings.Max,
verticalSize,
OnValuesChanged);
// Oxygen source multiplier
CampaignSettings.MultiplierSettings oxygenSourceMultiplierSettings = CampaignSettings.GetMultiplierSettings("OxygenMultiplier");
SettingValue<float> oxygenMultiplier = CreateGUIFloatInputCarousel(
settingsList.Content,
TextManager.Get("campaignoption.oxygensourcemultiplier"),
TextManager.Get("campaignoption.oxygensourcemultiplier.tooltip"),
prevSettings.OxygenMultiplier,
valueStep: oxygenSourceMultiplierSettings.Step,
minValue: oxygenSourceMultiplierSettings.Min,
maxValue: oxygenSourceMultiplierSettings.Max,
verticalSize,
OnValuesChanged);
// Reactor fuel multiplier
CampaignSettings.MultiplierSettings reactorFuelMultiplierSettings = CampaignSettings.GetMultiplierSettings("FuelMultiplier");
SettingValue<float> fuelMultiplier = CreateGUIFloatInputCarousel(
settingsList.Content,
TextManager.Get("campaignoption.reactorfuelmultiplier"),
TextManager.Get("campaignoption.reactorfuelmultiplier.tooltip"),
prevSettings.FuelMultiplier,
valueStep: reactorFuelMultiplierSettings.Step,
minValue: reactorFuelMultiplierSettings.Min,
maxValue: reactorFuelMultiplierSettings.Max,
verticalSize,
OnValuesChanged);
// Repair fail effect multiplier
CampaignSettings.MultiplierSettings repairFailMultiplierSettings = CampaignSettings.GetMultiplierSettings("RepairFailMultiplier");
SettingValue<float> repairFailMultiplier = CreateGUIFloatInputCarousel(
settingsList.Content,
TextManager.Get("campaignoption.repairfailmultiplier"),
TextManager.Get("campaignoption.repairfailmultiplier.tooltip"),
prevSettings.RepairFailMultiplier,
valueStep: repairFailMultiplierSettings.Step,
minValue: repairFailMultiplierSettings.Min,
maxValue: repairFailMultiplierSettings.Max,
verticalSize,
OnValuesChanged);
ImmutableArray<SettingCarouselElement<PatdownProbabilityOption>> patdownProbabilityPresets = ImmutableArray.Create(
new SettingCarouselElement<PatdownProbabilityOption>(PatdownProbabilityOption.Off, "probability.off"),
new SettingCarouselElement<PatdownProbabilityOption>(PatdownProbabilityOption.Low, "probability.low"),
new SettingCarouselElement<PatdownProbabilityOption>(PatdownProbabilityOption.Medium, "probability.medium"),
new SettingCarouselElement<PatdownProbabilityOption>(PatdownProbabilityOption.High, "probability.high")
);
SettingCarouselElement<PatdownProbabilityOption> prevPatdownProbability = patdownProbabilityPresets
.FirstOrNull(element => element.Value == prevSettings.PatdownProbability)
?? patdownProbabilityPresets[1]; // middle option
SettingValue<PatdownProbabilityOption> patdownProbability = CreateSelectionCarousel(
settingsList.Content,
TextManager.Get("campaignoption.patdownprobability"),
TextManager.Get("campaignoption.patdownprobability.tooltip"),
prevPatdownProbability,
verticalSize,
patdownProbabilityPresets,
OnValuesChanged);
// Show initial husk warning
SettingValue<bool> huskWarning = CreateTickbox(
settingsList.Content,
TextManager.Get("campaignoption.showhuskwarning"),
TextManager.Get("campaignoption.showhuskwarning.tooltip"),
prevSettings.ShowHuskWarning,
verticalSize,
OnValuesChanged);
@@ -259,8 +491,18 @@ namespace Barotrauma
radiationEnabled.SetValue(settings.RadiationEnabled);
maxMissionCountInput.SetValue(settings.MaxMissionCount);
startingFundsInput.SetValue(settings.StartingBalanceAmount);
difficultyInput.SetValue(settings.Difficulty);
hostilityInput.SetValue(settings.WorldHostility);
startingSetInput.SetValue(settings.StartItemSet);
crewVitalityMultiplier.SetValue(settings.CrewVitalityMultiplier);
nonCrewVitalityMultiplier.SetValue(settings.NonCrewVitalityMultiplier);
oxygenMultiplier.SetValue(settings.OxygenMultiplier);
fuelMultiplier.SetValue(settings.FuelMultiplier);
rewardMultiplier.SetValue(settings.MissionRewardMultiplier);
shopPriceMultiplier.SetValue(settings.ShopPriceMultiplier);
shipyardPriceMultiplier.SetValue(settings.ShipyardPriceMultiplier);
repairFailMultiplier.SetValue(settings.RepairFailMultiplier);
patdownProbability.SetValue(settings.PatdownProbability);
huskWarning.SetValue(settings.ShowHuskWarning);
loadingPreset = false;
return true;
};
@@ -268,7 +510,7 @@ namespace Barotrauma
void OnValuesChanged()
{
if (loadingPreset) { return; }
presetDropdown.Select(0);
presetDropdown.Select(0); // Switch to the Custom preset if this is an actual user-made change
}
return new CampaignSettingElements
@@ -278,70 +520,178 @@ namespace Barotrauma
RadiationEnabled = radiationEnabled,
MaxMissionCount = maxMissionCountInput,
StartingFunds = startingFundsInput,
Difficulty = difficultyInput,
StartItemSet = startingSetInput
WorldHostility = hostilityInput,
StartItemSet = startingSetInput,
CrewVitalityMultiplier = crewVitalityMultiplier,
NonCrewVitalityMultiplier = nonCrewVitalityMultiplier,
OxygenMultiplier = oxygenMultiplier,
FuelMultiplier = fuelMultiplier,
MissionRewardMultiplier = rewardMultiplier,
ShopPriceMultiplier = shopPriceMultiplier,
ShipyardPriceMultiplier = shipyardPriceMultiplier,
RepairFailMultiplier = repairFailMultiplier,
PatdownProbability = patdownProbability,
ShowHuskWarning = huskWarning,
};
// 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, Action onChanged)
// 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> CreateGUIIntegerInputCarousel(
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);
GUILayoutGroup inputContainer = CreateSettingBase(
parent,
description,
tooltip,
horizontalSize: 0.55f,
verticalSize: verticalSize);
GUIButton minusButton = new GUIButton(new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIMinusButton", textAlignment: Alignment.Center)
{
ClickSound = GUISoundType.Decrease,
UserData = -valueStep
};
GUINumberInput numberInput = new GUINumberInput(new RectTransform(Vector2.One, inputContainer.RectTransform, Anchor.Center), NumberType.Int, textAlignment: Alignment.Center, style: "GUITextBox",
hidePlusMinusButtons: true)
GUIButton minusButton = new GUIButton(
new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: "GUIMinusButton",
textAlignment: Alignment.Center);
RectTransform numberInputRect = new(Vector2.One, inputContainer.RectTransform, Anchor.Center);
GUIButton plusButton = new GUIButton(
new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: "GUIPlusButton",
textAlignment: Alignment.Center);
GUINumberInput numberInput = new GUINumberInput(
numberInputRect,
NumberType.Int,
textAlignment: Alignment.Center,
style: "GUITextBox",
buttonVisibility: GUINumberInput.ButtonVisibility.ForceVisible,
customPlusMinusButtons: (plusButton, minusButton))
{
IntValue = defaultValue,
MinValueInt = minValue,
MaxValueInt = maxValue
MaxValueInt = maxValue,
ValueStep = valueStep,
ToolTip = tooltip
};
inputContainer.RectTransform.Parent.MinSize = new Point(0, numberInput.RectTransform.MinSize.Y);
GUIButton plusButton = new GUIButton(new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIPlusButton", textAlignment: Alignment.Center)
{
ClickSound = GUISoundType.Increase,
UserData = valueStep
};
minusButton.OnClicked = plusButton.OnClicked = ChangeValue;
numberInput.OnValueChanged += _ => onChanged();
bool ChangeValue(GUIButton btn, object userData)
{
if (userData is not int change) { return false; }
numberInput.IntValue += change;
return true;
}
return new SettingValue<int>(() => numberInput.IntValue, i => numberInput.IntValue = i);
return new SettingValue<int>(
() => numberInput.IntValue,
i => numberInput.IntValue = i);
}
static SettingValue<T> CreateSelectionCarousel<T>(GUIComponent parent, LocalizedString description, LocalizedString tooltip, SettingCarouselElement<T> defaultValue, float verticalSize,
ImmutableArray<SettingCarouselElement<T>> options, Action onChanged)
static SettingValue<float> CreateGUIFloatInputCarousel(
GUIComponent parent,
LocalizedString description,
LocalizedString tooltip,
float defaultValue,
float valueStep,
float minValue,
float maxValue,
float verticalSize,
Action onChanged)
{
GUILayoutGroup inputContainer = CreateSettingBase(parent, description, tooltip, horizontalSize: 0.55f, verticalSize: verticalSize);
GUILayoutGroup inputContainer = CreateSettingBase(
parent,
description,
tooltip,
horizontalSize: 0.55f,
verticalSize: verticalSize);
GUIButton minusButton = new GUIButton(new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonToggleLeft", textAlignment: Alignment.Center) { UserData = -1 };
GUIFrame inputFrame = new GUIFrame(new RectTransform(Vector2.One, inputContainer.RectTransform), style: null);
GUINumberInput numberInput = new GUINumberInput(new RectTransform(Vector2.One, inputFrame.RectTransform, Anchor.Center), NumberType.Int, textAlignment: Alignment.Center, style: "GUITextBox", hidePlusMinusButtons: true)
GUIButton minusButton = new GUIButton(
new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: "GUIMinusButton",
textAlignment: Alignment.Center);
RectTransform numberInputRect = new(Vector2.One, inputContainer.RectTransform, Anchor.Center);
GUIButton plusButton = new GUIButton(
new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: "GUIPlusButton",
textAlignment: Alignment.Center);
GUINumberInput numberInput = new GUINumberInput(
numberInputRect,
NumberType.Float,
textAlignment: Alignment.Center,
style: "GUITextBox",
buttonVisibility: GUINumberInput.ButtonVisibility.ForceVisible,
customPlusMinusButtons: (plusButton, minusButton))
{
FloatValue = defaultValue,
MinValueFloat = minValue,
MaxValueFloat = maxValue,
ValueStep = valueStep,
ToolTip = tooltip
};
numberInput.RectTransform.Parent.MinSize = new Point(0, numberInput.RectTransform.MinSize.Y);
numberInput.OnValueChanged += _ => onChanged();
return new SettingValue<float>(
() => numberInput.FloatValue,
i => numberInput.FloatValue = (float)Math.Round(i, 1));
}
static SettingValue<T> CreateSelectionCarousel<T>(
GUIComponent parent,
LocalizedString description,
LocalizedString tooltip,
SettingCarouselElement<T> defaultValue,
float verticalSize,
ImmutableArray<SettingCarouselElement<T>> options,
Action onChanged)
{
GUILayoutGroup inputContainer = CreateSettingBase(
parent,
description,
tooltip,
horizontalSize: 0.55f,
verticalSize: verticalSize);
GUIButton minusButton = new GUIButton(
new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: "GUIButtonToggleLeft",
textAlignment: Alignment.Center)
{
UserData = -1
};
GUIFrame inputFrame = new GUIFrame(
new RectTransform(Vector2.One, inputContainer.RectTransform),
style: null);
GUINumberInput numberInput = new GUINumberInput(
new RectTransform(Vector2.One, inputFrame.RectTransform, Anchor.Center),
NumberType.Int,
textAlignment: Alignment.Center,
style: "GUITextBox",
buttonVisibility: GUINumberInput.ButtonVisibility.ForceHidden)
{
IntValue = options.IndexOf(defaultValue),
MinValueInt = 0,
MaxValueInt = options.Length,
Visible = false
Visible = false,
ToolTip = tooltip
};
inputContainer.RectTransform.Parent.MinSize = new Point(0, numberInput.RectTransform.MinSize.Y);
GUITextBox inputLabel = new GUITextBox(new RectTransform(Vector2.One, inputFrame.RectTransform, Anchor.Center), text: defaultValue.Label.Value, textAlignment: Alignment.Center, createPenIcon: false)
GUITextBox inputLabel = new GUITextBox(
new RectTransform(Vector2.One, inputFrame.RectTransform, Anchor.Center),
text: defaultValue.Label.Value,
textAlignment: Alignment.Center,
createPenIcon: false)
{
CanBeFocused = false
};
GUIButton plusButton = new GUIButton(new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight), style: "GUIButtonToggleRight", textAlignment: Alignment.Center) { UserData = 1 };
GUIButton plusButton = new GUIButton(
new RectTransform(Vector2.One, inputContainer.RectTransform, scaleBasis: ScaleBasis.BothHeight),
style: "GUIButtonToggleRight",
textAlignment: Alignment.Center)
{
UserData = 1
};
minusButton.OnClicked = plusButton.OnClicked = ChangeValue;
@@ -381,20 +731,33 @@ namespace Barotrauma
inputLabel.Text = options[value].Label.Value;
}
return new SettingValue<T>(() => options[numberInput.IntValue].Value, t => SetValue(options.IndexOf(e => Equals(e.Value, t))));
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, Action onChanged)
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);
GUITickBox tickBox = new GUITickBox(new RectTransform(Vector2.One, tickboxContainer.RectTransform), string.Empty)
GUILayoutGroup inputContainer = CreateSettingBase(parent, description, tooltip, 0.625f, verticalSize);
GUILayoutGroup tickboxContainer = new GUILayoutGroup(
new RectTransform(new Vector2(0.375f, 1.0f), inputContainer.RectTransform),
childAnchor: Anchor.Center);
GUITickBox tickBox = new GUITickBox(
new RectTransform(Vector2.One, tickboxContainer.RectTransform),
string.Empty)
{
Selected = defaultValue,
ToolTip = tooltip
};
tickBox.Box.IgnoreLayoutGroups = true;
tickBox.Box.RectTransform.SetPosition(Anchor.CenterRight);
tickBox.Box.RectTransform.SetPosition(Anchor.CenterLeft);
inputContainer.RectTransform.Parent.MinSize = new Point(0, tickBox.RectTransform.MinSize.Y);
tickBox.OnSelected += _ =>
@@ -406,11 +769,29 @@ namespace Barotrauma
return new SettingValue<bool>(() => tickBox.Selected, b => tickBox.Selected = b);
}
static GUILayoutGroup CreateSettingBase(GUIComponent parent, LocalizedString description, LocalizedString tooltip, float horizontalSize, float verticalSize)
static GUILayoutGroup CreateSettingBase(
GUIComponent parent,
LocalizedString description,
LocalizedString tooltip,
float horizontalSize,
float verticalSize)
{
GUILayoutGroup settingHolder = new GUILayoutGroup(new RectTransform(new Vector2(1f, verticalSize), parent.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
GUITextBlock descriptionBlock = new GUITextBlock(new RectTransform(new Vector2(horizontalSize, 1f), settingHolder.RectTransform), description, font: parent.Rect.Width < 320 ? GUIStyle.SmallFont : GUIStyle.Font, wrap: true) { ToolTip = tooltip };
GUILayoutGroup inputContainer = new GUILayoutGroup(new RectTransform(new Vector2(1f - horizontalSize, 0.8f), settingHolder.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft)
GUILayoutGroup settingHolder = new GUILayoutGroup(
new RectTransform(new Vector2(1f, verticalSize), parent.RectTransform),
isHorizontal: true,
childAnchor: Anchor.CenterLeft);
GUITextBlock descriptionBlock = new GUITextBlock(
new RectTransform(new Vector2(horizontalSize, 1f), settingHolder.RectTransform),
description,
font: parent.Rect.Width < 320 ? GUIStyle.SmallFont : GUIStyle.Font,
wrap: true)
{
ToolTip = tooltip
};
GUILayoutGroup inputContainer = new GUILayoutGroup(
new RectTransform(new Vector2(1f - horizontalSize, 0.8f), settingHolder.RectTransform),
isHorizontal: true,
childAnchor: Anchor.CenterLeft)
{
RelativeSpacing = 0.05f,
Stretch = true
@@ -1,10 +1,7 @@
using Barotrauma.Extensions;
using Barotrauma.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
namespace Barotrauma
{
@@ -14,16 +11,20 @@ namespace Barotrauma
private int prevInitialMoney;
private CampaignSettingElements campaignSettingElements;
public bool LoadGameMenuVisible => loadGameContainer is { Visible: true };
public MultiPlayerCampaignSetupUI(GUIComponent newGameContainer, GUIComponent loadGameContainer, List<CampaignMode.SaveInfo> saveFiles = null)
: base(newGameContainer, loadGameContainer)
{
var verticalLayout = new GUILayoutGroup(new RectTransform(Vector2.One, newGameContainer.RectTransform), isHorizontal: false)
{
Stretch = true,
RelativeSpacing = 0.05f
RelativeSpacing = 0.025f
};
GUILayoutGroup nameSeedLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.3f), verticalLayout.RectTransform), isHorizontal: false)
GUILayoutGroup nameSeedLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), verticalLayout.RectTransform), isHorizontal: false)
{
Stretch = true
};
@@ -31,119 +32,41 @@ namespace Barotrauma
GUILayoutGroup campaignSettingLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.6f), verticalLayout.RectTransform), isHorizontal: false)
{
Stretch = true,
RelativeSpacing = 0.05f
RelativeSpacing = 0.0f
};
// New game
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)
var saveLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform) { MinSize = new Point(0, GUI.IntScale(24)) }, TextManager.Get("SaveName"), textAlignment: Alignment.CenterLeft);
saveNameBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), saveLabel.RectTransform, Anchor.CenterRight), string.Empty)
{
textFilterFunction = ToolBox.RemoveInvalidFileNameChars
};
saveLabel.InheritTotalChildrenMinHeight();
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));
var seedLabel = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.03f), nameSeedLayout.RectTransform) { MinSize = new Point(0, GUI.IntScale(24)) }, TextManager.Get("MapSeed"), textAlignment: Alignment.CenterLeft);
seedBox = new GUITextBox(new RectTransform(new Vector2(0.5f, 1.0f), seedLabel.RectTransform, Anchor.CenterRight), ToolBox.RandomSeed(8));
seedLabel.InheritTotalChildrenMinHeight();
nameSeedLayout.RectTransform.MinSize = new Point(0, nameSeedLayout.Children.Sum(c => c.RectTransform.MinSize.Y));
nameSeedLayout.InheritTotalChildrenMinHeight();
CampaignSettingElements elements = CreateCampaignSettingList(campaignSettingLayout, CampaignSettings.Empty, false);
campaignSettingElements = 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);
verticalLayout.RectTransform) { MaxSize = new Point(int.MaxValue, GUI.IntScale(30)) }, childAnchor: Anchor.BottomRight, isHorizontal: true);
StartButton = new GUIButton(new RectTransform(new Vector2(0.4f, 1f), buttonContainer.RectTransform, Anchor.BottomRight), TextManager.Get("StartCampaignButton"))
{
OnClicked = (GUIButton btn, object userData) =>
{
if (string.IsNullOrWhiteSpace(saveNameBox.Text))
{
saveNameBox.Flash(GUIStyle.Red);
return false;
}
SubmarineInfo selectedSub = null;
if (GameMain.NetLobbyScreen.SelectedSub == null) { return false; }
selectedSub = GameMain.NetLobbyScreen.SelectedSub;
if (selectedSub.SubmarineClass == SubmarineClass.Undefined)
{
new GUIMessageBox(TextManager.Get("error"), TextManager.Get("undefinedsubmarineselected"));
return false;
}
if (string.IsNullOrEmpty(selectedSub.MD5Hash.StringRepresentation))
{
new GUIMessageBox(TextManager.Get("error"), TextManager.Get("nohashsubmarineselected"));
return false;
}
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveNameBox.Text);
bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;
CampaignSettings settings = elements.CreateSettings();
if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages)
{
if (!hasRequiredContentPackages)
{
var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"),
TextManager.GetWithVariable("ContentPackageMismatchWarning", "[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)),
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
msgBox.Buttons[0].OnClicked = msgBox.Close;
msgBox.Buttons[0].OnClicked += (button, obj) =>
{
if (GUIMessageBox.MessageBoxes.Count == 0)
{
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
}
return true;
};
msgBox.Buttons[1].OnClicked = msgBox.Close;
}
if (selectedSub.HasTag(SubmarineTag.Shuttle))
{
var msgBox = new GUIMessageBox(TextManager.Get("ShuttleSelected"),
TextManager.Get("ShuttleWarning"),
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
msgBox.Buttons[0].OnClicked = (button, obj) =>
{
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
return true;
};
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked = msgBox.Close;
return false;
}
}
else
{
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
}
return true;
}
};
StartButton.RectTransform.MaxSize = RectTransform.MaxPoint;
StartButton.Children.ForEach(c => c.RectTransform.MaxSize = RectTransform.MaxPoint);
prevInitialMoney = 8000;
InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), buttonContainer.RectTransform), "", font: GUIStyle.SmallFont, textColor: GUIStyle.Green)
prevInitialMoney = CampaignSettings.DefaultInitialMoney;
InitialMoneyText = new GUITextBlock(new RectTransform(new Vector2(0.6f, 1f), buttonContainer.RectTransform), "", font: GUIStyle.SmallFont, textColor: GUIStyle.Green, textAlignment: Alignment.CenterRight)
{
TextGetter = () =>
{
int initialMoney = 8000;
if (CampaignModePresets.Definitions.TryGetValue(nameof(StartingBalanceAmount).ToIdentifier(), out var definition))
int defaultInitialMoney = CampaignSettings.DefaultInitialMoney;
int initialMoney = defaultInitialMoney;
if (CampaignModePresets.TryGetAttribute(
nameof(CampaignSettings.StartingBalanceAmount).ToIdentifier(),
campaignSettingElements.StartingFunds.GetValue().ToIdentifier(),
out var attribute))
{
initialMoney = definition.GetInt(elements.StartingFunds.GetValue().ToIdentifier());
initialMoney = attribute.GetAttributeInt(defaultInitialMoney);
}
if (prevInitialMoney != initialMoney)
{
@@ -165,6 +88,87 @@ namespace Barotrauma
CreateLoadMenu(saveFiles);
}
public bool StartGameClicked(GUIButton button, object userdata)
{
if (string.IsNullOrWhiteSpace(saveNameBox.Text))
{
saveNameBox.Flash(GUIStyle.Red, flashDuration: 5.0f);
saveNameBox.Pulsate(Vector2.One, Vector2.One * 1.2f, duration: 2.0f);
newGameContainer?.Flash(GUIStyle.Red, flashDuration: 0.5f);
return false;
}
SubmarineInfo selectedSub = null;
if (GameMain.NetLobbyScreen.SelectedSub == null) { return false; }
selectedSub = GameMain.NetLobbyScreen.SelectedSub;
if (selectedSub.SubmarineClass == SubmarineClass.Undefined)
{
new GUIMessageBox(TextManager.Get("error"), TextManager.Get("undefinedsubmarineselected"));
return false;
}
if (string.IsNullOrEmpty(selectedSub.MD5Hash.StringRepresentation))
{
new GUIMessageBox(TextManager.Get("error"), TextManager.Get("nohashsubmarineselected"));
return false;
}
string savePath = SaveUtil.CreateSavePath(SaveUtil.SaveType.Multiplayer, saveNameBox.Text);
bool hasRequiredContentPackages = selectedSub.RequiredContentPackagesInstalled;
CampaignSettings settings = campaignSettingElements.CreateSettings();
if (selectedSub.HasTag(SubmarineTag.Shuttle) || !hasRequiredContentPackages)
{
if (!hasRequiredContentPackages)
{
var msgBox = new GUIMessageBox(TextManager.Get("ContentPackageMismatch"),
TextManager.GetWithVariable("ContentPackageMismatchWarning", "[requiredcontentpackages]", string.Join(", ", selectedSub.RequiredContentPackages)),
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
msgBox.Buttons[0].OnClicked = msgBox.Close;
msgBox.Buttons[0].OnClicked += (button, obj) =>
{
if (GUIMessageBox.MessageBoxes.Count == 0)
{
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
}
return true;
};
msgBox.Buttons[1].OnClicked = msgBox.Close;
}
if (selectedSub.HasTag(SubmarineTag.Shuttle))
{
var msgBox = new GUIMessageBox(TextManager.Get("ShuttleSelected"),
TextManager.Get("ShuttleWarning"),
new LocalizedString[] { TextManager.Get("Yes"), TextManager.Get("No") });
msgBox.Buttons[0].OnClicked = (button, obj) =>
{
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
return true;
};
msgBox.Buttons[0].OnClicked += msgBox.Close;
msgBox.Buttons[1].OnClicked = msgBox.Close;
return false;
}
}
else
{
StartNewGame?.Invoke(selectedSub, savePath, seedBox.Text, settings);
CoroutineManager.StartCoroutine(WaitForCampaignSetup(), "WaitForCampaignSetup");
}
return true;
}
private IEnumerable<CoroutineStatus> WaitForCampaignSetup()
{
GUI.SetCursorWaiting();
@@ -13,7 +13,7 @@ namespace Barotrauma.CharacterEditor
// Ragdoll data
private Identifier name;
private bool isHumanoid;
private bool canEnterSubmarine = true;
private CanEnterSubmarine canEnterSubmarine = CanEnterSubmarine.True;
private bool canWalk;
private string texturePath;
private string xmlPath;
@@ -153,6 +153,7 @@ namespace Barotrauma.CharacterEditor
};
var topGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.99f, 1), frame.RectTransform, Anchor.Center)) { AbsoluteSpacing = 2 };
var fields = new List<GUIComponent>();
GUITextBox nameField = null;
GUITextBox texturePathElement = null;
GUITextBox xmlPathElement = null;
GUIDropDown contentPackageDropDown = null;
@@ -177,7 +178,7 @@ namespace Barotrauma.CharacterEditor
{
case 0:
new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), mainElement.RectTransform, Anchor.CenterLeft), TextManager.Get("Name"));
var nameField = new GUITextBox(new RectTransform(new Vector2(0.7f, 1), mainElement.RectTransform, Anchor.CenterRight), Name.Value ?? GetCharacterEditorTranslation("DefaultName").Value) { CaretColor = Color.White };
nameField = new GUITextBox(new RectTransform(new Vector2(0.7f, 1), mainElement.RectTransform, Anchor.CenterRight), Name.Value ?? GetCharacterEditorTranslation("DefaultName").Value) { CaretColor = Color.White };
string ProcessText(string text) => text.RemoveWhitespace().CapitaliseFirstInvariant();
Name = ProcessText(nameField.Text).ToIdentifier();
nameField.OnTextChanged += (tb, text) =>
@@ -204,9 +205,14 @@ namespace Barotrauma.CharacterEditor
var l = new GUITextBlock(new RectTransform(new Vector2(0.3f, 1), mainElement.RectTransform, Anchor.CenterLeft), GetCharacterEditorTranslation("CanEnterSubmarines"));
var t = new GUITickBox(new RectTransform(new Vector2(0.7f, 1), mainElement.RectTransform, Anchor.CenterRight), string.Empty)
{
Selected = CanEnterSubmarine,
//TODO: allow ternary selection (true, false, partial)
Selected = CanEnterSubmarine == CanEnterSubmarine.True,
Enabled = !IsCopy,
OnSelected = (tB) => CanEnterSubmarine = tB.Selected
OnSelected = (tB) =>
{
CanEnterSubmarine = tB.Selected ? CanEnterSubmarine.True : CanEnterSubmarine.False;
return true;
}
};
if (!t.Enabled)
{
@@ -409,6 +415,12 @@ namespace Barotrauma.CharacterEditor
return false;
}
if (Name.Value.IsNullOrWhiteSpace())
{
nameField?.Flash(useRectangleFlash: true);
return false;
}
string evaluatedTexturePath = ContentPath.FromRaw(
contentPackageDropDown.SelectedData as ContentPackage,
TexturePath).Value;
@@ -905,7 +917,7 @@ namespace Barotrauma.CharacterEditor
get => Instance.isHumanoid;
set => Instance.isHumanoid = value;
}
public bool CanEnterSubmarine
public CanEnterSubmarine CanEnterSubmarine
{
get => Instance.canEnterSubmarine;
set => Instance.canEnterSubmarine = value;
@@ -440,13 +440,13 @@ namespace Barotrauma
{
widget.MouseDown += () =>
{
widget.color = GUIStyle.Green;
widget.Color = GUIStyle.Green;
prevAngle = Rotation;
disableMove = true;
};
widget.Deselected += () =>
{
widget.color = Color.Yellow;
widget.Color = Color.Yellow;
disableMove = false;
};
widget.MouseHeld += (deltaTime) =>
@@ -484,7 +484,7 @@ namespace Barotrauma
};
widget.PreDraw += (sprtBtch, deltaTime) =>
{
widget.tooltip = $"Scale: {Math.Round(Scale, 2)}\n" +
widget.Tooltip = $"Scale: {Math.Round(Scale, 2)}\n" +
$"Rotation: {(int) MathHelper.ToDegrees(Rotation)}";
float rotation = Rotation - (float) Math.PI / 2f;
widget.DrawPos = Position + new Vector2((float) Math.Cos(rotation), (float) Math.Sin(rotation)) * (Scale * widgetSize);
@@ -519,17 +519,17 @@ namespace Barotrauma
{
if (!widgets.TryGetValue(id, out Widget? widget))
{
widget = new Widget(id, size, Widget.Shape.Rectangle)
widget = new Widget(id, size, WidgetShape.Rectangle)
{
color = Color.Yellow,
Color = Color.Yellow,
RequireMouseOn = false
};
widgets.Add(id, widget);
initMethod?.Invoke(widget);
}
widget.size = size;
widget.thickness = thickness;
widget.Size = size;
widget.Thickness = thickness;
return widget;
}
@@ -457,7 +457,14 @@ namespace Barotrauma
}
else
{
connection.OverrideValue = ChangeType(attribute.Value, connection.ValueType);
try
{
connection.OverrideValue = ChangeType(attribute.Value, connection.ValueType);
}
catch
{
DebugConsole.ThrowError($"Failed to convert the value {attribute.Value} of the attribute {attribute.Name} to {connection.ValueType}.");
}
}
}
}
@@ -813,7 +820,6 @@ namespace Barotrauma
Vector2 size = type == typeof(string) ? new Vector2(0.2f, 0.3f) : new Vector2(0.2f, 0.175f);
var msgBox = new GUIMessageBox(TextManager.Get("EventEditor.Edit"), "", new[] { TextManager.Get("Cancel"), TextManager.Get("OK") }, size, minSize: new Point(300, 175));
Vector2 layoutSize = type == typeof(string) ? new Vector2(1f, 0.5f) : new Vector2(1f, 0.25f);
var layout = new GUILayoutGroup(new RectTransform(layoutSize, msgBox.Content.RectTransform), isHorizontal: true);
@@ -838,7 +844,7 @@ namespace Barotrauma
valueInput.OnTextChanged += (component, o) =>
{
Vector2 textSize = valueInput.Font.MeasureString(valueInput.WrappedText);
valueInput.RectTransform.NonScaledSize = new Point(valueInput.RectTransform.NonScaledSize.X, (int) textSize.Y + 10);
valueInput.RectTransform.NonScaledSize = new Point(valueInput.RectTransform.NonScaledSize.X, (int)textSize.Y + 10);
listBox.UpdateScrollBarSize();
listBox.BarScroll = 1.0f;
newValue = o;
@@ -855,14 +861,31 @@ namespace Barotrauma
return true;
};
}
else if (type == typeof(float) || type == typeof(int))
else if (type == typeof(float))
{
GUINumberInput valueInput = new GUINumberInput(new RectTransform(Vector2.One, layout.RectTransform), NumberType.Float) { FloatValue = (float) (newValue ?? 0.0f) };
GUINumberInput valueInput = new GUINumberInput(new RectTransform(Vector2.One, layout.RectTransform), NumberType.Float);
if (newValue is float floatVal)
{
valueInput.FloatValue = floatVal;
}
valueInput.OnValueChanged += component => { newValue = component.FloatValue; };
}
else if (type == typeof(int))
{
GUINumberInput valueInput = new GUINumberInput(new RectTransform(Vector2.One, layout.RectTransform), NumberType.Int);
if (newValue is int intVal)
{
valueInput.IntValue = intVal;
}
valueInput.OnValueChanged += component => { newValue = component.IntValue; };
}
else if (type == typeof(bool))
{
GUITickBox valueInput = new GUITickBox(new RectTransform(Vector2.One, layout.RectTransform), "Value") { Selected = (bool) (newValue ?? false) };
GUITickBox valueInput = new GUITickBox(new RectTransform(Vector2.One, layout.RectTransform), "Value");
if (newValue is bool val)
{
valueInput.Selected = val;
}
valueInput.OnSelected += component =>
{
newValue = component.Selected;
@@ -518,6 +518,8 @@ namespace Barotrauma
}
GraphicsQuad.Render();
Character.DrawSpeechBubbles(spriteBatch, cam);
if (fadeToBlackState > 0.0f)
{
spriteBatch.Begin(SpriteSortMode.Deferred);
@@ -35,6 +35,8 @@ namespace Barotrauma
private readonly GUITickBox lightingEnabled, cursorLightEnabled, allowInvalidOutpost, mirrorLevel;
private readonly GUIDropDown selectedSubDropDown;
private readonly GUIDropDown selectedBeaconStationDropdown;
private readonly GUIDropDown selectedWreckDropdown;
private Sprite editingSprite;
@@ -195,6 +197,28 @@ namespace Barotrauma
}
subDropDownContainer.RectTransform.MinSize = new Point(0, selectedSubDropDown.RectTransform.MinSize.Y);
var beaconStationDropDownContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.02f), paddedRightPanel.RectTransform), isHorizontal: true);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), beaconStationDropDownContainer.RectTransform), TextManager.Get("submarinetype.beaconstation"));
selectedBeaconStationDropdown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1.0f), beaconStationDropDownContainer.RectTransform));
selectedBeaconStationDropdown.AddItem(TextManager.Get("Any"), userData: null);
foreach (SubmarineInfo beaconStation in SubmarineInfo.SavedSubmarines)
{
if (beaconStation.Type != SubmarineType.BeaconStation) { continue; }
selectedBeaconStationDropdown.AddItem(beaconStation.DisplayName, userData: beaconStation);
}
beaconStationDropDownContainer.RectTransform.MinSize = new Point(0, selectedBeaconStationDropdown.RectTransform.MinSize.Y);
var wreckDropDownContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.02f), paddedRightPanel.RectTransform), isHorizontal: true);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1.0f), wreckDropDownContainer.RectTransform), TextManager.Get("submarinetype.wreck"));
selectedWreckDropdown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1.0f), wreckDropDownContainer.RectTransform));
selectedWreckDropdown.AddItem(TextManager.Get("Any"), userData: null);
foreach (SubmarineInfo wreck in SubmarineInfo.SavedSubmarines)
{
if (wreck.Type != SubmarineType.Wreck) { continue; }
selectedWreckDropdown.AddItem(wreck.DisplayName, userData: wreck);
}
wreckDropDownContainer.RectTransform.MinSize = new Point(0, selectedWreckDropdown.RectTransform.MinSize.Y);
mirrorLevel = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.02f), paddedRightPanel.RectTransform), TextManager.Get("mirrorentityx"));
allowInvalidOutpost = new GUITickBox(new RectTransform(new Vector2(1.0f, 0.025f), paddedRightPanel.RectTransform),
@@ -218,6 +242,8 @@ namespace Barotrauma
GameMain.LightManager.ClearLights();
currentLevelData = LevelData.CreateRandom(seedBox.Text, generationParams: selectedParams);
currentLevelData.ForceOutpostGenerationParams = outpostParamsList.SelectedData as OutpostGenerationParams;
currentLevelData.ForceBeaconStation = selectedBeaconStationDropdown.SelectedData as SubmarineInfo;
currentLevelData.ForceWreck = selectedWreckDropdown.SelectedData as SubmarineInfo;
currentLevelData.AllowInvalidOutpost = allowInvalidOutpost.Selected;
var dummyLocations = GameSession.CreateDummyLocations(currentLevelData);
Level.Generate(currentLevelData, mirror: mirrorLevel.Selected, startLocation: dummyLocations[0], endLocation: dummyLocations[1]);
@@ -269,7 +295,7 @@ namespace Barotrauma
var nonPlayerFiles = ContentPackageManager.EnabledPackages.All.SelectMany(p => p
.GetFiles<BaseSubFile>()
.Where(f => !(f is SubmarineFile))).ToArray();
.Where(f => f is not SubmarineFile)).ToArray();
SubmarineInfo subInfo = selectedSubDropDown.SelectedData as SubmarineInfo;
subInfo ??= SubmarineInfo.SavedSubmarines.GetRandomUnsynced(s =>
s.IsPlayer && !s.HasTag(SubmarineTag.Shuttle) &&
@@ -339,6 +365,9 @@ namespace Barotrauma
currentLevelData = LevelData.CreateRandom(ToolBox.RandomSeed(10), generationParams: selectedParams);
currentLevelData.ForceOutpostGenerationParams = outpostParamsList.SelectedData as OutpostGenerationParams;
currentLevelData.ForceBeaconStation = selectedBeaconStationDropdown.SelectedData as SubmarineInfo;
currentLevelData.ForceWreck = selectedWreckDropdown.SelectedData as SubmarineInfo;
currentLevelData.AllowInvalidOutpost = allowInvalidOutpost.Selected;
var dummyLocations = GameSession.CreateDummyLocations(currentLevelData);
DebugConsole.NewMessage("*****************************************************************************");
@@ -967,7 +996,7 @@ namespace Barotrauma
{
foreach (Item item in Item.ItemList)
{
if (item == null) { continue; }
if (item == null || item.HiddenInGame) { continue; }
foreach (var light in item.GetComponents<Items.Components.LightComponent>())
{
light.Update((float)deltaTime, Cam);
@@ -152,7 +152,9 @@ namespace Barotrauma
{
SetMenuTabPositioning();
CreateHostServerFields();
bool prevMenuOpen = GUI.SettingsMenuOpen;
SettingsMenu.Create(menuTabs[Tab.Settings].RectTransform);
GUI.SettingsMenuOpen = prevMenuOpen;
if (remoteContentDoc?.Root != null)
{
remoteContentContainer.ClearChildren();
@@ -1269,7 +1271,7 @@ namespace Barotrauma
selectedSub = new SubmarineInfo(Path.Combine(SaveUtil.TempPath, selectedSub.Name + ".sub"));
GameMain.GameSession = new GameSession(selectedSub, savePath, GameModePreset.SinglePlayerCampaign, settings, mapSeed);
GameMain.GameSession.CrewManager.CharacterInfos.Clear();
GameMain.GameSession.CrewManager.ClearCharacterInfos();
foreach (var characterInfo in campaignSetupUI.CharacterMenus.Select(m => m.CharacterInfo))
{
GameMain.GameSession.CrewManager.AddCharacterInfo(characterInfo);
@@ -1366,7 +1368,7 @@ namespace Barotrauma
float bannerAspectRatio = (float) playstyleBanner.Sprite.SourceRect.Width / playstyleBanner.Sprite.SourceRect.Height;
playstyleBanner.RectTransform.NonScaledSize = new Point(playstyleBanner.Rect.Width, (int)(playstyleBanner.Rect.Width / bannerAspectRatio));
playstyleBanner.RectTransform.IsFixedSize = true;
new GUIFrame(new RectTransform(Vector2.One, playstyleBanner.RectTransform), "InnerGlow", color: Color.Black);
new GUIFrame(new RectTransform(playstyleBanner.Rect.Size + new Point(1), playstyleBanner.RectTransform, Anchor.Center), "InnerGlow", color: Color.Black);
new GUITextBlock(new RectTransform(new Vector2(0.15f, 0.05f), playstyleBanner.RectTransform) { RelativeOffset = new Vector2(0.01f, 0.03f) },
"playstyle name goes here", font: GUIStyle.SmallFont, textAlignment: Alignment.Center, textColor: Color.White, style: "GUISlopedHeader");
@@ -1,4 +1,4 @@
#nullable enable
#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
@@ -53,7 +53,9 @@ namespace Barotrauma
base.Select();
DeletePrevDownloads();
Reset();
bool allowDownloads = GameMain.Client.ClientPeer is { AllowModDownloads: true };
Frame.ClearChildren();
var mainVisibleFrame = new GUIFrame(new RectTransform((0.6f, 0.8f), Frame.RectTransform, Anchor.Center));
@@ -66,7 +68,7 @@ namespace Barotrauma
"", font: GUIStyle.LargeFont,
textAlignment: Alignment.CenterLeft)
{
TextGetter = () => GameMain.NetLobbyScreen.ServerName.Text
TextGetter = () => GameMain.Client.ServerName
};
mainLayoutSpacing();
var downloadList = new GUIListBox(new RectTransform((1.0f, 0.76f), mainLayout.RectTransform));
@@ -163,7 +165,7 @@ namespace Barotrauma
var msgBoxModList = new GUIListBox(new RectTransform(Vector2.One, innerLayout.RectTransform));
innerLayoutSpacing(0.05f);
var footer = textBlock(TextManager.Get("ModDownloadFooter"), GUIStyle.Font, Alignment.Center);
var footer = textBlock(TextManager.Get(allowDownloads ? "ModDownloadFooter" : "ModDownloadFooterFail"), GUIStyle.Font, Alignment.Center);
innerLayoutSpacing(0.05f);
GUILayoutGroup buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.1f), innerLayout.RectTransform), isHorizontal: true);
@@ -182,15 +184,28 @@ namespace Barotrauma
}
};
buttonContainerSpacing(0.1f);
button(TextManager.Get("Yes"), () => confirmDownload = true);
buttonContainerSpacing(0.2f);
button(TextManager.Get("No"), () =>
if (allowDownloads)
{
GameMain.Client?.Quit();
GameMain.MainMenuScreen.Select();
});
buttonContainerSpacing(0.1f);
buttonContainerSpacing(0.1f);
button(TextManager.Get("Yes"), () => confirmDownload = true);
buttonContainerSpacing(0.2f);
button(TextManager.Get("No"), () =>
{
GameMain.Client?.Quit();
GameMain.MainMenuScreen.Select();
});
buttonContainerSpacing(0.1f);
}
else
{
buttonContainerSpacing(0.15f);
button(TextManager.Get("Cancel"), () =>
{
GameMain.Client?.Quit();
GameMain.MainMenuScreen.Select();
}, width: 0.7f);
buttonContainerSpacing(0.15f);
}
var missingIds = missingPackages
.Where(p => p.IsMandatory)
File diff suppressed because it is too large Load Diff
@@ -306,22 +306,6 @@ namespace Barotrauma
OverflowClip = true
};
if (string.IsNullOrEmpty(ClientNameBox.Text))
{
TaskPool.Add("GetDefaultUserName",
GetDefaultUserName(),
t =>
{
if (!t.TryGetResult(out string name)) { return; }
if (ClientNameBox.Text.IsNullOrEmpty()) { ClientNameBox.Text = name; }
});
}
ClientNameBox.OnTextChanged += (textbox, text) =>
{
MultiplayerPreferences.Instance.PlayerName = text;
return true;
};
var tabButtonHolder = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - sidebarWidth - infoHolder.RelativeSpacing, 0.5f), infoHolder.RectTransform), isHorizontal: true);
tabs[TabEnum.All] = new Tab(TabEnum.All, this, tabButtonHolder, "");
@@ -874,11 +858,44 @@ namespace Barotrauma
return 0;
}
}
public override void Select()
{
base.Select();
if (string.IsNullOrEmpty(ClientNameBox.Text))
{
TaskPool.Add("GetDefaultUserName",
GetDefaultUserName(),
t =>
{
if (!t.TryGetResult(out string name)) { return; }
if (ClientNameBox.Text.IsNullOrEmpty())
{
ClientNameBox.Text = name;
string nameWithoutInvisibleSymbols = string.Empty;
foreach (char c in ClientNameBox.Text)
{
Vector2 size = ClientNameBox.Font.MeasureChar(c);
if (size.X > 0 && size.Y > 0)
{
nameWithoutInvisibleSymbols += c;
}
}
if (nameWithoutInvisibleSymbols != ClientNameBox.Text)
{
MultiplayerPreferences.Instance.PlayerName = ClientNameBox.Text = nameWithoutInvisibleSymbols;
new GUIMessageBox(TextManager.Get("Warning"), TextManager.GetWithVariable("NameContainsInvisibleSymbols", "[name]", nameWithoutInvisibleSymbols));
}
}
});
}
ClientNameBox.OnTextChanged += (textbox, text) =>
{
MultiplayerPreferences.Instance.PlayerName = text;
return true;
};
if (EosInterface.IdQueries.IsLoggedIntoEosConnect)
{
if (SteamManager.IsInitialized)
@@ -50,6 +50,8 @@ namespace Barotrauma
private bool editBackgroundColor;
private Color backgroundColor = new Color(0.051f, 0.149f, 0.271f, 1.0f);
private bool ControlDown => PlayerInput.KeyDown(Keys.LeftControl) || PlayerInput.KeyDown(Keys.RightControl);
private readonly Camera cam;
public override Camera Cam
{
@@ -366,7 +368,8 @@ namespace Barotrauma
"DecorativeSprite",
"BarrelSprite",
"RailSprite",
"SchematicSprite"
"SchematicSprite",
"WeldedSprite"
};
foreach (string spriteElementName in spriteElementNames)
@@ -471,10 +474,10 @@ namespace Barotrauma
public override void Update(double deltaTime)
{
base.Update(deltaTime);
Widget.EnableMultiSelect = PlayerInput.KeyDown(Keys.LeftControl);
Widget.EnableMultiSelect = ControlDown;
spriteList.SelectMultiple = Widget.EnableMultiSelect;
// Select rects with the mouse
if (Widget.selectedWidgets.None() || Widget.EnableMultiSelect)
if (Widget.SelectedWidgets.None() || Widget.EnableMultiSelect)
{
if (SelectedTexture != null && GUI.MouseOn == null)
{
@@ -578,7 +581,7 @@ namespace Barotrauma
foreach (var sprite in selectedSprites)
{
var newRect = sprite.SourceRect;
if (PlayerInput.KeyDown(Keys.LeftControl))
if (ControlDown)
{
newRect.Width--;
}
@@ -593,7 +596,7 @@ namespace Barotrauma
foreach (var sprite in selectedSprites)
{
var newRect = sprite.SourceRect;
if (PlayerInput.KeyDown(Keys.LeftControl))
if (ControlDown)
{
newRect.Width++;
}
@@ -608,7 +611,7 @@ namespace Barotrauma
foreach (var sprite in selectedSprites)
{
var newRect = sprite.SourceRect;
if (PlayerInput.KeyDown(Keys.LeftControl))
if (ControlDown)
{
newRect.Height++;
}
@@ -623,7 +626,7 @@ namespace Barotrauma
foreach (var sprite in selectedSprites)
{
var newRect = sprite.SourceRect;
if (PlayerInput.KeyDown(Keys.LeftControl))
if (ControlDown)
{
newRect.Height--;
}
@@ -637,6 +640,7 @@ namespace Barotrauma
}
}
public override void Draw(double deltaTime, GraphicsDevice graphics, SpriteBatch spriteBatch)
{
graphics.Clear(backgroundColor);
@@ -691,22 +695,22 @@ namespace Barotrauma
Vector2 GetTopLeft() => sprite.SourceRect.Location.ToVector2();
Vector2 GetTopRight() => new Vector2(GetTopLeft().X + sprite.SourceRect.Width, GetTopLeft().Y);
Vector2 GetBottomRight() => new Vector2(GetTopRight().X, GetTopRight().Y + sprite.SourceRect.Height);
var originWidget = GetWidget($"{id}_origin", sprite, widgetSize, Widget.Shape.Cross, initMethod: w =>
var originWidget = GetWidget($"{id}_origin", sprite, widgetSize, WidgetShape.Cross, initMethod: w =>
{
w.tooltip = TextManager.AddPunctuation(':', originLabel, sprite.RelativeOrigin.FormatDoubleDecimal());
w.Tooltip = TextManager.AddPunctuation(':', originLabel, sprite.RelativeOrigin.FormatDoubleDecimal());
w.MouseHeld += dTime =>
{
w.DrawPos = PlayerInput.MousePosition.Clamp(textureRect.Location.ToVector2() + GetTopLeft() * zoom, textureRect.Location.ToVector2() + GetBottomRight() * zoom);
sprite.Origin = (w.DrawPos - textureRect.Location.ToVector2() - sprite.SourceRect.Location.ToVector2() * zoom) / zoom;
w.tooltip = TextManager.AddPunctuation(':', originLabel, sprite.RelativeOrigin.FormatDoubleDecimal());
w.Tooltip = TextManager.AddPunctuation(':', originLabel, sprite.RelativeOrigin.FormatDoubleDecimal());
};
w.refresh = () =>
w.Refresh = () =>
w.DrawPos = (textureRect.Location.ToVector2() + (sprite.Origin + sprite.SourceRect.Location.ToVector2()) * zoom)
.Clamp(textureRect.Location.ToVector2() + GetTopLeft() * zoom, textureRect.Location.ToVector2() + GetBottomRight() * zoom);
});
var positionWidget = GetWidget($"{id}_position", sprite, widgetSize, Widget.Shape.Rectangle, initMethod: w =>
var positionWidget = GetWidget($"{id}_position", sprite, widgetSize, WidgetShape.Rectangle, initMethod: w =>
{
w.tooltip = positionLabel + sprite.SourceRect.Location;
w.Tooltip = positionLabel + sprite.SourceRect.Location;
w.MouseHeld += dTime =>
{
w.DrawPos = (drawGrid && snapToGrid) ?
@@ -719,13 +723,13 @@ namespace Barotrauma
// TODO: cache the sprite name?
textBox.Text = GetSpriteName(sprite) + " " + sprite.SourceRect;
}
w.tooltip = positionLabel + sprite.SourceRect.Location;
w.Tooltip = positionLabel + sprite.SourceRect.Location;
};
w.refresh = () => w.DrawPos = textureRect.Location.ToVector2() + sprite.SourceRect.Location.ToVector2() * zoom;
w.Refresh = () => w.DrawPos = textureRect.Location.ToVector2() + sprite.SourceRect.Location.ToVector2() * zoom;
});
var sizeWidget = GetWidget($"{id}_size", sprite, widgetSize, Widget.Shape.Rectangle, initMethod: w =>
var sizeWidget = GetWidget($"{id}_size", sprite, widgetSize, WidgetShape.Rectangle, initMethod: w =>
{
w.tooltip = TextManager.AddPunctuation(':', sizeLabel, sprite.SourceRect.Size.ToString());
w.Tooltip = TextManager.AddPunctuation(':', sizeLabel, sprite.SourceRect.Size.ToString());
w.MouseHeld += dTime =>
{
w.DrawPos = (drawGrid && snapToGrid) ?
@@ -740,9 +744,9 @@ namespace Barotrauma
// TODO: cache the sprite name?
textBox.Text = GetSpriteName(sprite) + " " + sprite.SourceRect;
}
w.tooltip = TextManager.AddPunctuation(':', sizeLabel, sprite.SourceRect.Size.ToString());
w.Tooltip = TextManager.AddPunctuation(':', sizeLabel, sprite.SourceRect.Size.ToString());
};
w.refresh = () => w.DrawPos = textureRect.Location.ToVector2() + new Vector2(sprite.SourceRect.Right, sprite.SourceRect.Bottom) * zoom;
w.Refresh = () => w.DrawPos = textureRect.Location.ToVector2() + new Vector2(sprite.SourceRect.Right, sprite.SourceRect.Bottom) * zoom;
});
originWidget.MouseDown += () => GUI.KeyboardDispatcher.Subscriber = null;
positionWidget.MouseDown += () => GUI.KeyboardDispatcher.Subscriber = null;
@@ -1027,31 +1031,31 @@ namespace Barotrauma
#region Widgets
private Dictionary<string, Widget> widgets = new Dictionary<string, Widget>();
private Widget GetWidget(string id, Sprite sprite, int size = 5, Widget.Shape shape = Widget.Shape.Rectangle, Action<Widget> initMethod = null)
private Widget GetWidget(string id, Sprite sprite, int size = 5, WidgetShape shape = WidgetShape.Rectangle, Action<Widget> initMethod = null)
{
if (!widgets.TryGetValue(id, out Widget widget))
{
int selectedSize = (int)Math.Round(size * 1.5f);
widget = new Widget(id, size, shape)
{
data = sprite,
color = Color.Yellow,
secondaryColor = Color.Gray,
tooltipOffset = new Vector2(selectedSize / 2 + 5, -10)
Data = sprite,
Color = Color.Yellow,
SecondaryColor = Color.Gray,
TooltipOffset = new Vector2(selectedSize / 2 + 5, -10)
};
widget.PreDraw += (sp, dTime) =>
{
if (!widget.IsControlled)
{
widget.refresh();
widget.Refresh();
}
};
widget.PreUpdate += dTime => widget.Enabled = selectedSprites.Contains(sprite);
widget.PostUpdate += dTime =>
{
widget.inputAreaMargin = widget.IsControlled ? 1000 : 0;
widget.size = widget.IsSelected ? selectedSize : size;
widget.isFilled = widget.IsControlled;
widget.InputAreaMargin = widget.IsControlled ? 1000 : 0;
widget.Size = widget.IsSelected ? selectedSize : size;
widget.IsFilled = widget.IsControlled;
};
widgets.Add(id, widget);
initMethod?.Invoke(widget);
@@ -1062,7 +1066,7 @@ namespace Barotrauma
private void ResetWidgets()
{
widgets.Clear();
Widget.selectedWidgets.Clear();
Widget.SelectedWidgets.Clear();
}
#endregion
}
@@ -1,4 +1,4 @@
using Barotrauma.Extensions;
using Barotrauma.Extensions;
using Barotrauma.IO;
using Barotrauma.Items.Components;
using Barotrauma.Steam;
@@ -81,7 +81,10 @@ namespace Barotrauma
ItemCount,
LightCount,
ShadowCastingLightCount,
WaterInHulls
WaterInHulls,
LowOxygenOutputWarning,
TooLargeForEndGame,
NotEnoughContainers
}
public static Vector2 MouseDragStart = Vector2.Zero;
@@ -143,6 +146,7 @@ namespace Barotrauma
private GUIButton visibilityButton;
private GUIFrame layerPanel;
private GUIListBox layerList;
private List<GUIButton> layerSpecificButtons = new List<GUIButton>();
private GUIFrame undoBufferPanel;
private GUIFrame undoBufferDisclaimer;
@@ -552,6 +556,21 @@ namespace Barotrauma
}
};
spacing = new GUIFrame(new RectTransform(new Vector2(0.02f, 1.0f), paddedTopPanel.RectTransform), style: null);
var selectedLayerText = new GUITextBlock(new RectTransform(new Vector2(0.15f, 1.0f), paddedTopPanel.RectTransform),
string.Empty, textAlignment: Alignment.Center);
selectedLayerText.TextGetter = () =>
{
string selectedLayer = layerList.SelectedData as string;
if (selectedLayer != prevSelectedLayer)
{
prevSelectedLayer = selectedLayer;
return selectedLayer.IsNullOrEmpty() ? string.Empty : TextManager.GetWithVariable("editor.layer.editinglayer", "[layer]", selectedLayer);
}
return selectedLayerText.Text;
};
TopPanel.RectTransform.MinSize = new Point(0, (int)(paddedTopPanel.RectTransform.Children.Max(c => c.MinSize.Y) / paddedTopPanel.RectTransform.RelativeSize.Y));
paddedTopPanel.Recalculate();
@@ -581,25 +600,27 @@ namespace Barotrauma
{
ScrollBarVisible = true,
AutoHideScrollBar = false,
OnSelected = (component, o) =>
OnSelected = (component, userdata) =>
{
if (GUI.MouseOn is GUITickBox) { return false; } // lol
if (!(o is string layer)) { return false; }
MapEntity.SelectedList.Clear();
foreach (MapEntity entity in MapEntity.MapEntityList.Where(me => !me.Removed && me.Layer == layer))
//toggling selection is not how listboxes normally work, need to do that manually here
SoundPlayer.PlayUISound(GUISoundType.Select);
if (layerList.SelectedData == userdata)
{
if (entity.IsSelected) { continue; }
MapEntity.SelectedList.Add(entity);
layerSpecificButtons.ForEach(btn => btn.Enabled = false);
layerList.Deselect();
return false;
}
else
{
layerSpecificButtons.ForEach(btn => btn.Enabled = true);
return true;
}
return true;
}
};
GUILayoutGroup layerButtonGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.2f), layerGroup.RectTransform));
GUILayoutGroup layerButtonTopGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), layerButtonGroup.RectTransform), isHorizontal: true);
GUILayoutGroup layerButtonBottomGroup = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), layerButtonGroup.RectTransform), isHorizontal: true);
GUIButton layerAddButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1f), layerButtonTopGroup.RectTransform), text: TextManager.Get("editor.layer.newlayer"), style: "GUIButtonFreeScale")
{
@@ -612,6 +633,7 @@ namespace Barotrauma
GUIButton layerDeleteButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1f), layerButtonTopGroup.RectTransform), text: TextManager.Get("editor.layer.deletelayer"), style: "GUIButtonFreeScale")
{
Enabled = false,
OnClicked = (button, o) =>
{
if (layerList.SelectedData is string layer)
@@ -620,10 +642,12 @@ namespace Barotrauma
}
return true;
}
};
};
layerSpecificButtons.Add(layerDeleteButton);
GUIButton layerRenameButton = new GUIButton(new RectTransform(new Vector2(1f, 0.5f), layerButtonGroup.RectTransform), text: TextManager.Get("editor.layer.renamelayer"), style: "GUIButtonFreeScale")
GUIButton layerRenameButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), layerButtonBottomGroup.RectTransform), text: TextManager.Get("editor.layer.renamelayer"), style: "GUIButtonFreeScale")
{
Enabled = false,
OnClicked = (button, o) =>
{
if (layerList.SelectedData is string layer)
@@ -636,9 +660,27 @@ namespace Barotrauma
return true;
}
};
layerSpecificButtons.Add(layerRenameButton);
GUITextBlock.AutoScaleAndNormalize(layerAddButton.TextBlock, layerDeleteButton.TextBlock, layerRenameButton.TextBlock);
GUIButton selectLayerButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), layerButtonBottomGroup.RectTransform), text: TextManager.Get("editor.layer.selectlayer"), style: "GUIButtonFreeScale")
{
Enabled = false,
OnClicked = (button, o) =>
{
if (layerList.SelectedData is string layer)
{
foreach (MapEntity entity in MapEntity.MapEntityList.Where(me => !me.Removed && me.Layer == layer))
{
if (entity.IsSelected) { continue; }
MapEntity.SelectedList.Add(entity);
}
}
return true;
}
};
layerSpecificButtons.Add(selectLayerButton);
GUITextBlock.AutoScaleAndNormalize(layerAddButton.TextBlock, layerDeleteButton.TextBlock, layerRenameButton.TextBlock, selectLayerButton.TextBlock);
Vector2 subPanelSize = new Vector2(0.925f, 0.9f);
@@ -1213,17 +1255,13 @@ namespace Barotrauma
frame.RectTransform.MaxSize = new Point(int.MaxValue, frame.Rect.Width);
LocalizedString name = legacy ? TextManager.GetWithVariable("legacyitemformat", "[name]", ep.Name) : ep.Name;
frame.ToolTip = $"‖color:{XMLExtensions.ToStringHex(GUIStyle.TextColorBright)}‖{name}‖color:end‖";
if (!ep.Description.IsNullOrEmpty())
{
frame.ToolTip += '\n' + ep.Description;
}
frame.ToolTip = ep.CreateTooltipText();
if (ep.ContentPackage != GameMain.VanillaContent && ep.ContentPackage != null)
if (ep.IsModded)
{
frame.Color = Color.Magenta;
frame.ToolTip = $"{frame.ToolTip}\n‖color:{XMLExtensions.ToStringHex(Color.MediumPurple)}‖{ep.ContentPackage?.Name}‖color:end‖";
}
if (ep.HideInMenus || ep.HideInEditors)
{
frame.Color = Color.Red;
@@ -1392,14 +1430,17 @@ namespace Barotrauma
Level.Loaded?.GenerationParams?.AmbientLightColor ??
new Color(3, 3, 3, 3);
UpdateEntityList();
isAutoSaving = false;
if (!wasSelectedBefore)
{
OpenEntityMenu(null);
wasSelectedBefore = true;
}
else
{
OpenEntityMenu(selectedCategory);
}
if (backedUpSubInfo != null)
{
@@ -2035,11 +2076,9 @@ namespace Barotrauma
saveFrame = new GUIFrame(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: "GUIBackgroundBlocker");
var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.55f, 0.6f), saveFrame.RectTransform, Anchor.Center) { MinSize = new Point(750, 500) });
var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.55f, 0.65f), saveFrame.RectTransform, Anchor.Center) { MinSize = new Point(750, 500) });
var paddedSaveFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.95f, 0.9f), innerFrame.RectTransform, Anchor.Center)) { Stretch = true, RelativeSpacing = 0.02f };
//var header = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), paddedSaveFrame.RectTransform), TextManager.Get("SaveSubDialogHeader"), font: GUIStyle.LargeFont);
var columnArea = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.9f), paddedSaveFrame.RectTransform), isHorizontal: true) { RelativeSpacing = 0.02f, Stretch = true };
var leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.55f, 1.0f), columnArea.RectTransform)) { RelativeSpacing = 0.01f, Stretch = true };
var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.42f, 1.0f), columnArea.RectTransform)) { RelativeSpacing = 0.02f, Stretch = true };
@@ -2123,6 +2162,41 @@ namespace Barotrauma
subTypeDropdown.AddItem(TextManager.Get(textTag), subType);
}
if (Layers.Any())
{
var layerVisibilityGroup = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.01f), leftColumn.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), layerVisibilityGroup.RectTransform), TextManager.Get("editor.layer.visiblebydefault"), textAlignment: Alignment.CenterLeft);
var layerVisibilityDropDown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), layerVisibilityGroup.RectTransform),
text: LocalizedString.Join(", ", Layers.Where(l => !Submarine.MainSub?.Info?.LayersHiddenByDefault?.Contains(l.ToIdentifier()) ?? false).Select(lt => TextManager.Capitalize(lt.Key)) ?? ((LocalizedString)"None").ToEnumerable()), selectMultiple: true);
foreach (string layerName in Layers.Keys)
{
layerVisibilityDropDown.AddItem(TextManager.Capitalize(layerName), layerName);
if (MainSub?.Info == null) { continue; }
if (!MainSub.Info.LayersHiddenByDefault.Contains(layerName.ToIdentifier()))
{
layerVisibilityDropDown.SelectItem(layerName);
}
}
layerVisibilityDropDown.OnSelected += (_, __) =>
{
if (MainSub.Info == null) { return false; }
MainSub.Info.LayersHiddenByDefault.Clear();
foreach (string layerName in Layers.Keys)
{
//selected as visible = not hidden
if (layerVisibilityDropDown.SelectedDataMultiple.Any(o => o as string == layerName))
{
continue;
}
MainSub.Info.LayersHiddenByDefault.Add(layerName.ToIdentifier());
}
layerVisibilityDropDown.Text = ToolBox.LimitString(layerVisibilityDropDown.Text.Value, layerVisibilityDropDown.Font, layerVisibilityDropDown.Rect.Width);
return true;
};
layerVisibilityGroup.RectTransform.MinSize = layerVisibilityDropDown.RectTransform.MinSize = new Point(0, layerVisibilityDropDown.RectTransform.Children.Max(c => c.MinSize.Y));
}
//---------------------------------------
var subTypeDependentSettingFrame = new GUIFrame(new RectTransform((1.0f, 0.5f), leftColumn.RectTransform), style: "InnerFrame");
@@ -2154,7 +2228,7 @@ namespace Barotrauma
var moduleTypeDropDown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), outpostModuleGroup.RectTransform),
text: LocalizedString.Join(", ", MainSub?.Info?.OutpostModuleInfo?.ModuleFlags.Select(s => TextManager.Capitalize(s.Value)) ?? ((LocalizedString)"None").ToEnumerable()), selectMultiple: true);
foreach (Identifier flag in availableFlags)
foreach (Identifier flag in availableFlags.OrderBy(f => f.Value, StringComparer.InvariantCultureIgnoreCase))
{
moduleTypeDropDown.AddItem(TextManager.Capitalize(flag.Value), flag);
if (MainSub?.Info?.OutpostModuleInfo == null) { continue; }
@@ -2189,7 +2263,7 @@ namespace Barotrauma
{
allowAttachDropDown.SelectItem("any".ToIdentifier());
}
foreach (Identifier flag in availableFlags)
foreach (Identifier flag in availableFlags.OrderBy(f => f.Value, StringComparer.InvariantCultureIgnoreCase))
{
if (flag == "any" || flag == "none") { continue; }
allowAttachDropDown.AddItem(TextManager.Capitalize(flag.Value), flag);
@@ -2215,12 +2289,13 @@ namespace Barotrauma
var locationTypeGroup = new GUILayoutGroup(new RectTransform(new Vector2(.975f, 0.1f), outpostSettingsContainer.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), locationTypeGroup.RectTransform), TextManager.Get("outpostmoduleallowedlocationtypes"), textAlignment: Alignment.CenterLeft);
HashSet<Identifier> availableLocationTypes = new HashSet<Identifier> { "any".ToIdentifier() };
HashSet<Identifier> availableLocationTypes = new HashSet<Identifier>();
foreach (LocationType locationType in LocationType.Prefabs) { availableLocationTypes.Add(locationType.Identifier); }
var locationTypeDropDown = new GUIDropDown(new RectTransform(new Vector2(0.5f, 1f), locationTypeGroup.RectTransform),
text: LocalizedString.Join(", ", MainSub?.Info?.OutpostModuleInfo?.AllowedLocationTypes.Select(lt => TextManager.Capitalize(lt.Value)) ?? ((LocalizedString)"any").ToEnumerable()), selectMultiple: true);
foreach (Identifier locationType in availableLocationTypes)
locationTypeDropDown.AddItem(TextManager.Capitalize("any"), "any".ToIdentifier());
foreach (Identifier locationType in availableLocationTypes.OrderBy(f => f.Value, StringComparer.InvariantCultureIgnoreCase))
{
locationTypeDropDown.AddItem(TextManager.Capitalize(locationType.Value), locationType);
if (MainSub?.Info?.OutpostModuleInfo == null) { continue; }
@@ -2239,7 +2314,6 @@ namespace Barotrauma
};
locationTypeGroup.RectTransform.MinSize = new Point(0, locationTypeGroup.RectTransform.Children.Max(c => c.MinSize.Y));
// gap positions ---------------------
var gapPositionGroup = new GUILayoutGroup(new RectTransform(new Vector2(.975f, 0.1f), outpostSettingsContainer.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
@@ -2472,7 +2546,7 @@ namespace Barotrauma
int basePrice = (GameMain.DebugDraw ? 0 : MainSub?.CalculateBasePrice()) ?? 1000;
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), priceGroup.RectTransform), NumberType.Int, hidePlusMinusButtons: true)
new GUINumberInput(new RectTransform(new Vector2(0.4f, 1.0f), priceGroup.RectTransform), NumberType.Int, buttonVisibility: GUINumberInput.ButtonVisibility.ForceHidden)
{
IntValue = Math.Max(MainSub?.Info?.Price ?? basePrice, basePrice),
MinValueInt = basePrice,
@@ -3148,6 +3222,7 @@ namespace Barotrauma
}
UpdateEntityList();
OpenEntityMenu(selectedCategory);
}
saveFrame = null;
@@ -3208,14 +3283,18 @@ namespace Barotrauma
SubmarineInfo.RefreshSavedSubs();
SetMode(Mode.Default);
loadFrame = new GUIButton(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), style: null)
loadFrame = new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, GUI.Canvas, Anchor.Center), style: "GUIBackgroundBlocker");
new GUIButton(new RectTransform(Vector2.One, loadFrame.RectTransform, Anchor.Center), style: null)
{
OnClicked = (btn, userdata) => { if (GUI.MouseOn == btn || GUI.MouseOn == btn.TextBlock) loadFrame = null; return true; },
OnClicked = (_, _) =>
{
loadFrame = null;
return true;
}
};
new GUIFrame(new RectTransform(GUI.Canvas.RelativeSize, loadFrame.RectTransform, Anchor.Center), style: "GUIBackgroundBlocker");
var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.75f), loadFrame.RectTransform, Anchor.Center) { MinSize = new Point(350, 500) });
var innerFrame = new GUIFrame(new RectTransform(new Vector2(0.53f, 0.75f), loadFrame.RectTransform, Anchor.Center, scaleBasis: ScaleBasis.Smallest) { MinSize = new Point(350, 500) });
var paddedLoadFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), innerFrame.RectTransform, Anchor.Center)) { Stretch = true, RelativeSpacing = 0.01f };
@@ -3905,16 +3984,15 @@ namespace Barotrauma
}
else
{
List<ContextMenuOption> availableLayerOptions = new List<ContextMenuOption>
List<ContextMenuOption> availableLayers = new List<ContextMenuOption>
{
new ContextMenuOption("editor.layer.nolayer", true, onSelected: () => { MoveToLayer(null, targets); })
};
availableLayers.AddRange(Layers.Select(layer => new ContextMenuOption(layer.Key, true, onSelected: () => { MoveToLayer(layer.Key, targets); })));
availableLayerOptions.AddRange(Layers.Select(layer => new ContextMenuOption(layer.Key, true, onSelected: () => { MoveToLayer(layer.Key, targets); })));
ContextMenuOption[] layerOptions =
{
new ContextMenuOption("editor.layer.movetolayer", isEnabled: hasTargets, availableLayerOptions.ToArray()),
List<ContextMenuOption> availableLayerOptions = new List<ContextMenuOption>
{ new ContextMenuOption("editor.layer.movetolayer", isEnabled: hasTargets, availableLayers.ToArray()),
new ContextMenuOption("editor.layer.createlayer", isEnabled: hasTargets, onSelected: () => { CreateNewLayer(null, targets); }),
new ContextMenuOption("editor.layer.selectall", isEnabled: hasTargets, onSelected: () =>
{
@@ -3924,19 +4002,11 @@ namespace Barotrauma
MapEntity.SelectedList.Add(match);
}
}),
new ContextMenuOption("editor.layer.openlayermenu", isEnabled: true, onSelected: () =>
{
previouslyUsedPanel.Visible = false;
undoBufferPanel.Visible = false;
showEntitiesPanel.Visible = false;
layerPanel.Visible = !layerPanel.Visible;
layerPanel.RectTransform.AbsoluteOffset = new Point(Math.Max(Math.Max(visibilityButton.Rect.X, entityCountPanel.Rect.Right), saveAssemblyFrame.Rect.Right), TopPanel.Rect.Height);
})
};
availableLayerOptions.AddRange(Layers.Select(layer => new ContextMenuOption(layer.Key, true, onSelected: () => { MoveToLayer(layer.Key, targets); })));
GUIContextMenu.CreateContextMenu(
new ContextMenuOption("label.openlabel", isEnabled: target != null, onSelected: () => OpenItem(target)),
new ContextMenuOption("editor.layer", isEnabled: hasTargets, layerOptions),
new ContextMenuOption("editor.cut", isEnabled: hasTargets, onSelected: () => MapEntity.Cut(targets)),
new ContextMenuOption("editor.copytoclipboard", isEnabled: hasTargets, onSelected: () => MapEntity.Copy(targets)),
new ContextMenuOption("editor.paste", isEnabled: MapEntity.CopiedList.Any(), onSelected: () => MapEntity.Paste(cam.ScreenToWorld(PlayerInput.MousePosition))),
@@ -3948,6 +4018,10 @@ namespace Barotrauma
if (!me.Removed) { me.Remove(); }
}
}),
new ContextMenuOption(string.Empty, isEnabled: false, onSelected: () => { /*do nothing*/ }),
new ContextMenuOption("editor.layer.movetoactivelayer", isEnabled: !(layerList?.SelectedData as string).IsNullOrEmpty(), onSelected: () => { MoveToLayer(layerList.SelectedData as string, targets); }),
new ContextMenuOption("editor.layer.removefromlayer", isEnabled: targets.Any(t => t.Layer != string.Empty), onSelected: () => { targets.ForEach(t => t.Layer = string.Empty); }),
new ContextMenuOption("editor.layeroptions", isEnabled: hasTargets, availableLayerOptions.ToArray()),
new ContextMenuOption(TextManager.GetWithVariable("editortip.shiftforextraoptions", "[button]", PlayerInput.SecondaryMouseLabel) + '\n' + TextManager.Get("editortip.altforruler"), isEnabled: false, onSelected: null));
}
}
@@ -3958,6 +4032,10 @@ namespace Barotrauma
foreach (MapEntity entity in content)
{
if (MapEntity.SelectedList.Contains(entity))
{
MapEntity.ResetEditingHUD();
}
entity.Layer = layer;
}
}
@@ -4003,7 +4081,7 @@ namespace Barotrauma
UpdateLayerPanel();
}
private void ReconstructLayers()
public void ReconstructLayers()
{
ClearLayers();
foreach (MapEntity entity in MapEntity.MapEntityList)
@@ -5055,6 +5133,29 @@ namespace Barotrauma
}
GameMain.SubEditorScreen.UpdateUndoHistoryPanel();
if (command is AddOrDeleteCommand addOrDelete)
{
GameMain.SubEditorScreen.EntityAddedOrDeleted(addOrDelete.Receivers);
}
}
private string prevSelectedLayer;
private void EntityAddedOrDeleted(IEnumerable<MapEntity> entities)
{
if (layerList?.SelectedData is string selectedLayer)
{
//add the created entities to the selected layer
foreach (var entity in entities)
{
if (!entity.Removed)
{
entity.Layer = selectedLayer;
}
}
var layerElement = layerList.Content.FindChild(selectedLayer);
layerElement?.Flash(GUIStyle.Green);
}
}
private void UpdateLayerPanel()
@@ -5064,10 +5165,15 @@ namespace Barotrauma
layerList.Content.ClearChildren();
layerList.Deselect();
layerSpecificButtons.ForEach(btn => btn.Enabled = false);
GUILayoutGroup buttonHeaders = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.075f), layerList.Content.RectTransform), isHorizontal: true, childAnchor: Anchor.BottomLeft);
new GUIButton(new RectTransform(new Vector2(0.25f, 1f), buttonHeaders.RectTransform), TextManager.Get("editor.layer.headervisible"), style: "GUIButtonSmallFreeScale") { ForceUpperCase = ForceUpperCase.Yes };
new GUIButton(new RectTransform(new Vector2(0.15f, 1f), buttonHeaders.RectTransform), TextManager.Get("editor.layer.headerlink"), style: "GUIButtonSmallFreeScale") { ForceUpperCase = ForceUpperCase.Yes };
new GUIButton(new RectTransform(new Vector2(0.25f, 1f), buttonHeaders.RectTransform), TextManager.Get("editor.layer.headervisible"), style: "GUIButtonSmallFreeScale") { ForceUpperCase = ForceUpperCase.Yes };
new GUIButton(new RectTransform(new Vector2(0.15f, 1f), buttonHeaders.RectTransform), TextManager.Get("editor.layer.headerlink"), style: "GUIButtonSmallFreeScale")
{
ForceUpperCase = ForceUpperCase.Yes,
ToolTip = TextManager.Get("editor.layer.headerlink.tooltip")
};
new GUIButton(new RectTransform(new Vector2(0.6f, 1f), buttonHeaders.RectTransform), TextManager.Get("name"), style: "GUIButtonSmallFreeScale") { ForceUpperCase = ForceUpperCase.Yes };
foreach (var (layer, (visibility, linkage)) in Layers)
@@ -5090,7 +5196,11 @@ namespace Barotrauma
UpdateLayerPanel();
return false;
}
//hiding a layer automatically deselects it (can't edit a hidden layer)
if (!box.Selected && layerList.SelectedData as string == layer)
{
layerList.Deselect();
}
Layers[layer] = new LayerData(box.Selected ? LayerVisibility.Visible : LayerVisibility.Invisible, data.Linkage);
return true;
}
@@ -5134,7 +5244,7 @@ namespace Barotrauma
var btn = child as GUIButton;
string originalBtnText = btn.Text.Value;
btn.Text = ToolBox.LimitString(btn.Text, btn.Font, btn.Rect.Width);
if (originalBtnText != btn.Text)
if (originalBtnText != btn.Text && btn.ToolTip.IsNullOrEmpty())
{
btn.ToolTip = originalBtnText;
}
@@ -5334,51 +5444,58 @@ namespace Barotrauma
}
}
if (PlayerInput.KeyHit(InputType.Use) && mode == Mode.Default)
if (mode == Mode.Default)
{
if (dummyCharacter != null)
if (PlayerInput.KeyHit(InputType.Use))
{
if (dummyCharacter.SelectedItem == null)
if (dummyCharacter != null)
{
foreach (var entity in MapEntity.HighlightedEntities)
if (dummyCharacter.SelectedItem == null)
{
if (entity is Item item && item.Components.Any(ic => ic is not ConnectionPanel && ic is not Repairable && ic.GuiFrame != null))
foreach (var entity in MapEntity.HighlightedEntities)
{
var container = item.GetComponents<ItemContainer>().ToList();
if (!container.Any() || container.Any(ic => ic?.DrawInventory ?? false))
if (entity is Item item && item.Components.Any(ic => ic is not ConnectionPanel && ic is not Repairable && ic.GuiFrame != null))
{
OpenItem(item);
break;
var container = item.GetComponents<ItemContainer>().ToList();
if (!container.Any() || container.Any(ic => ic?.DrawInventory ?? false))
{
OpenItem(item);
break;
}
}
}
}
}
else
{
CloseItem();
else
{
CloseItem();
}
}
}
}
// Focus to selection
if (PlayerInput.KeyHit(Keys.F) && mode == Mode.Default)
{
// content warning: contains coordinate system workarounds
var selected = MapEntity.SelectedList;
if (selected.Count > 0)
// Focus to selection
if (PlayerInput.KeyHit(Keys.F))
{
var dRect = selected.First().Rect;
var rect = new Rectangle(dRect.Left, dRect.Top, dRect.Width, dRect.Height * -1);
if (selected.Count > 1)
// content warning: contains coordinate system workarounds
var selected = MapEntity.SelectedList;
if (selected.Count > 0)
{
// Create one big rect out of our selection
selected.Skip(1).ForEach(me =>
var dRect = selected.First().Rect;
var rect = new Rectangle(dRect.Left, dRect.Top, dRect.Width, dRect.Height * -1);
if (selected.Count > 1)
{
var wRect = me.Rect;
rect = Rectangle.Union(rect, new Rectangle(wRect.Left, wRect.Top, wRect.Width, wRect.Height * -1));
});
// Create one big rect out of our selection
selected.Skip(1).ForEach(me =>
{
var wRect = me.Rect;
rect = Rectangle.Union(rect, new Rectangle(wRect.Left, wRect.Top, wRect.Width, wRect.Height * -1));
});
}
camTargetFocus = rect.Center.ToVector2();
}
camTargetFocus = rect.Center.ToVector2();
}
if (PlayerInput.KeyHit(Keys.Tab))
{
entityFilterBox.Select();
}
}
@@ -5392,11 +5509,6 @@ namespace Barotrauma
toggleEntityMenuButton.OnClicked?.Invoke(toggleEntityMenuButton, toggleEntityMenuButton.UserData);
}
if (PlayerInput.KeyHit(Keys.Tab))
{
entityFilterBox.Select();
}
if (PlayerInput.IsCtrlDown() && MapEntity.StartMovingPos == Vector2.Zero)
{
cam.MoveCamera((float) deltaTime, allowMove: false, allowZoom: GUI.MouseOn == null);
@@ -5478,8 +5590,9 @@ namespace Barotrauma
foreach (LightComponent lightComponent in item.GetComponents<LightComponent>())
{
lightComponent.Light.Color =
item.body == null || item.body.Enabled ||
(item.ParentInventory is ItemInventory itemInventory && !itemInventory.Container.HideItems) ?
(item.body == null || item.body.Enabled || item.ParentInventory is ItemInventory { Container.HideItems: true }) &&
/*the light is only visible when worn -> can't be visible in the editor*/
lightComponent.Parent is not Wearable ?
lightComponent.LightColor :
Color.Transparent;
lightComponent.Light.LightSpriteEffect = lightComponent.Item.SpriteEffects;