Merge remote-tracking branch 'upstream/master' into develop
This commit is contained in:
@@ -409,9 +409,9 @@ namespace Barotrauma
|
||||
{
|
||||
senderName = (message.Type == ChatMessageType.Private ? "[PM] " : "") + message.SenderName;
|
||||
}
|
||||
if (message.Sender?.Info?.Job != null)
|
||||
if (message.SenderCharacter?.Info?.Job != null)
|
||||
{
|
||||
senderColor = Color.Lerp(message.Sender.Info.Job.Prefab.UIColor, Color.White, 0.25f);
|
||||
senderColor = Color.Lerp(message.SenderCharacter.Info.Job.Prefab.UIColor, Color.White, 0.25f);
|
||||
}
|
||||
|
||||
var msgHolder = new GUIFrame(new RectTransform(new Vector2(0.95f, 0.0f), chatBox.Content.RectTransform, Anchor.TopCenter), style: null,
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Barotrauma
|
||||
private readonly CampaignUI campaignUI;
|
||||
private readonly GUIComponent parentComponent;
|
||||
|
||||
private GUILayoutGroup pendingAndCrewGroup;
|
||||
private GUIListBox hireableList, pendingList, crewList;
|
||||
private GUIFrame characterPreviewFrame;
|
||||
private GUIDropDown sortingDropDown;
|
||||
@@ -24,7 +25,14 @@ namespace Barotrauma
|
||||
private PlayerBalanceElement? playerBalanceElement;
|
||||
|
||||
private List<CharacterInfo> PendingHires => campaign.Map?.CurrentLocation?.HireManager?.PendingHires;
|
||||
private bool HasPermission => CampaignMode.AllowedToManageCampaign(ClientPermissions.ManageHires);
|
||||
|
||||
// Is the player hiring a new character for themselves instead of bots for the crew?
|
||||
// The window can only be used for one of these purposes at the same time.
|
||||
private static bool HiringNewCharacter => GameMain.NetworkMember?.ServerSettings is { RespawnMode: RespawnMode.Permadeath, IronmanMode: false } &&
|
||||
GameMain.Client?.CharacterInfo is { PermanentlyDead: true };
|
||||
|
||||
private static bool HasPermissionToHire => CampaignMode.AllowedToManageCampaign(
|
||||
HiringNewCharacter ? ClientPermissions.ManageMoney : ClientPermissions.ManageHires);
|
||||
|
||||
private Point resolutionWhenCreated;
|
||||
|
||||
@@ -60,20 +68,20 @@ namespace Barotrauma
|
||||
RefreshCrewFrames(hireableList);
|
||||
RefreshCrewFrames(crewList);
|
||||
RefreshCrewFrames(pendingList);
|
||||
if (clearAllButton != null) { clearAllButton.Enabled = HasPermission; }
|
||||
if (clearAllButton != null) { clearAllButton.Enabled = HasPermissionToHire; }
|
||||
}
|
||||
|
||||
private void RefreshCrewFrames(GUIListBox listBox)
|
||||
{
|
||||
if (listBox == null) { return; }
|
||||
listBox.CanBeFocused = HasPermission;
|
||||
listBox.CanBeFocused = HasPermissionToHire;
|
||||
foreach (GUIComponent child in listBox.Content.Children)
|
||||
{
|
||||
if (child.FindChild(c => c is GUIButton && c.UserData is CharacterInfo, true) is GUIButton buyButton)
|
||||
{
|
||||
CharacterInfo characterInfo = buyButton.UserData as CharacterInfo;
|
||||
bool enoughReputationToHire = EnoughReputationToHire(characterInfo);
|
||||
buyButton.Enabled = HasPermission && enoughReputationToHire;
|
||||
bool enougMoneyToHire = !HiringNewCharacter || campaign.CanAfford(HireManager.GetSalaryFor(characterInfo));
|
||||
buyButton.Enabled = HasPermissionToHire && EnoughReputationToHire(characterInfo) && enougMoneyToHire;
|
||||
foreach (GUITextBlock text in child.GetAllChildren<GUITextBlock>())
|
||||
{
|
||||
text.TextColor = new Color(text.TextColor, buyButton.Enabled ? 1.0f : 0.6f);
|
||||
@@ -174,7 +182,7 @@ namespace Barotrauma
|
||||
|
||||
playerBalanceElement = CampaignUI.AddBalanceElement(pendingAndCrewMainGroup, new Vector2(1.0f, 0.75f / 14.0f));
|
||||
|
||||
var pendingAndCrewGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
|
||||
pendingAndCrewGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
|
||||
parent: new GUIFrame(new RectTransform(new Vector2(1.0f, 13.25f / 14.0f), pendingAndCrewMainGroup.RectTransform)
|
||||
{
|
||||
MaxSize = new Point(panelMaxWidth, campaignUI.GetTabContainer(CampaignMode.InteractionType.Crew).Rect.Height)
|
||||
@@ -222,7 +230,7 @@ namespace Barotrauma
|
||||
{
|
||||
ClickSound = GUISoundType.Cart,
|
||||
ForceUpperCase = ForceUpperCase.Yes,
|
||||
Enabled = HasPermission,
|
||||
Enabled = HasPermissionToHire,
|
||||
OnClicked = (b, o) => RemoveAllPendingHires()
|
||||
};
|
||||
GUITextBlock.AutoScaleAndNormalize(validateHiresButton.TextBlock, clearAllButton.TextBlock);
|
||||
@@ -277,7 +285,7 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (CharacterInfo c in hireableCharacters)
|
||||
{
|
||||
if (c == null) { continue; }
|
||||
if (c == null || PendingHires.Contains(c)) { continue; }
|
||||
CreateCharacterFrame(c, hireableList);
|
||||
}
|
||||
}
|
||||
@@ -289,8 +297,8 @@ namespace Barotrauma
|
||||
{
|
||||
HireManager hireManager = location.HireManager;
|
||||
if (hireManager == null) { return; }
|
||||
int hireVal = hireManager.AvailableCharacters.Aggregate(0, (curr, hire) => curr + hire.GetIdentifier());
|
||||
int newVal = availableHires.Aggregate(0, (curr, hire) => curr + hire.GetIdentifier());
|
||||
int hireVal = hireManager.AvailableCharacters.Aggregate(0, (curr, hire) => curr + hire.ID);
|
||||
int newVal = availableHires.Aggregate(0, (curr, hire) => curr + hire.ID);
|
||||
if (hireVal != newVal)
|
||||
{
|
||||
location.HireManager.AvailableCharacters = availableHires;
|
||||
@@ -371,7 +379,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateCharacterFrame(CharacterInfo characterInfo, GUIListBox listBox)
|
||||
public GUIComponent CreateCharacterFrame(CharacterInfo characterInfo, GUIListBox listBox, bool hideSalary = false)
|
||||
{
|
||||
Skill skill = null;
|
||||
Color? jobColor = null;
|
||||
@@ -442,33 +450,41 @@ namespace Barotrauma
|
||||
CanBeFocused = false
|
||||
};
|
||||
}
|
||||
|
||||
if (listBox != crewList)
|
||||
|
||||
if (!hideSalary)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform),
|
||||
TextManager.FormatCurrency(HireManager.GetSalaryFor(characterInfo)),
|
||||
textAlignment: Alignment.Center)
|
||||
if (listBox != crewList)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just a bit of padding to make list layouts similar
|
||||
new GUIFrame(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform), style: null) { CanBeFocused = false };
|
||||
new GUITextBlock(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform),
|
||||
TextManager.FormatCurrency(HireManager.GetSalaryFor(characterInfo)),
|
||||
textAlignment: Alignment.Center)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just a bit of padding to make list layouts similar
|
||||
new GUIFrame(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform), style: null) { CanBeFocused = false };
|
||||
}
|
||||
}
|
||||
|
||||
if (listBox == hireableList)
|
||||
{
|
||||
var hireButton = new GUIButton(new RectTransform(new Vector2(width, 0.9f), mainGroup.RectTransform), style: "CrewManagementAddButton")
|
||||
{
|
||||
ToolTip = TextManager.Get("hirebutton"),
|
||||
ClickSound = GUISoundType.Cart,
|
||||
UserData = characterInfo,
|
||||
Enabled = CanHire(characterInfo),
|
||||
Enabled = CanHire(characterInfo) && !HiringNewCharacter,
|
||||
OnClicked = (b, o) => AddPendingHire(o as CharacterInfo)
|
||||
};
|
||||
hireButton.OnAddedToGUIUpdateList += (GUIComponent btn) =>
|
||||
{
|
||||
if (HiringNewCharacter)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (PendingHires.Count + campaign.CrewManager.GetCharacterInfos().Count() >= CrewManager.MaxCrewSize)
|
||||
{
|
||||
if (btn.Enabled)
|
||||
@@ -483,6 +499,41 @@ namespace Barotrauma
|
||||
btn.Enabled = CanHire(characterInfo);
|
||||
}
|
||||
};
|
||||
|
||||
if (HiringNewCharacter)
|
||||
{
|
||||
bool canHire = CanHire(characterInfo) && campaign.CanAfford(HireManager.GetSalaryFor(characterInfo));
|
||||
var takeoverButton = new GUIButton(new RectTransform(new Vector2(width, 0.9f), mainGroup.RectTransform), style: "CrewManagementTakeControlButton")
|
||||
{
|
||||
ToolTip = canHire ? TextManager.Get("hireandtakecontrol") : TextManager.Get("hireandtakecontroldisabled"),
|
||||
ClickSound = GUISoundType.ConfirmTransaction,
|
||||
UserData = characterInfo,
|
||||
Enabled = canHire,
|
||||
OnClicked = (b, o) =>
|
||||
{
|
||||
if (GameMain.Client is not GameClient gameClient)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Client client = gameClient.ConnectedClients.FirstOrDefault(c => c.SessionId == gameClient.SessionId);
|
||||
if (!campaign.TryPurchase(client, HireManager.GetSalaryFor(characterInfo)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
gameClient.SendTakeOverBotRequest(characterInfo);
|
||||
needsHireableRefresh = true;
|
||||
campaign.ShowCampaignUI = false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
takeoverButton.OnAddedToGUIUpdateList += (GUIComponent btn) =>
|
||||
{
|
||||
bool canHireCurrently = HiringNewCharacter && CanHire(characterInfo) && campaign.CanAfford(HireManager.GetSalaryFor(characterInfo));
|
||||
btn.ToolTip = TextManager.Get(canHireCurrently ? "hireandtakecontrol" : "hireandtakecontroldisabled");
|
||||
btn.Visible = GameMain.GameSession is { AllowHrManagerBotTakeover: true };
|
||||
btn.Enabled = canHireCurrently;
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (listBox == pendingList)
|
||||
{
|
||||
@@ -501,7 +552,7 @@ namespace Barotrauma
|
||||
{
|
||||
UserData = characterInfo,
|
||||
//can't fire if there's only one character in the crew
|
||||
Enabled = currentCrew.Contains(characterInfo) && currentCrew.Count() > 1 && HasPermission,
|
||||
Enabled = currentCrew.Contains(characterInfo) && currentCrew.Count() > 1 && HasPermissionToHire,
|
||||
OnClicked = (btn, obj) =>
|
||||
{
|
||||
var confirmDialog = new GUIMessageBox(
|
||||
@@ -534,11 +585,13 @@ namespace Barotrauma
|
||||
};
|
||||
}
|
||||
|
||||
bool CanHire(CharacterInfo characterInfo)
|
||||
bool CanHire(CharacterInfo thisCharacterInfo)
|
||||
{
|
||||
if (!HasPermission) { return false; }
|
||||
return EnoughReputationToHire(characterInfo);
|
||||
if (!HasPermissionToHire) { return false; }
|
||||
return EnoughReputationToHire(thisCharacterInfo);
|
||||
}
|
||||
|
||||
return frame;
|
||||
}
|
||||
|
||||
private bool EnoughReputationToHire(CharacterInfo characterInfo)
|
||||
@@ -709,10 +762,10 @@ namespace Barotrauma
|
||||
totalBlock.Text = TextManager.FormatCurrency(total);
|
||||
bool enoughMoney = campaign == null || campaign.CanAfford(total);
|
||||
totalBlock.TextColor = enoughMoney ? Color.White : Color.Red;
|
||||
validateHiresButton.Enabled = enoughMoney && HasPermission && pendingList.Content.RectTransform.Children.Any();
|
||||
validateHiresButton.Enabled = enoughMoney && HasPermissionToHire && pendingList.Content.RectTransform.Children.Any();
|
||||
}
|
||||
|
||||
public bool ValidateHires(List<CharacterInfo> hires, bool takeMoney = true, bool createNetworkEvent = false)
|
||||
public bool ValidateHires(List<CharacterInfo> hires, bool takeMoney = true, bool createNetworkEvent = false, bool createNotification = true)
|
||||
{
|
||||
if (hires == null || hires.None()) { return false; }
|
||||
|
||||
@@ -750,11 +803,14 @@ namespace Barotrauma
|
||||
{
|
||||
UpdateLocationView(campaign.Map.CurrentLocation, true);
|
||||
SelectCharacter(null, null, null);
|
||||
var dialog = new GUIMessageBox(
|
||||
TextManager.Get("newcrewmembers"),
|
||||
TextManager.GetWithVariable("crewhiredmessage", "[location]", campaignUI?.Campaign?.Map?.CurrentLocation?.DisplayName),
|
||||
new LocalizedString[] { TextManager.Get("Ok") });
|
||||
dialog.Buttons[0].OnClicked += dialog.Close;
|
||||
if (createNotification)
|
||||
{
|
||||
var dialog = new GUIMessageBox(
|
||||
TextManager.Get("newcrewmembers"),
|
||||
TextManager.GetWithVariable("crewhiredmessage", "[location]", campaignUI?.Campaign?.Map?.CurrentLocation?.DisplayName),
|
||||
new LocalizedString[] { TextManager.Get("Ok") });
|
||||
dialog.Buttons[0].OnClicked += dialog.Close;
|
||||
}
|
||||
}
|
||||
|
||||
if (createNetworkEvent)
|
||||
@@ -767,7 +823,7 @@ namespace Barotrauma
|
||||
|
||||
private bool CreateRenamingComponent(GUIButton button, object userData)
|
||||
{
|
||||
if (!HasPermission || userData is not CharacterInfo characterInfo) { return false; }
|
||||
if (!HasPermissionToHire || userData is not CharacterInfo characterInfo) { return false; }
|
||||
var outerGlowFrame = new GUIFrame(new RectTransform(new Vector2(1.25f, 1.25f), parentComponent.RectTransform, Anchor.Center),
|
||||
style: "OuterGlow", color: Color.Black * 0.7f);
|
||||
var frame = new GUIFrame(new RectTransform(new Vector2(0.33f, 0.4f), outerGlowFrame.RectTransform, anchor: Anchor.Center)
|
||||
@@ -875,6 +931,9 @@ namespace Barotrauma
|
||||
{
|
||||
playerBalanceElement = CampaignUI.UpdateBalanceElement(playerBalanceElement);
|
||||
}
|
||||
|
||||
// When showing this window to someone hiring a new character, the right side panels aren't needed
|
||||
pendingAndCrewGroup.Visible = !HiringNewCharacter;
|
||||
|
||||
if (needsHireableRefresh)
|
||||
{
|
||||
@@ -949,7 +1008,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void SetPendingHires(List<int> characterInfos, Location location)
|
||||
public void SetPendingHires(List<UInt16> characterInfos, Location location)
|
||||
{
|
||||
List<CharacterInfo> oldHires = PendingHires.ToList();
|
||||
foreach (CharacterInfo pendingHire in oldHires)
|
||||
@@ -957,9 +1016,9 @@ namespace Barotrauma
|
||||
RemovePendingHire(pendingHire, createNetworkMessage: false);
|
||||
}
|
||||
PendingHires.Clear();
|
||||
foreach (int identifier in characterInfos)
|
||||
foreach (UInt16 identifier in characterInfos)
|
||||
{
|
||||
CharacterInfo match = location.HireManager.AvailableCharacters.Find(info => info.GetIdentifierUsingOriginalName() == identifier);
|
||||
CharacterInfo match = location.HireManager.AvailableCharacters.Find(info => info.ID == identifier);
|
||||
if (match != null)
|
||||
{
|
||||
AddPendingHire(match, createNetworkMessage: false);
|
||||
@@ -992,7 +1051,7 @@ namespace Barotrauma
|
||||
msg.WriteUInt16((ushort)PendingHires.Count);
|
||||
foreach (CharacterInfo pendingHire in PendingHires)
|
||||
{
|
||||
msg.WriteInt32(pendingHire.GetIdentifierUsingOriginalName());
|
||||
msg.WriteUInt16(pendingHire.ID);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1002,17 +1061,16 @@ namespace Barotrauma
|
||||
msg.WriteBoolean(validRenaming);
|
||||
if (validRenaming)
|
||||
{
|
||||
int identifier = renameCharacter.info.GetIdentifierUsingOriginalName();
|
||||
msg.WriteInt32(identifier);
|
||||
msg.WriteUInt16(renameCharacter.info.ID);
|
||||
msg.WriteString(renameCharacter.newName);
|
||||
bool existingCrewMember = campaign.CrewManager?.GetCharacterInfos().Any(ci => ci.GetIdentifierUsingOriginalName() == identifier) ?? false;
|
||||
bool existingCrewMember = campaign.CrewManager?.GetCharacterInfos().Any(ci => ci.ID == renameCharacter.info.ID) ?? false;
|
||||
msg.WriteBoolean(existingCrewMember);
|
||||
}
|
||||
|
||||
msg.WriteBoolean(firedCharacter != null);
|
||||
if (firedCharacter != null)
|
||||
{
|
||||
msg.WriteInt32(firedCharacter.GetIdentifier());
|
||||
msg.WriteUInt16(firedCharacter.ID);
|
||||
}
|
||||
|
||||
GameMain.Client.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||
|
||||
@@ -0,0 +1,529 @@
|
||||
#nullable enable
|
||||
using Barotrauma.Networking;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Barotrauma;
|
||||
|
||||
internal class DeathPrompt
|
||||
{
|
||||
private static CoroutineHandle? createPromptCoroutine;
|
||||
|
||||
private GUIComponent? skillPanel;
|
||||
private GUIComponent? newCharacterPanel;
|
||||
private GUIComponent? takeOverBotPanel;
|
||||
|
||||
private GUIComponent? content;
|
||||
|
||||
public static GUIComponent? takeOverBotPanelFrame;
|
||||
|
||||
/// <summary>
|
||||
/// Private constructor, because these should only be created using the Show method
|
||||
/// </summary>
|
||||
private DeathPrompt() { }
|
||||
|
||||
public static void Create(float delay)
|
||||
{
|
||||
if (!RespawnManager.UseDeathPrompt) { return; }
|
||||
if (GameMain.GameSession.DeathPrompt != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (createPromptCoroutine != null && CoroutineManager.IsCoroutineRunning(createPromptCoroutine)) { return; }
|
||||
if ((GameMain.GameSession is not { IsRunning: true })) { return; }
|
||||
|
||||
createPromptCoroutine = CoroutineManager.Invoke(() =>
|
||||
{
|
||||
if (GameMain.GameSession != null)
|
||||
{
|
||||
GameMain.GameSession.DeathPrompt = new DeathPrompt();
|
||||
GameMain.GameSession.DeathPrompt.CreatePrompt();
|
||||
SoundPlayer.OverrideMusicType = "crewdead".ToIdentifier();
|
||||
SoundPlayer.OverrideMusicDuration = 25.0f;
|
||||
}
|
||||
}, delay);
|
||||
}
|
||||
|
||||
public void AddToGUIUpdateList()
|
||||
{
|
||||
content?.AddToGUIUpdateList();
|
||||
}
|
||||
|
||||
private void CreatePrompt()
|
||||
{
|
||||
const float FadeInInterval = 1.0f;
|
||||
const float FadeInDuration = 1.0f;
|
||||
|
||||
bool permadeath = GameMain.NetworkMember is { ServerSettings.RespawnMode: RespawnMode.Permadeath };
|
||||
bool ironman = GameMain.NetworkMember is { ServerSettings: { RespawnMode: RespawnMode.Permadeath, IronmanMode: true } };
|
||||
|
||||
var background = new GUICustomComponent(new RectTransform(Vector2.One, GUI.Canvas, Anchor.Center), onDraw: DrawBackground)
|
||||
{
|
||||
UserData = this
|
||||
};
|
||||
background.FadeIn(wait: 0, duration: 5.0f);
|
||||
|
||||
var foreground = new GUIImage(new RectTransform(new Vector2(1.0f, GUI.RelativeHorizontalAspectRatio), background.RectTransform, Anchor.BottomCenter) { AbsoluteOffset = new Point(0, GUI.IntScale(-20)) }, "DeathScreenForeground")
|
||||
{
|
||||
Color = Color.White
|
||||
};
|
||||
foreground.FadeIn(wait: 0, duration: 5.0f);
|
||||
foreground.Pulsate(startScale: Vector2.One, Vector2.One * 0.8f, duration: 25.0f);
|
||||
|
||||
var frame = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.3f), background.RectTransform, Anchor.Center))
|
||||
{
|
||||
UserData = this
|
||||
};
|
||||
frame.FadeIn(wait: 0, duration: FadeInDuration);
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(0.5f, 0.1f), background.RectTransform, Anchor.TopCenter) { RelativeOffset = new Vector2(0.0f, 0.2f) }, string.Empty, font: GUIStyle.LargeFont, textAlignment: Alignment.TopCenter)
|
||||
{
|
||||
TextGetter = () =>
|
||||
{
|
||||
return GameMain.Client.EndRoundTimeRemaining > 0.0f ?
|
||||
TextManager.GetWithVariable("endinground", "[time]", ToolBox.SecondsToReadableTime(GameMain.Client.EndRoundTimeRemaining))
|
||||
.Fallback(ToolBox.SecondsToReadableTime(GameMain.Client.EndRoundTimeRemaining), useDefaultLanguageIfFound: false) :
|
||||
string.Empty;
|
||||
}
|
||||
};
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.8f, 0.8f), frame.RectTransform, Anchor.Center))
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
//"you have died" header
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), TextManager.Get("deathprompt.header"), font: GUIStyle.LargeFont, textAlignment: Alignment.Center)
|
||||
.FadeIn(wait: 0, duration: FadeInDuration);
|
||||
|
||||
var causeOfDeath = GameMain.Client?.Character?.CauseOfDeath;
|
||||
if (causeOfDeath != null && causeOfDeath.Type != CauseOfDeathType.Unknown)
|
||||
{
|
||||
var causeOfDeathDescription = causeOfDeath.Affliction != null ?
|
||||
causeOfDeath.Affliction.SelfCauseOfDeathDescription :
|
||||
TextManager.Get("Self_CauseOfDeathDescription." + causeOfDeath.Type.ToString(), "Self_CauseOfDeathDescription.Damage");
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform), causeOfDeathDescription)
|
||||
.FadeIn(wait: FadeInInterval * 2, duration: FadeInDuration);
|
||||
}
|
||||
|
||||
if (permadeath)
|
||||
{
|
||||
if (ironman)
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
||||
TextManager.Get("deathprompt.permadeathnotification") + "\n\n" + TextManager.Get("deathprompt.ironmanexplanation"), wrap: true)
|
||||
.FadeIn(wait: FadeInInterval * 3, duration: FadeInDuration);
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
||||
TextManager.Get("deathprompt.permadeathnotification") + '\n' + TextManager.Get("deathprompt.takeoverbotexplanation"), wrap: true)
|
||||
.FadeIn(wait: FadeInInterval * 3, duration: FadeInDuration);
|
||||
}
|
||||
}
|
||||
else if (RespawnManager.SkillLossPercentageOnDeath > 0)
|
||||
{
|
||||
string skillLossAmount = ((int)RespawnManager.SkillLossPercentageOnDeath).ToString();
|
||||
string skillLossText = $"‖color: { XMLExtensions.ToStringHex(GUIStyle.Red)}‖{skillLossAmount}‖end‖";
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), content.RectTransform),
|
||||
RichString.Rich(TextManager.GetWithVariable("respawnskillpenalty", "[percentage]", skillLossText)))
|
||||
.FadeIn(wait: FadeInInterval * 3, duration: FadeInDuration);
|
||||
};
|
||||
|
||||
//"what do you want to do" buttons in the middle
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
var decisionButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.15f), content.RectTransform), isHorizontal: true)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
if (ironman)
|
||||
{
|
||||
// The only option is to spectate
|
||||
var buttonContainerMiddle = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 1.0f), decisionButtonContainer.RectTransform), childAnchor: Anchor.Center);
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonContainerMiddle.RectTransform), TextManager.Get("spectatebutton"))
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: true);
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
}.FadeIn(wait: FadeInInterval * 4, duration: FadeInDuration, alsoChildren: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
var buttonContainerLeft = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), decisionButtonContainer.RectTransform));
|
||||
var buttonContainerRight = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1.0f), decisionButtonContainer.RectTransform));
|
||||
|
||||
// The default "I'll wait" button
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), buttonContainerLeft.RectTransform), TextManager.Get("respawnquestionpromptwait"))
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: true);
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
}.FadeIn(wait: FadeInInterval * 4, duration: FadeInDuration, alsoChildren: true);
|
||||
|
||||
if (permadeath)
|
||||
{
|
||||
if (GameMain.Client != null && GameMain.Client.ServerSettings.AllowBotTakeoverOnPermadeath)
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), buttonContainerRight.RectTransform), TextManager.Get("deathprompt.takeoverbot"))
|
||||
{
|
||||
Enabled = false,
|
||||
OnAddedToGUIUpdateList = (component) =>
|
||||
{
|
||||
component.Enabled = GetAvailableBots().Any();
|
||||
},
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (takeOverBotPanel == null)
|
||||
{
|
||||
CreateTakeOverBotPanel(frame, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
takeOverBotPanel.Parent?.RemoveChild(takeOverBotPanel);
|
||||
takeOverBotPanel = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}.FadeIn(wait: FadeInInterval * 4, duration: FadeInDuration, alsoChildren: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 1.0f), buttonContainerRight.RectTransform), TextManager.Get("deathprompt.respawnnow"))
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
GameMain.Client?.SendRespawnPromptResponse(waitForNextRoundRespawn: false);
|
||||
Close();
|
||||
return true;
|
||||
},
|
||||
Enabled = GameMain.NetworkMember is { ServerSettings.RespawnMode: RespawnMode.MidRound }
|
||||
}.FadeIn(wait: FadeInInterval * 4, duration: FadeInDuration, alsoChildren: true);
|
||||
}
|
||||
|
||||
//"info buttons" at the bottom
|
||||
//-------------------------------------------------------------------------------------------------------
|
||||
|
||||
var infoButtonContainer = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.2f), content.RectTransform), childAnchor: Anchor.TopRight)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.025f
|
||||
};
|
||||
if (permadeath)
|
||||
{
|
||||
if (Level.IsLoadedFriendlyOutpost)
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(0.6f, 1.0f), infoButtonContainer.RectTransform), TextManager.Get("npctitle.hrmanager"), style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (GameMain.GameSession?.Campaign is { } campaign)
|
||||
{
|
||||
campaign.ShowCampaignUI = true;
|
||||
campaign.CampaignUI?.SelectTab(CampaignMode.InteractionType.Crew);
|
||||
}
|
||||
Close();
|
||||
return true;
|
||||
}
|
||||
}.FadeIn(wait: FadeInInterval * 5, duration: FadeInDuration, alsoChildren: true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
new GUIButton(new RectTransform(new Vector2(0.6f, 1.0f), infoButtonContainer.RectTransform), TextManager.Get("deathprompt.showskills"), style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (skillPanel == null)
|
||||
{
|
||||
CreateSkillPanel(frame, GameMain.Client?.Character?.Info ?? GameMain.Client?.CharacterInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
skillPanel.Parent?.RemoveChild(skillPanel);
|
||||
skillPanel = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}.FadeIn(wait: FadeInInterval * 5, duration: FadeInDuration, alsoChildren: true);
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.6f, 1.0f), infoButtonContainer.RectTransform), TextManager.Get("deathprompt.newcharacter"), style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (newCharacterPanel == null)
|
||||
{
|
||||
CreateNewCharacterPanel(frame);
|
||||
}
|
||||
else
|
||||
{
|
||||
newCharacterPanel.Parent?.RemoveChild(newCharacterPanel);
|
||||
newCharacterPanel = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}.FadeIn(wait: FadeInInterval * 5, duration: FadeInDuration, alsoChildren: true);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
/*new GUIButton(new RectTransform(new Vector2(0.4f, 1.0f), infoButtonContainer.RectTransform), "Respawn settings", style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}.FadeIn(wait: FadeInInterval * 5, duration: FadeInDuration, alsoChildren: true);*/
|
||||
|
||||
this.content = background;
|
||||
}
|
||||
|
||||
private void CreateSkillPanel(GUIComponent parent, CharacterInfo? characterInfo)
|
||||
{
|
||||
if (characterInfo == null) { return; }
|
||||
var frame = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent.RectTransform, Anchor.CenterRight, Pivot.CenterLeft));
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.8f), frame.RectTransform, Anchor.Center), isHorizontal: true)
|
||||
{
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
var leftColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.4f, 1.0f), content.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
var middleColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 1.0f), content.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
var rightColumn = new GUILayoutGroup(new RectTransform(new Vector2(0.3f, 1.0f), content.RectTransform))
|
||||
{
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
var leftHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), leftColumn.RectTransform), TextManager.Get("Skills"), font: GUIStyle.SubHeadingFont, textColor: GUIStyle.TextColorBright);
|
||||
var middleHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), middleColumn.RectTransform), TextManager.Get("deathprompt.SkillsLostHeader"), font: GUIStyle.SubHeadingFont, textColor: GUIStyle.TextColorBright);
|
||||
var rightHeader = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), rightColumn.RectTransform), TextManager.Get("deathprompt.respawnnow"), font: GUIStyle.SubHeadingFont, textColor: GUIStyle.TextColorBright);
|
||||
|
||||
GUITextBlock.AutoScaleAndNormalize(leftHeader, middleHeader, rightHeader);
|
||||
|
||||
foreach (var skill in characterInfo.Job.GetSkills().OrderByDescending(s => s.Level))
|
||||
{
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), leftColumn.RectTransform), skill.DisplayName);
|
||||
|
||||
int previousSkill = (int)skill.HighestLevelDuringRound;
|
||||
int reducedSkill = (int)RespawnManager.GetReducedSkill(characterInfo, skill, RespawnManager.SkillLossPercentageOnDeath);
|
||||
int reducedSkillOnImmediateRespawn = (int)RespawnManager.GetReducedSkill(characterInfo, skill, RespawnManager.SkillLossPercentageOnImmediateRespawn, currentSkillLevel: reducedSkill);
|
||||
|
||||
int skillLoss = reducedSkill - previousSkill;
|
||||
int skillLossOnImmediateRespawn = reducedSkillOnImmediateRespawn - previousSkill;
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), middleColumn.RectTransform),
|
||||
RichString.Rich($"{reducedSkill} (‖color:{XMLExtensions.ToStringHex(GUIStyle.Red)}‖{skillLoss}‖end‖)"));
|
||||
|
||||
new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.0f), rightColumn.RectTransform),
|
||||
RichString.Rich($"{reducedSkillOnImmediateRespawn} (‖color:{XMLExtensions.ToStringHex(GUIStyle.Red)}‖{skillLossOnImmediateRespawn}‖end‖)"));
|
||||
}
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(1.0f, 0.15f), leftColumn.RectTransform, Anchor.BottomLeft), TextManager.Get("Close"), style: "GUIButtonSmall")
|
||||
{
|
||||
IgnoreLayoutGroups = true,
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
frame.Parent?.RemoveChild(frame);
|
||||
skillPanel = null;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
skillPanel = frame;
|
||||
}
|
||||
|
||||
private void CreateNewCharacterPanel(GUIComponent parent)
|
||||
{
|
||||
var frame = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.5f), parent.RectTransform, Anchor.CenterRight, Pivot.CenterLeft));
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), frame.RectTransform, Anchor.Center), isHorizontal: false)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
GameMain.NetLobbyScreen.CreatePlayerFrame(content, alwaysAllowEditing: true, createPendingText: false);
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.15f), content.RectTransform), isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonContainer.RectTransform, Anchor.BottomLeft), TextManager.Get("Cancel"), style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
frame.Parent?.RemoveChild(frame);
|
||||
newCharacterPanel = null;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonContainer.RectTransform, Anchor.BottomLeft), TextManager.Get("ApplySettingsYes"), style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
GameMain.NetLobbyScreen.TryDiscardCampaignCharacter(onYes: () =>
|
||||
{
|
||||
frame.Parent?.RemoveChild(frame);
|
||||
newCharacterPanel = null;
|
||||
});
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
newCharacterPanel = frame;
|
||||
}
|
||||
|
||||
public static void CreateTakeOverBotPanel()
|
||||
{
|
||||
var panelHolder = new GUIFrame(new RectTransform(new Vector2(0.3f, 0.3f), GUI.Canvas, Anchor.Center));
|
||||
var takeOverBotPanel = CreateTakeOverBotPanel(panelHolder, deathPrompt: null);
|
||||
if (takeOverBotPanel != null)
|
||||
{
|
||||
takeOverBotPanel.RectTransform.SetPosition(Anchor.Center);
|
||||
GUIMessageBox.MessageBoxes.Add(panelHolder);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Static because the "take over bot" panel can be accessed outside the death prompt too
|
||||
/// </summary>
|
||||
private static GUIComponent? CreateTakeOverBotPanel(GUIComponent parent, DeathPrompt? deathPrompt)
|
||||
{
|
||||
if (GameMain.GameSession?.CrewManager == null) { return null; }
|
||||
if (GameMain.GameSession?.Campaign is not MultiPlayerCampaign campaign) { return null; }
|
||||
|
||||
if (campaign.CampaignUI == null) { campaign.InitCampaignUI(); }
|
||||
|
||||
var frame = new GUIFrame(new RectTransform(new Vector2(1.0f, 1.0f), parent.RectTransform, Anchor.CenterRight, Pivot.CenterLeft));
|
||||
takeOverBotPanelFrame = frame;
|
||||
|
||||
var content = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.9f), frame.RectTransform, Anchor.Center), isHorizontal: false)
|
||||
{
|
||||
Stretch = true,
|
||||
RelativeSpacing = 0.05f
|
||||
};
|
||||
|
||||
var botList = new GUIListBox(new RectTransform(new Vector2(1.0f, 0.9f), content.RectTransform));
|
||||
foreach (CharacterInfo c in GetAvailableBots())
|
||||
{
|
||||
var characterFrame = campaign.CampaignUI?.CrewManagement.CreateCharacterFrame(c, botList, hideSalary: true);
|
||||
if (characterFrame != null)
|
||||
{
|
||||
characterFrame.UserData = c;
|
||||
}
|
||||
}
|
||||
botList.UpdateScrollBarSize();
|
||||
|
||||
var buttonContainer = new GUILayoutGroup(new RectTransform(new Vector2(0.98f, 0.15f), content.RectTransform), isHorizontal: true)
|
||||
{
|
||||
RelativeSpacing = 0.05f,
|
||||
Stretch = true
|
||||
};
|
||||
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonContainer.RectTransform, Anchor.BottomLeft), TextManager.Get("Cancel"), style: "GUIButtonSmall")
|
||||
{
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
GUIMessageBox.MessageBoxes.Remove(frame.Parent);
|
||||
frame.Parent?.RemoveChild(frame);
|
||||
if (deathPrompt != null)
|
||||
{
|
||||
deathPrompt.takeOverBotPanel = null;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
new GUIButton(new RectTransform(new Vector2(0.5f, 1.0f), buttonContainer.RectTransform, Anchor.BottomLeft), TextManager.Get("inputtype.select"), style: "GUIButtonSmall")
|
||||
{
|
||||
Enabled = false,
|
||||
OnAddedToGUIUpdateList = (component) =>
|
||||
{
|
||||
component.Enabled = botList.SelectedData is CharacterInfo;
|
||||
},
|
||||
OnClicked = (btn, userdata) =>
|
||||
{
|
||||
if (botList.SelectedData is CharacterInfo selectedCharacter && GameMain.Client is GameClient client)
|
||||
{
|
||||
client.SendTakeOverBotRequest(selectedCharacter);
|
||||
GUIMessageBox.MessageBoxes.Remove(frame.Parent);
|
||||
deathPrompt?.Close();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DebugConsole.ThrowError($"Conditions for sending bot takeover request not met");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
if (deathPrompt != null)
|
||||
{
|
||||
deathPrompt.takeOverBotPanel = frame;
|
||||
}
|
||||
return frame;
|
||||
}
|
||||
|
||||
private static IEnumerable<CharacterInfo> GetAvailableBots()
|
||||
{
|
||||
if (GameMain.GameSession?.CrewManager is { } crewManager)
|
||||
{
|
||||
return crewManager.GetCharacterInfos().Where(c =>
|
||||
/*either an alive bot */
|
||||
c is { Character.IsBot: true, Character.IsDead: false } ||
|
||||
/* or a newly hired bot that hasn't spawned yet */
|
||||
(c.IsNewHire && c.Character == null));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Enumerable.Empty<CharacterInfo>();
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawBackground(SpriteBatch spriteBatch, GUICustomComponent guiCustomComponent)
|
||||
{
|
||||
var background = GUIStyle.GetComponentStyle("DeathScreenBackground");
|
||||
if (background != null)
|
||||
{
|
||||
GUI.DrawBackgroundSprite(spriteBatch, background.GetDefaultSprite(), Color.White * (guiCustomComponent.Color.A / 255.0f));
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (GameMain.GameSession != null)
|
||||
{
|
||||
GameMain.GameSession.DeathPrompt = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void CloseBotPanel()
|
||||
{
|
||||
if (takeOverBotPanelFrame is GUIComponent frame)
|
||||
{
|
||||
GUIMessageBox.MessageBoxes.Remove(frame.Parent);
|
||||
frame.Parent?.RemoveChild(frame);
|
||||
}
|
||||
takeOverBotPanelFrame = null;
|
||||
}
|
||||
}
|
||||
@@ -717,9 +717,9 @@ namespace Barotrauma
|
||||
private static readonly Queue<GUIComponent> removals = new Queue<GUIComponent>();
|
||||
private static readonly Queue<GUIComponent> additions = new Queue<GUIComponent>();
|
||||
// A helpers list for all elements that have a draw order less than 0.
|
||||
private static readonly List<GUIComponent> first = new List<GUIComponent>();
|
||||
private static readonly List<GUIComponent> firstAdditions = new List<GUIComponent>();
|
||||
// A helper list for all elements that have a draw order greater than 0.
|
||||
private static readonly List<GUIComponent> last = new List<GUIComponent>();
|
||||
private static readonly List<GUIComponent> lastAdditions = new List<GUIComponent>();
|
||||
|
||||
/// <summary>
|
||||
/// Adds the component on the addition queue.
|
||||
@@ -737,11 +737,11 @@ namespace Barotrauma
|
||||
if (!component.Visible) { return; }
|
||||
if (component.UpdateOrder < 0)
|
||||
{
|
||||
first.Add(component);
|
||||
firstAdditions.Add(component);
|
||||
}
|
||||
else if (component.UpdateOrder > 0)
|
||||
{
|
||||
last.Add(component);
|
||||
lastAdditions.Add(component);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -800,9 +800,9 @@ namespace Barotrauma
|
||||
RemoveFromUpdateList(component);
|
||||
}
|
||||
}
|
||||
ProcessHelperList(first);
|
||||
ProcessHelperList(firstAdditions);
|
||||
ProcessAdditions();
|
||||
ProcessHelperList(last);
|
||||
ProcessHelperList(lastAdditions);
|
||||
ProcessRemovals();
|
||||
}
|
||||
}
|
||||
@@ -897,7 +897,7 @@ namespace Barotrauma
|
||||
|
||||
public static IEnumerable<GUIComponent> GetAdditions()
|
||||
{
|
||||
return additions;
|
||||
return additions.Union(firstAdditions).Union(lastAdditions);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -2171,6 +2171,28 @@ namespace Barotrauma
|
||||
return frame;
|
||||
}
|
||||
|
||||
public static GUITextBox CreateTextBoxWithPlaceholder(RectTransform rectT, string text, LocalizedString placeholder)
|
||||
{
|
||||
var holder = new GUIFrame(rectT, style: null);
|
||||
var textBox = new GUITextBox(new RectTransform(Vector2.One, holder.RectTransform, Anchor.CenterLeft), text, createClearButton: false);
|
||||
var placeholderElement = new GUITextBlock(new RectTransform(Vector2.One, holder.RectTransform, Anchor.CenterLeft),
|
||||
textColor: Color.DarkGray * 0.6f,
|
||||
text: placeholder,
|
||||
textAlignment: Alignment.CenterLeft)
|
||||
{
|
||||
CanBeFocused = false
|
||||
};
|
||||
|
||||
new GUICustomComponent(new RectTransform(Vector2.Zero, holder.RectTransform),
|
||||
onUpdate: delegate { placeholderElement.RectTransform.NonScaledSize = textBox.Frame.RectTransform.NonScaledSize; });
|
||||
|
||||
textBox.OnSelected += delegate { placeholderElement.Visible = false; };
|
||||
textBox.OnDeselected += delegate { placeholderElement.Visible = textBox.Text.IsNullOrWhiteSpace(); };
|
||||
|
||||
placeholderElement.Visible = string.IsNullOrWhiteSpace(text);
|
||||
return textBox;
|
||||
}
|
||||
|
||||
public static void NotifyPrompt(LocalizedString header, LocalizedString body)
|
||||
{
|
||||
GUIMessageBox msgBox = new GUIMessageBox(header, body, new[] { TextManager.Get("Ok") }, new Vector2(0.2f, 0.175f), minSize: new Point(300, 175));
|
||||
|
||||
@@ -815,7 +815,8 @@ namespace Barotrauma
|
||||
protected virtual void SetAlpha(float a)
|
||||
{
|
||||
color = new Color(color.R / 255.0f, color.G / 255.0f, color.B / 255.0f, a);
|
||||
hoverColor = new Color(hoverColor.R / 255.0f, hoverColor.G / 255.0f, hoverColor.B / 255.0f, a);;
|
||||
hoverColor = new Color(hoverColor.R / 255.0f, hoverColor.G / 255.0f, hoverColor.B / 255.0f, a);
|
||||
disabledColor = new Color(disabledColor.R / 255.0f, disabledColor.G / 255.0f, disabledColor.B / 255.0f, a);
|
||||
}
|
||||
|
||||
public virtual void Flash(Color? color = null, float flashDuration = 1.5f, bool useRectangleFlash = false, bool useCircularFlash = false, Vector2? flashRectInflate = null)
|
||||
@@ -835,15 +836,29 @@ namespace Barotrauma
|
||||
flashColor = (color == null) ? GUIStyle.Red : (Color)color;
|
||||
}
|
||||
|
||||
public void FadeOut(float duration, bool removeAfter, float wait = 0.0f, Action onRemove = null)
|
||||
public void FadeOut(float duration, bool removeAfter, float wait = 0.0f, Action onRemove = null, bool alsoChildren = false)
|
||||
{
|
||||
CoroutineManager.StartCoroutine(LerpAlpha(0.0f, duration, removeAfter, wait, onRemove));
|
||||
if (alsoChildren)
|
||||
{
|
||||
foreach (var child in Children)
|
||||
{
|
||||
child.FadeOut(duration, removeAfter, wait, onRemove, alsoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void FadeIn(float wait, float duration)
|
||||
public void FadeIn(float wait, float duration, bool alsoChildren = false)
|
||||
{
|
||||
SetAlpha(0.0f);
|
||||
CoroutineManager.StartCoroutine(LerpAlpha(1.0f, duration, false, wait));
|
||||
if (alsoChildren)
|
||||
{
|
||||
foreach (var child in Children)
|
||||
{
|
||||
child.FadeIn(wait, duration, alsoChildren);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SlideIn(float wait, float duration, int amount, SlideDirection direction)
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace Barotrauma
|
||||
}
|
||||
else if (sprite?.Texture is { IsDisposed: false })
|
||||
{
|
||||
spriteBatch.Draw(sprite.Texture, Rect.Center.ToVector2(), sourceRect, currentColor * (currentColor.A / 255.0f), Rotation, origin,
|
||||
spriteBatch.Draw(sprite.Texture, new Vector2(Rect.X + Rect.Width / 2.0f, Rect.Y + Rect.Height / 2.0f), sourceRect, currentColor * (currentColor.A / 255.0f), Rotation, origin,
|
||||
Scale, SpriteEffects, 0.0f);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace Barotrauma
|
||||
{
|
||||
public class GUIMessageBox : GUIFrame
|
||||
{
|
||||
#warning TODO: change this to List<GUIMessageBox> and fix incorrect uses of this list
|
||||
public readonly static List<GUIComponent> MessageBoxes = new List<GUIComponent>();
|
||||
private static int DefaultWidth
|
||||
{
|
||||
|
||||
@@ -128,7 +128,7 @@ namespace Barotrauma
|
||||
}
|
||||
set
|
||||
{
|
||||
if (MathUtils.NearlyEqual(value, floatValue)) { return; }
|
||||
if (Math.Abs(value - floatValue) < 0.0001f && MathUtils.NearlyEqual(value, floatValue)) { return; }
|
||||
floatValue = value;
|
||||
ClampFloatValue();
|
||||
float newValue = floatValue;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#nullable enable
|
||||
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -25,6 +26,11 @@ namespace Barotrauma
|
||||
|
||||
public delegate void OnValueChangedHandler(GUISelectionCarousel<T> carousel);
|
||||
public OnValueChangedHandler? OnValueChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Are there some conditions for selecting a particular element?
|
||||
/// </summary>
|
||||
public Func<T, bool>? ElementSelectionCondition { get; set; }
|
||||
|
||||
public GUITextBlock TextBlock { get; private set; }
|
||||
|
||||
@@ -89,35 +95,9 @@ namespace Barotrauma
|
||||
GUIStyle.Apply(TextBlock, "TextBlock", this);
|
||||
RightButton = new GUIButton(new RectTransform(new Vector2(0.15f, 1.0f), layoutGroup.RectTransform), style: "GUIButtonToggleRight");
|
||||
GUIStyle.Apply(RightButton, "RightButton", this);
|
||||
|
||||
RightButton.OnClicked += (btn, userData) =>
|
||||
{
|
||||
if (elements.Count < 2) { return false; }
|
||||
if (SelectedElement == null)
|
||||
{
|
||||
SelectElement(elements.First());
|
||||
}
|
||||
else
|
||||
{
|
||||
int newIndex = (elements.IndexOf(SelectedElement) + 1) % elements.Count;
|
||||
SelectElement(elements[newIndex]);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
LeftButton.OnClicked += (btn, userData) =>
|
||||
{
|
||||
if (elements.Count < 2) { return false; }
|
||||
if (SelectedElement == null)
|
||||
{
|
||||
SelectElement(elements.First());
|
||||
}
|
||||
else
|
||||
{
|
||||
int newIndex = MathUtils.PositiveModulo((elements.IndexOf(SelectedElement) - 1), elements.Count);
|
||||
SelectElement(elements[newIndex]);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
RightButton.OnClicked += (_, _) => SelectNextValidElement();
|
||||
LeftButton.OnClicked += (_, _) => SelectNextValidElement(directionLeft: true);
|
||||
|
||||
if (newElements != null && newElements.Any())
|
||||
{
|
||||
@@ -140,9 +120,11 @@ namespace Barotrauma
|
||||
SelectElement(null);
|
||||
return;
|
||||
}
|
||||
if (elements.FirstOrDefault(e => value.Equals(e.value)) is { } element)
|
||||
var matchingElement = elements.Where(e => value.Equals(e.value)) // selection is in the set of possible values
|
||||
.FirstOrDefault(e => ElementSelectionCondition == null || ElementSelectionCondition(e.value)); // selection matches extra conditions, if any
|
||||
if (matchingElement != null)
|
||||
{
|
||||
SelectElement(element);
|
||||
SelectElement(matchingElement);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,5 +169,42 @@ namespace Barotrauma
|
||||
SelectElement(newElement);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Refresh the current selection, for example if there are conditions for which elements are valid, and those might have changed
|
||||
/// </summary>
|
||||
public void Refresh()
|
||||
{
|
||||
if (SelectedElement != null)
|
||||
{
|
||||
if (ElementSelectionCondition == null || ElementSelectionCondition(SelectedElement.value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SelectElement(elements.FirstOrDefault(e => ElementSelectionCondition == null || ElementSelectionCondition(e.value)));
|
||||
}
|
||||
|
||||
private bool SelectNextValidElement(bool directionLeft = false)
|
||||
{
|
||||
if (elements.Count < 2) { return false; }
|
||||
|
||||
// Try to find a valid next/previous element
|
||||
int currentIndex = SelectedElement == null ? -1 : elements.IndexOf(SelectedElement);
|
||||
int newIndex = currentIndex;
|
||||
for (int i = 0; i < elements.Count; i++)
|
||||
{
|
||||
newIndex = directionLeft ? MathUtils.PositiveModulo((newIndex - 1), elements.Count) : (newIndex + 1) % elements.Count;
|
||||
if (ElementSelectionCondition == null || ElementSelectionCondition(elements[newIndex].value))
|
||||
{
|
||||
SelectElement(elements[newIndex]);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// No valid elements found
|
||||
SelectElement(null);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -438,8 +438,11 @@ namespace Barotrauma
|
||||
|
||||
protected override void SetAlpha(float a)
|
||||
{
|
||||
// base.SetAlpha(a);
|
||||
textColor = new Color(TextColor.R / 255.0f, TextColor.G / 255.0f, TextColor.B / 255.0f, a);
|
||||
textColor = new Color(TextColor, a);
|
||||
if (hoverTextColor.HasValue)
|
||||
{
|
||||
hoverTextColor = new Color(hoverTextColor.Value, a);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2108,13 +2108,13 @@ namespace Barotrauma
|
||||
deliveryPrompt.Buttons[0].OnClicked = (btn, userdata) =>
|
||||
{
|
||||
ConfirmPurchase(deliverImmediately: true);
|
||||
deliveryPrompt.Close();
|
||||
deliveryPrompt?.Close();
|
||||
return true;
|
||||
};
|
||||
deliveryPrompt.Buttons[1].OnClicked = (btn, userdata) =>
|
||||
{
|
||||
ConfirmPurchase(deliverImmediately: false);
|
||||
deliveryPrompt.Close();
|
||||
deliveryPrompt?.Close();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -742,8 +742,8 @@ namespace Barotrauma
|
||||
|
||||
private (LocalizedString header, LocalizedString body) GetItemTransferWarningText()
|
||||
{
|
||||
var header = TextManager.Get("itemtransferheader").Fallback("lowfuelheader");
|
||||
var body = TextManager.Get("itemtransferwarning").Fallback("lowfuelwarning");
|
||||
var header = TextManager.Get("itemtransferheader").Fallback("lowfuelheader", useDefaultLanguageIfFound: false);
|
||||
var body = TextManager.Get("itemtransferwarning").Fallback("lowfuelwarning", useDefaultLanguageIfFound: false);
|
||||
return (header, body);
|
||||
}
|
||||
|
||||
|
||||
@@ -320,7 +320,61 @@ namespace Barotrauma
|
||||
var reputationButton = createTabButton(InfoFrameTab.Reputation, "reputation");
|
||||
|
||||
var balanceFrame = new GUIFrame(new RectTransform(new Point(innerLayoutGroup.Rect.Width, innerLayoutGroup.Rect.Height - infoFrameHolderHeight), parent: innerLayoutGroup.RectTransform), style: "InnerFrame");
|
||||
GUITextBlock balanceText = new GUITextBlock(new RectTransform(Vector2.One, balanceFrame.RectTransform), string.Empty, textAlignment: Alignment.Right);
|
||||
GUILayoutGroup salaryFrame = new GUILayoutGroup(new RectTransform(new Vector2(0.66f, 1f), balanceFrame.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
|
||||
|
||||
GUIScrollBar salaryScrollBar = null;
|
||||
GUITextBlock salaryPercentage = null;
|
||||
if (GameMain.GameSession?.GameMode is MultiPlayerCampaign)
|
||||
{
|
||||
float value = campaignMode.Bank.RewardDistribution;
|
||||
GUITextBlock salaryText = new GUITextBlock(new RectTransform(new Vector2(0.25f, 1f), salaryFrame.RectTransform), TextManager.Get("defaultsalary"), textAlignment: Alignment.Center)
|
||||
{
|
||||
AutoScaleHorizontal = true
|
||||
};
|
||||
salaryScrollBar = new GUIScrollBar(new RectTransform(new Vector2(0.4f, 1f), salaryFrame.RectTransform), barSize: 0.1f, style: "GUISlider")
|
||||
{
|
||||
Range = new Vector2(0, 1),
|
||||
BarScrollValue = value / 100f,
|
||||
Step = 0.01f,
|
||||
BarSize = 0.1f,
|
||||
};
|
||||
|
||||
salaryPercentage = new GUITextBlock(new RectTransform(new Vector2(0.15f, 1f), salaryFrame.RectTransform), "0", textAlignment: Alignment.Center)
|
||||
{
|
||||
Text = ValueToPercentage(RoundRewardDistribution(salaryScrollBar.BarScroll, salaryScrollBar.Step))
|
||||
};
|
||||
|
||||
salaryScrollBar.OnMoved = (scrollBar, value) =>
|
||||
{
|
||||
salaryPercentage.Text = ValueToPercentage(RoundRewardDistribution(value, scrollBar.Step));
|
||||
return true;
|
||||
};
|
||||
salaryScrollBar.OnReleased = (bar, scroll) =>
|
||||
{
|
||||
int newRewardDistribution = RoundRewardDistribution(scroll, bar.Step);
|
||||
SetRewardDistribution(Option.None, newRewardDistribution);
|
||||
return true;
|
||||
};
|
||||
|
||||
var resetButton = new GUIButton(new RectTransform(new Vector2(0.2f, 1f), salaryFrame.RectTransform), TextManager.Get("ResetSalaries"), style: "GUIButtonSmall")
|
||||
{
|
||||
TextBlock = { AutoScaleHorizontal = true },
|
||||
ToolTip = TextManager.Get("resetsalaries.tooltip"),
|
||||
OnClicked = (button, userData) =>
|
||||
{
|
||||
GUI.AskForConfirmation(TextManager.Get("ResetSalaries"), TextManager.Get("ResetSalaries.Warning"), onConfirm: ResetRewardDistributions);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
void UpdateSliderEnabled()
|
||||
=> salaryScrollBar.Enabled = resetButton.Enabled = CampaignMode.AllowedToManageWallets();
|
||||
UpdateSliderEnabled();
|
||||
|
||||
Identifier defaultSalaryEventIdentifier = "DefaultSalarySlider".ToIdentifier();
|
||||
GameMain.Client?.OnPermissionChanged?.RegisterOverwriteExisting(defaultSalaryEventIdentifier, _ => UpdateSliderEnabled());
|
||||
}
|
||||
GUITextBlock balanceText = new GUITextBlock(new RectTransform(new Vector2(0.33f, 1f), balanceFrame.RectTransform, Anchor.TopRight), string.Empty, textAlignment: Alignment.Right);
|
||||
if (GameMain.IsMultiplayer)
|
||||
{
|
||||
balanceText.ToolTip = TextManager.Get("bankdescription");
|
||||
@@ -343,6 +397,13 @@ namespace Barotrauma
|
||||
{
|
||||
if (!e.Owner.IsNone()) { return; }
|
||||
SetBalanceText(balanceText, e.Wallet.Balance);
|
||||
|
||||
if (salaryPercentage is not null && salaryScrollBar is not null)
|
||||
{
|
||||
float rewardDistribution = e.Wallet.RewardDistribution;
|
||||
salaryScrollBar.BarScrollValue = rewardDistribution / 100f;
|
||||
salaryPercentage.Text = ValueToPercentage(rewardDistribution);
|
||||
}
|
||||
});
|
||||
registeredEvents.Add(eventIdentifier);
|
||||
|
||||
@@ -350,6 +411,9 @@ namespace Barotrauma
|
||||
{
|
||||
text.Text = TextManager.GetWithVariable("bankbalanceformat", "[money]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", balance));
|
||||
}
|
||||
|
||||
LocalizedString ValueToPercentage(float value)
|
||||
=> TextManager.GetWithVariable("percentageformat", "[value]", $"{(int)MathF.Round(value)}");
|
||||
}
|
||||
|
||||
var submarineButton = createTabButton(InfoFrameTab.Submarine, "submarine");
|
||||
@@ -1037,11 +1101,10 @@ namespace Barotrauma
|
||||
{
|
||||
int newRewardDistribution = RoundRewardDistribution(scroll, bar.Step);
|
||||
if (newRewardDistribution == targetWallet.RewardDistribution) { return false; }
|
||||
SetRewardDistribution(character, newRewardDistribution);
|
||||
SetRewardDistribution(Option.Some(character), newRewardDistribution);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
int RoundRewardDistribution(float scroll, float step) => (int)MathUtils.RoundTowardsClosest(scroll * 100, step * 100);
|
||||
|
||||
SetRewardText(targetWallet.RewardDistribution, rewardBlock);
|
||||
|
||||
@@ -1201,6 +1264,7 @@ namespace Barotrauma
|
||||
{
|
||||
moneyBlock.Text = TextManager.FormatCurrency(e.Info.Balance);
|
||||
salarySlider.BarScrollValue = e.Info.RewardDistribution / 100f;
|
||||
SetRewardText(e.Info.RewardDistribution, rewardBlock);
|
||||
}
|
||||
|
||||
UpdateAllInputs();
|
||||
@@ -1311,20 +1375,29 @@ namespace Barotrauma
|
||||
transfer.Write(msg);
|
||||
GameMain.Client?.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
static void SetRewardDistribution(Character character, int newValue)
|
||||
{
|
||||
INetSerializableStruct transfer = new NetWalletSetSalaryUpdate
|
||||
{
|
||||
Target = character.ID,
|
||||
NewRewardDistribution = newValue
|
||||
};
|
||||
IWriteMessage msg = new WriteOnlyMessage().WithHeader(ClientPacketHeader.REWARD_DISTRIBUTION);
|
||||
transfer.Write(msg);
|
||||
GameMain.Client?.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetRewardDistribution(Option<Character> character, int newValue)
|
||||
{
|
||||
INetSerializableStruct transfer = new NetWalletSetSalaryUpdate
|
||||
{
|
||||
Target = character.Select(c => c.ID),
|
||||
NewRewardDistribution = newValue
|
||||
};
|
||||
IWriteMessage msg = new WriteOnlyMessage().WithHeader(ClientPacketHeader.REWARD_DISTRIBUTION);
|
||||
transfer.Write(msg);
|
||||
GameMain.Client?.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
static void ResetRewardDistributions()
|
||||
{
|
||||
IWriteMessage msg = new WriteOnlyMessage().WithHeader(ClientPacketHeader.RESET_REWARD_DISTRIBUTION);
|
||||
GameMain.Client?.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
|
||||
}
|
||||
|
||||
static int RoundRewardDistribution(float scroll, float step)
|
||||
=> (int)MathUtils.RoundTowardsClosest(scroll * 100, step * 100);
|
||||
|
||||
private GUIComponent CreateClientInfoFrame(GUIFrame frame, Client client, Sprite permissionIcon = null)
|
||||
{
|
||||
GUIComponent paddedFrame;
|
||||
|
||||
@@ -133,43 +133,47 @@ namespace Barotrauma
|
||||
GUIFrame containerFrame = new GUIFrame(new RectTransform(new Vector2(1f, 0.9f), characterLayout.RectTransform), style: null);
|
||||
GUILayoutGroup playerFrame = new GUILayoutGroup(new RectTransform(new Vector2(1.0f, 0.9f), containerFrame.RectTransform, Anchor.TopCenter));
|
||||
GameMain.NetLobbyScreen.CreatePlayerFrame(playerFrame, alwaysAllowEditing: true, createPendingText: false);
|
||||
|
||||
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.5f, 0.2f), skillLayout.RectTransform, Anchor.BottomRight),
|
||||
text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"), style: "GUIButtonSmall")
|
||||
|
||||
// TODO: What is CampaignCharacterDiscarded and can it be relevant in permadeath mode?
|
||||
if (!GameMain.NetLobbyScreen.PermadeathMode)
|
||||
{
|
||||
IgnoreLayoutGroups = false,
|
||||
TextBlock =
|
||||
GUIButton newCharacterBox = new GUIButton(new RectTransform(new Vector2(0.5f, 0.2f), skillLayout.RectTransform, Anchor.BottomRight),
|
||||
text: GameMain.NetLobbyScreen.CampaignCharacterDiscarded ? TextManager.Get("settings") : TextManager.Get("createnew"), style: "GUIButtonSmall")
|
||||
{
|
||||
AutoScaleHorizontal = true
|
||||
}
|
||||
};
|
||||
|
||||
newCharacterBox.OnClicked = (button, o) =>
|
||||
{
|
||||
if (!GameMain.NetLobbyScreen.CampaignCharacterDiscarded)
|
||||
{
|
||||
GameMain.NetLobbyScreen.TryDiscardCampaignCharacter(() =>
|
||||
IgnoreLayoutGroups = false,
|
||||
TextBlock =
|
||||
{
|
||||
newCharacterBox.Text = TextManager.Get("settings");
|
||||
if (TabMenu.PendingChangesFrame != null)
|
||||
{
|
||||
NetLobbyScreen.CreateChangesPendingFrame(TabMenu.PendingChangesFrame);
|
||||
}
|
||||
AutoScaleHorizontal = true
|
||||
}
|
||||
};
|
||||
|
||||
OpenMenu();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenMenu();
|
||||
return true;
|
||||
|
||||
void OpenMenu()
|
||||
newCharacterBox.OnClicked = (button, o) =>
|
||||
{
|
||||
characterSettingsFrame!.Visible = true;
|
||||
content.Visible = false;
|
||||
}
|
||||
};
|
||||
if (!GameMain.NetLobbyScreen.CampaignCharacterDiscarded)
|
||||
{
|
||||
GameMain.NetLobbyScreen.TryDiscardCampaignCharacter(() =>
|
||||
{
|
||||
newCharacterBox.Text = TextManager.Get("settings");
|
||||
if (TabMenu.PendingChangesFrame != null)
|
||||
{
|
||||
NetLobbyScreen.CreateChangesPendingFrame(TabMenu.PendingChangesFrame);
|
||||
}
|
||||
|
||||
OpenMenu();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenMenu();
|
||||
return true;
|
||||
|
||||
void OpenMenu()
|
||||
{
|
||||
characterSettingsFrame!.Visible = true;
|
||||
content.Visible = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
GUILayoutGroup characterCloseButtonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.1f), characterLayout.RectTransform), childAnchor: Anchor.BottomCenter);
|
||||
new GUIButton(new RectTransform(new Vector2(0.4f, 1f), characterCloseButtonLayout.RectTransform), TextManager.Get("ApplySettingsButton")) //TODO: Is this text appropriate for this circumstance for all languages?
|
||||
@@ -177,6 +181,7 @@ namespace Barotrauma
|
||||
OnClicked = (button, o) =>
|
||||
{
|
||||
GameMain.Client?.SendCharacterInfo(GameMain.Client.PendingName);
|
||||
GameMain.NetLobbyScreen.CampaignCharacterDiscarded = false;
|
||||
characterSettingsFrame.Visible = false;
|
||||
content.Visible = true;
|
||||
return true;
|
||||
|
||||
@@ -773,7 +773,7 @@ namespace Barotrauma
|
||||
subItems ??= GetSubItems();
|
||||
return subItems.Any(i =>
|
||||
i.Prefab.SwappableItem != null &&
|
||||
!i.HiddenInGame && i.AllowSwapping &&
|
||||
!i.IsHidden && i.AllowSwapping &&
|
||||
(i.Prefab.SwappableItem.CanBeBought || ItemPrefab.Prefabs.Any(ip => ip.SwappableItem?.ReplacementOnUninstall == i.Prefab.Identifier)) &&
|
||||
Submarine.MainSub.IsEntityFoundOnThisSub(i, true) && category.ItemTags.Any(t => i.HasTag(t)));
|
||||
}
|
||||
@@ -876,7 +876,7 @@ namespace Barotrauma
|
||||
{
|
||||
parent.Content.ClearChildren();
|
||||
currentUpgradeCategory = category;
|
||||
var entitiesOnSub = submarine.GetItems(true).Where(i => submarine.IsEntityFoundOnThisSub(i, true) && !i.HiddenInGame && i.AllowSwapping && i.Prefab.SwappableItem != null && category.ItemTags.Any(t => i.HasTag(t))).ToList();
|
||||
var entitiesOnSub = submarine.GetItems(true).Where(i => submarine.IsEntityFoundOnThisSub(i, true) && !i.IsHidden && i.AllowSwapping && i.Prefab.SwappableItem != null && category.ItemTags.Any(t => i.HasTag(t))).ToList();
|
||||
|
||||
foreach (Item item in entitiesOnSub)
|
||||
{
|
||||
|
||||
@@ -115,7 +115,6 @@ namespace Barotrauma
|
||||
if (IsMouseOver || (!RequireMouseOn && SelectedWidgets.Contains(this) && PlayerInput.PrimaryMouseButtonHeld()))
|
||||
{
|
||||
Hovered?.Invoke();
|
||||
System.Diagnostics.Debug.WriteLine("hovered");
|
||||
if (RequireMouseOn || PlayerInput.PrimaryMouseButtonDown())
|
||||
{
|
||||
if ((multiselect && !SelectedWidgets.Contains(this)) || SelectedWidgets.None())
|
||||
|
||||
Reference in New Issue
Block a user