v1.5.7.0 (Summer Update)

This commit is contained in:
Regalis11
2024-06-18 16:49:51 +03:00
parent 4a63dacbce
commit 230d1b6e78
263 changed files with 7792 additions and 2845 deletions
@@ -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);